diff --git a/include/bits/prettyprint.hpp b/include/bits/prettyprint.hpp index 52d720b..862ee3d 100644 --- a/include/bits/prettyprint.hpp +++ b/include/bits/prettyprint.hpp @@ -23,400 +23,446 @@ namespace soi { -template +template std::basic_ostream & -print(std::basic_ostream & stream, const T& x); +print(std::basic_ostream &stream, const T &x); -namespace detail -{ +namespace detail { // SFINAE type trait to detect whether T::const_iterator exists. -struct sfinae_base -{ - using yes = char; - using no = yes[2]; +struct sfinae_base { + using yes = char; + using no = yes[2]; }; -template -struct has_const_iterator : private sfinae_base -{ +template struct has_const_iterator : private sfinae_base { private: - template static yes & test(typename C::const_iterator*); - template static no & test(...); -public: - static const bool value = sizeof(test(nullptr)) == sizeof(yes); - using type = T; -}; - -template -struct has_begin_end : private sfinae_base -{ -private: - template - static yes & f(typename std::enable_if< - std::is_same(&C::begin)), - typename C::const_iterator(C::*)() const>::value>::type *); - - template static no & f(...); - - template - static yes & g(typename std::enable_if< - std::is_same(&C::end)), - typename C::const_iterator(C::*)() const>::value, void>::type*); - - template static no & g(...); + template static yes &test(typename C::const_iterator *); + template static no &test(...); public: - static bool const beg_value = sizeof(f(nullptr)) == sizeof(yes); - static bool const end_value = sizeof(g(nullptr)) == sizeof(yes); + static const bool value = sizeof(test(nullptr)) == sizeof(yes); + using type = T; }; -} // namespace detail +template struct has_begin_end : private sfinae_base { +private: + template + static yes & + f(typename std::enable_if< + std::is_same(&C::begin)), + typename C::const_iterator (C::*)() const>::value>::type *); + template static no &f(...); + + template + static yes & + g(typename std::enable_if< + std::is_same(&C::end)), + typename C::const_iterator (C::*)() const>::value, + void>::type *); + + template static no &g(...); + +public: + static bool const beg_value = sizeof(f(nullptr)) == sizeof(yes); + static bool const end_value = sizeof(g(nullptr)) == sizeof(yes); +}; + +} // namespace detail // Holds the delimiter values for a specific character type -template -struct delimiters_values -{ - using char_type = TChar; - const char_type * prefix; - const char_type * delimiter; - const char_type * postfix; +template struct delimiters_values { + using char_type = TChar; + const char_type *prefix; + const char_type *delimiter; + const char_type *postfix; }; - // Defines the delimiter values for a specific container and character type -template -struct delimiters -{ - using type = delimiters_values; - static const type values; +template struct delimiters { + using type = delimiters_values; + static const type values; }; - // Functor to pretty_print containers. You can use this directly if you want // to specificy a non-default delimiters type. The pretty_printing logic can // be customized by specializing the nested template. -template , typename TDelimiters = delimiters> -struct pretty_print_container_helper -{ - using delimiters_type = TDelimiters; - using ostream_type = std::basic_ostream; +struct pretty_print_container_helper { + using delimiters_type = TDelimiters; + using ostream_type = std::basic_ostream; - template - struct pretty_printer - { - static void pretty_print_body(const U & c, ostream_type & stream) - { - using std::begin; - using std::end; + template struct pretty_printer { + static void pretty_print_body(const U &c, ostream_type &stream) { + using std::begin; + using std::end; - auto it = begin(c); - const auto the_end = end(c); + auto it = begin(c); + const auto the_end = end(c); - if (it != the_end) - { - for ( ; ; ) - { - ::soi::print(stream, *it); + if (it != the_end) { + for (;;) { + ::soi::print(stream, *it); - if (++it == the_end) break; + if (++it == the_end) + break; - if (delimiters_type::values.delimiter != NULL) - ::soi::print(stream, delimiters_type::values.delimiter); - } - } + if (delimiters_type::values.delimiter != NULL) + ::soi::print(stream, delimiters_type::values.delimiter); } - }; - - pretty_print_container_helper(const T & container) - : container_(container) - { } - - inline void operator()(ostream_type & stream) const - { - if (delimiters_type::values.prefix != NULL) - ::soi::print(stream, delimiters_type::values.prefix); - - pretty_printer::pretty_print_body(container_, stream); - - if (delimiters_type::values.postfix != NULL) - ::soi::print(stream, delimiters_type::values.postfix); + } } + }; + + pretty_print_container_helper(const T &container) : container_(container) {} + + inline void operator()(ostream_type &stream) const { + if (delimiters_type::values.prefix != NULL) + ::soi::print(stream, delimiters_type::values.prefix); + + pretty_printer::pretty_print_body(container_, stream); + + if (delimiters_type::values.postfix != NULL) + ::soi::print(stream, delimiters_type::values.postfix); + } private: - const T & container_; + const T &container_; }; // Specialization for pairs -template +template template -struct pretty_print_container_helper::pretty_printer> -{ - using ostream_type = typename pretty_print_container_helper::ostream_type; +struct pretty_print_container_helper< + T, TChar, TCharTraits, TDelimiters>::pretty_printer> { + using ostream_type = + typename pretty_print_container_helper::ostream_type; - static void pretty_print_body(const std::pair & c, ostream_type & stream) - { - ::soi::print(stream, c.first); - if (pretty_print_container_helper::delimiters_type::values.delimiter != NULL) - ::soi::print(stream, pretty_print_container_helper::delimiters_type::values.delimiter); - ::soi::print(stream, c.second); - } + static void pretty_print_body(const std::pair &c, + ostream_type &stream) { + ::soi::print(stream, c.first); + if (pretty_print_container_helper::delimiters_type::values + .delimiter != NULL) + ::soi::print( + stream, + pretty_print_container_helper::delimiters_type::values + .delimiter); + ::soi::print(stream, c.second); + } }; // Specialization for tuples -template -template -struct pretty_print_container_helper::pretty_printer> -{ - using ostream_type = typename pretty_print_container_helper::ostream_type; - using element_type = std::tuple; +template +template +struct pretty_print_container_helper< + T, TChar, TCharTraits, TDelimiters>::pretty_printer> { + using ostream_type = + typename pretty_print_container_helper::ostream_type; + using element_type = std::tuple; - template struct Int { }; + template struct Int {}; - static void pretty_print_body(const element_type & c, ostream_type & stream) - { - tuple_pretty_print(c, stream, Int<0>()); - } + static void pretty_print_body(const element_type &c, ostream_type &stream) { + tuple_pretty_print(c, stream, Int<0>()); + } - static void tuple_pretty_print(const element_type &, ostream_type &, Int) - { - } + static void tuple_pretty_print(const element_type &, ostream_type &, + Int) {} - static void tuple_pretty_print(const element_type & c, ostream_type & stream, - typename std::conditional, std::nullptr_t>::type) - { - ::soi::print(stream, std::get<0>(c)); - tuple_pretty_print(c, stream, Int<1>()); - } + static void + tuple_pretty_print(const element_type &c, ostream_type &stream, + typename std::conditional, + std::nullptr_t>::type) { + ::soi::print(stream, std::get<0>(c)); + tuple_pretty_print(c, stream, Int<1>()); + } - template - static void tuple_pretty_print(const element_type & c, ostream_type & stream, Int) - { - if (pretty_print_container_helper::delimiters_type::values.delimiter != NULL) - ::soi::print(stream, pretty_print_container_helper::delimiters_type::values.delimiter); + template + static void tuple_pretty_print(const element_type &c, ostream_type &stream, + Int) { + if (pretty_print_container_helper::delimiters_type::values + .delimiter != NULL) + ::soi::print( + stream, + pretty_print_container_helper::delimiters_type::values + .delimiter); - ::soi::print(stream, std::get(c)); + ::soi::print(stream, std::get(c)); - tuple_pretty_print(c, stream, Int()); - } + tuple_pretty_print(c, stream, Int()); + } }; // Pretty_Prints a pretty_print_container_helper to the specified stream. -template -inline std::basic_ostream & pretty_print( - std::basic_ostream & stream, - const pretty_print_container_helper & helper) -{ - helper(stream); - return stream; +template +inline std::basic_ostream & +pretty_print(std::basic_ostream &stream, + const pretty_print_container_helper &helper) { + helper(stream); + return stream; } - -// Basic is_container template; specialize to derive from std::true_type for all desired container types +// Basic is_container template; specialize to derive from std::true_type for all +// desired container types template -struct is_container : public std::integral_constant::value && - detail::has_begin_end::beg_value && - detail::has_begin_end::end_value> { }; +struct is_container + : public std::integral_constant::value && + detail::has_begin_end::beg_value && + detail::has_begin_end::end_value> {}; template -struct is_container : std::true_type { }; +struct is_container : std::true_type {}; -template -struct is_container : std::false_type { }; +template struct is_container : std::false_type {}; -template -struct is_container> : std::true_type { }; +template struct is_container> : std::true_type {}; template -struct is_container> : std::true_type { }; - -template -struct is_container> : std::true_type { }; +struct is_container> : std::true_type {}; +template +struct is_container> : std::true_type {}; // Default delimiters -template struct delimiters { static const delimiters_values values; }; -template const delimiters_values delimiters::values = { "[", ", ", "]" }; -template struct delimiters { static const delimiters_values values; }; -template const delimiters_values delimiters::values = { L"[", L", ", L"]" }; - +template struct delimiters { + static const delimiters_values values; +}; +template +const delimiters_values delimiters::values = {"[", ", ", "]"}; +template struct delimiters { + static const delimiters_values values; +}; +template +const delimiters_values delimiters::values = {L"[", L", ", + L"]"}; // Delimiters for (multi)set and unordered_(multi)set template -struct delimiters< ::std::set, char> { static const delimiters_values values; }; +struct delimiters<::std::set, char> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::set, char>::values = { "{", ", ", "}" }; +const delimiters_values + delimiters<::std::set, char>::values = {"{", ", ", + "}"}; template -struct delimiters< ::std::set, wchar_t> { static const delimiters_values values; }; +struct delimiters<::std::set, wchar_t> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::set, wchar_t>::values = { L"{", L", ", L"}" }; +const delimiters_values + delimiters<::std::set, wchar_t>::values = { + L"{", L", ", L"}"}; template -struct delimiters< ::std::multiset, char> { static const delimiters_values values; }; +struct delimiters<::std::multiset, char> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::multiset, char>::values = { "{", ", ", "}" }; +const delimiters_values delimiters<::std::multiset, + char>::values = {"{", ", ", "}"}; template -struct delimiters< ::std::multiset, wchar_t> { static const delimiters_values values; }; +struct delimiters<::std::multiset, wchar_t> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::multiset, wchar_t>::values = { L"{", L", ", L"}" }; +const delimiters_values + delimiters<::std::multiset, wchar_t>::values = { + L"{", L", ", L"}"}; template -struct delimiters< ::std::unordered_set, char> { static const delimiters_values values; }; +struct delimiters<::std::unordered_set, char> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::unordered_set, char>::values = { "{", ", ", "}" }; +const delimiters_values delimiters< + ::std::unordered_set, char>::values = { + "{", ", ", "}"}; template -struct delimiters< ::std::unordered_set, wchar_t> { static const delimiters_values values; }; +struct delimiters<::std::unordered_set, wchar_t> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::unordered_set, wchar_t>::values = { L"{", L", ", L"}" }; +const delimiters_values delimiters< + ::std::unordered_set, wchar_t>::values = { + L"{", L", ", L"}"}; template -struct delimiters< ::std::unordered_multiset, char> { static const delimiters_values values; }; +struct delimiters<::std::unordered_multiset, + char> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::unordered_multiset, char>::values = { "{", ", ", "}" }; +const delimiters_values delimiters< + ::std::unordered_multiset, char>::values = { + "{", ", ", "}"}; template -struct delimiters< ::std::unordered_multiset, wchar_t> { static const delimiters_values values; }; +struct delimiters<::std::unordered_multiset, + wchar_t> { + static const delimiters_values values; +}; template -const delimiters_values delimiters< ::std::unordered_multiset, wchar_t>::values = { L"{", L", ", L"}" }; - +const delimiters_values + delimiters<::std::unordered_multiset, + wchar_t>::values = {L"{", L", ", L"}"}; // Delimiters for pair and tuple -template struct delimiters, char> { static const delimiters_values values; }; -template const delimiters_values delimiters, char>::values = { "(", ", ", ")" }; -template struct delimiters< ::std::pair, wchar_t> { static const delimiters_values values; }; -template const delimiters_values delimiters< ::std::pair, wchar_t>::values = { L"(", L", ", L")" }; - -template struct delimiters, char> { static const delimiters_values values; }; -template const delimiters_values delimiters, char>::values = { "(", ", ", ")" }; -template struct delimiters< ::std::tuple, wchar_t> { static const delimiters_values values; }; -template const delimiters_values delimiters< ::std::tuple, wchar_t>::values = { L"(", L", ", L")" }; +template struct delimiters, char> { + static const delimiters_values values; +}; +template +const delimiters_values delimiters, char>::values = { + "(", ", ", ")"}; +template +struct delimiters<::std::pair, wchar_t> { + static const delimiters_values values; +}; +template +const delimiters_values + delimiters<::std::pair, wchar_t>::values = {L"(", L", ", L")"}; +template struct delimiters, char> { + static const delimiters_values values; +}; +template +const delimiters_values delimiters, char>::values = { + "(", ", ", ")"}; +template struct delimiters<::std::tuple, wchar_t> { + static const delimiters_values values; +}; +template +const delimiters_values + delimiters<::std::tuple, wchar_t>::values = {L"(", L", ", L")"}; // Type-erasing helper class for easy use of custom delimiters. -// Requires TCharTraits = std::char_traits and TChar = char or wchar_t, and MyDelims needs to be defined for TChar. -// Usage: "cout << pretty_pretty_print::custom_delims(x)". +// Requires TCharTraits = std::char_traits and TChar = char or wchar_t, +// and MyDelims needs to be defined for TChar. Usage: "cout << +// pretty_pretty_print::custom_delims(x)". -struct custom_delims_base -{ - virtual ~custom_delims_base() { } - virtual std::ostream & stream(::std::ostream &) = 0; - virtual std::wostream & stream(::std::wostream &) = 0; +struct custom_delims_base { + virtual ~custom_delims_base() {} + virtual std::ostream &stream(::std::ostream &) = 0; + virtual std::wostream &stream(::std::wostream &) = 0; }; template -struct custom_delims_wrapper : custom_delims_base -{ - custom_delims_wrapper(const T & t_) : t(t_) { } +struct custom_delims_wrapper : custom_delims_base { + custom_delims_wrapper(const T &t_) : t(t_) {} - std::ostream & stream(std::ostream & s) - { - return pretty_print(s, pretty_print_container_helper, Delims>(t)); - } + std::ostream &stream(std::ostream &s) { + return pretty_print( + s, + pretty_print_container_helper, Delims>( + t)); + } - std::wostream & stream(std::wostream & s) - { - return pretty_print(s, pretty_print_container_helper, Delims>(t)); - } + std::wostream &stream(std::wostream &s) { + return pretty_print( + s, pretty_print_container_helper, + Delims>(t)); + } private: - const T & t; + const T &t; }; -template -struct custom_delims -{ - template - custom_delims(const Container & c) : base(new custom_delims_wrapper(c)) { } +template struct custom_delims { + template + custom_delims(const Container &c) + : base(new custom_delims_wrapper(c)) {} - std::unique_ptr base; + std::unique_ptr base; }; template -inline std::basic_ostream & pretty_print(std::basic_ostream & s, const custom_delims & p) -{ - return p.base->stream(s); +inline std::basic_ostream & +pretty_print(std::basic_ostream &s, + const custom_delims &p) { + return p.base->stream(s); } - // A wrapper for a C-style array given as pointer-plus-size. // Usage: std::cout << pretty_pretty_print_array(arr, n) << std::endl; -template -struct array_wrapper_n -{ - typedef const T * const_iterator; - typedef T value_type; +template struct array_wrapper_n { + typedef const T *const_iterator; + typedef T value_type; - array_wrapper_n(const T * const a, size_t n) : _array(a), _n(n) { } - inline const_iterator begin() const { return _array; } - inline const_iterator end() const { return _array + _n; } + array_wrapper_n(const T *const a, size_t n) : _array(a), _n(n) {} + inline const_iterator begin() const { return _array; } + inline const_iterator end() const { return _array + _n; } private: - const T * const _array; - size_t _n; + const T *const _array; + size_t _n; }; +// A wrapper for hash-table based containers that offer local iterators to each +// bucket. Usage: std::cout << bucket_pretty_print(m, 4) << std::endl; +// (Pretty_Prints bucket 5 of container m.) -// A wrapper for hash-table based containers that offer local iterators to each bucket. -// Usage: std::cout << bucket_pretty_print(m, 4) << std::endl; (Pretty_Prints bucket 5 of container m.) +template struct bucket_pretty_print_wrapper { + typedef typename T::const_local_iterator const_iterator; + typedef typename T::size_type size_type; -template -struct bucket_pretty_print_wrapper -{ - typedef typename T::const_local_iterator const_iterator; - typedef typename T::size_type size_type; + const_iterator begin() const { return m_map.cbegin(n); } - const_iterator begin() const - { - return m_map.cbegin(n); - } + const_iterator end() const { return m_map.cend(n); } - const_iterator end() const - { - return m_map.cend(n); - } - - bucket_pretty_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { } + bucket_pretty_print_wrapper(const T &m, size_type bucket) + : m_map(m), n(bucket) {} private: - const T & m_map; - const size_type n; + const T &m_map; + const size_type n; }; -} // namespace soi - +} // namespace soi /* // Global accessor functions for the convenience wrappers template -inline pretty_pretty_print::array_wrapper_n pretty_pretty_print_array(const T * const a, size_t n) +inline pretty_pretty_print::array_wrapper_n pretty_pretty_print_array(const T +* const a, size_t n) { return pretty_pretty_print::array_wrapper_n(a, n); } @@ -433,18 +479,18 @@ return pretty_pretty_print::bucket_pretty_print_wrapper(m, n); */ -namespace soi -{ +namespace soi { // Pretty_Prints a container to the stream using default delimiters -template -inline typename std::enable_if< ::soi::is_container::value, - std::basic_ostream &>::type -pretty_print(std::basic_ostream & stream, const T & container) -{ - return ::soi::print(stream, ::soi::pretty_print_container_helper(container)); -} +template +inline typename std::enable_if<::soi::is_container::value, + std::basic_ostream &>::type +pretty_print(std::basic_ostream &stream, + const T &container) { + return ::soi::print( + stream, + ::soi::pretty_print_container_helper(container)); } +} // namespace soi - -#endif // SOI_PRETTY_PRETTY_PRINT +#endif // SOI_PRETTY_PRETTY_PRINT diff --git a/include/bits/soi-dbg.hpp b/include/bits/soi-dbg.hpp index d3544c7..cbb47a4 100644 --- a/include/bits/soi-dbg.hpp +++ b/include/bits/soi-dbg.hpp @@ -11,11 +11,11 @@ #define SOI_DBG #include -#include #include -#include #include +#include #include +#include #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #include @@ -31,113 +31,99 @@ namespace detail { // detecting the type name: https://stackoverflow.com/a/20170989 #ifndef _MSC_VER -# if __cplusplus < 201103 -# define CONSTEXPR11_TN -# define CONSTEXPR14_TN -# define NOEXCEPT_TN -# elif __cplusplus < 201402 -# define CONSTEXPR11_TN constexpr -# define CONSTEXPR14_TN -# define NOEXCEPT_TN noexcept -# else -# define CONSTEXPR11_TN constexpr -# define CONSTEXPR14_TN constexpr -# define NOEXCEPT_TN noexcept -# endif -#else // _MSC_VER -# if _MSC_VER < 1900 -# define CONSTEXPR11_TN -# define CONSTEXPR14_TN -# define NOEXCEPT_TN -# elif _MSC_VER < 2000 -# define CONSTEXPR11_TN constexpr -# define CONSTEXPR14_TN -# define NOEXCEPT_TN noexcept -# else -# define CONSTEXPR11_TN constexpr -# define CONSTEXPR14_TN constexpr -# define NOEXCEPT_TN noexcept -# endif -#endif // _MSC_VER +#if __cplusplus < 201103 +#define CONSTEXPR11_TN +#define CONSTEXPR14_TN +#define NOEXCEPT_TN +#elif __cplusplus < 201402 +#define CONSTEXPR11_TN constexpr +#define CONSTEXPR14_TN +#define NOEXCEPT_TN noexcept +#else +#define CONSTEXPR11_TN constexpr +#define CONSTEXPR14_TN constexpr +#define NOEXCEPT_TN noexcept +#endif +#else // _MSC_VER +#if _MSC_VER < 1900 +#define CONSTEXPR11_TN +#define CONSTEXPR14_TN +#define NOEXCEPT_TN +#elif _MSC_VER < 2000 +#define CONSTEXPR11_TN constexpr +#define CONSTEXPR14_TN +#define NOEXCEPT_TN noexcept +#else +#define CONSTEXPR11_TN constexpr +#define CONSTEXPR14_TN constexpr +#define NOEXCEPT_TN noexcept +#endif +#endif // _MSC_VER class static_string { - const char* const p_; - const std::size_t sz_; + const char *const p_; + const std::size_t sz_; public: - typedef const char* const_iterator; + typedef const char *const_iterator; - template - CONSTEXPR11_TN static_string(const char(&a)[N]) NOEXCEPT_TN - : p_(a) - , sz_(N-1) - {} + template + CONSTEXPR11_TN static_string(const char (&a)[N]) NOEXCEPT_TN : p_(a), + sz_(N - 1) {} - CONSTEXPR11_TN static_string(const char* p, std::size_t N) NOEXCEPT_TN - : p_(p) - , sz_(N) - {} + CONSTEXPR11_TN static_string(const char *p, std::size_t N) NOEXCEPT_TN + : p_(p), + sz_(N) {} - CONSTEXPR11_TN const char* data() const NOEXCEPT_TN {return p_;} - CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN {return sz_;} + CONSTEXPR11_TN const char *data() const NOEXCEPT_TN { return p_; } + CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN { return sz_; } - CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN {return p_;} - CONSTEXPR11_TN const_iterator end() const NOEXCEPT_TN {return p_ + sz_;} + CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN { return p_; } + CONSTEXPR11_TN const_iterator end() const NOEXCEPT_TN { return p_ + sz_; } - CONSTEXPR11_TN char operator[](std::size_t n) const - { - return n < sz_ ? p_[n] : throw std::out_of_range("static_string"); - } + CONSTEXPR11_TN char operator[](std::size_t n) const { + return n < sz_ ? p_[n] : throw std::out_of_range("static_string"); + } }; -inline -std::ostream& -operator<<(std::ostream& os, static_string const& s) -{ - return os.write(s.data(), s.size()); +inline std::ostream &operator<<(std::ostream &os, static_string const &s) { + return os.write(s.data(), s.size()); } -template -CONSTEXPR14_TN -static_string -type_name() -{ - const int k = sizeof("constexpr soi::detail:: T")/sizeof(char); +template CONSTEXPR14_TN static_string type_name() { + const int k = sizeof("constexpr soi::detail:: T") / sizeof(char); #ifdef __clang__ - static_string p = __PRETTY_FUNCTION__; - return static_string(p.data() + 31 + k, p.size() - 31 - k - 1); + static_string p = __PRETTY_FUNCTION__; + return static_string(p.data() + 31 + k, p.size() - 31 - k - 1); #elif defined(__GNUC__) - static_string p = __PRETTY_FUNCTION__; -# if __cplusplus < 201402 - return static_string(p.data() + 36 + k, p.size() - 36 - k - 1); -# else - return static_string(p.data() + 46 + k, p.size() - 46 - k - 1); -# endif + static_string p = __PRETTY_FUNCTION__; +#if __cplusplus < 201402 + return static_string(p.data() + 36 + k, p.size() - 36 - k - 1); +#else + return static_string(p.data() + 46 + k, p.size() - 46 - k - 1); +#endif #elif defined(_MSC_VER) - static_string p = __FUNCSIG__; - return static_string(p.data() + 38 + k, p.size() - 38 - k - 7); + static_string p = __FUNCSIG__; + return static_string(p.data() + 38 + k, p.size() - 38 - k - 7); #endif } constexpr bool is_prefix_of(char const *suffix, char const *s) { - return suffix[0]=='\0' || (suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1)); + return suffix[0] == '\0' || + (suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1)); } -static char const* const type_string = "string"; +static char const *const type_string = "string"; -template -CONSTEXPR14_TN -static_string -sanitized_type_name() { +template CONSTEXPR14_TN static_string sanitized_type_name() { CONSTEXPR14_TN static_string t = type_name(); CONSTEXPR14_TN std::size_t offset = - is_prefix_of("std::__debug::", t.data()) ? sizeof("std::__debug::")-1 : - is_prefix_of("std::", t.data()) ? sizeof("std::")-1 : - 0; - return - is_prefix_of("std::__cxx11::basic_string", t.data()) ? - static_string(type_string, sizeof(type_string)-2) : - static_string(t.data()+offset, t.size()-offset); + is_prefix_of("std::__debug::", t.data()) + ? sizeof("std::__debug::") - 1 + : is_prefix_of("std::", t.data()) ? sizeof("std::") - 1 : 0; + return is_prefix_of("std::__cxx11::basic_string", t.data()) + ? static_string(type_string, sizeof(type_string) - 2) + : static_string(t.data() + offset, t.size() - offset); } // ---------------------------------------------------------------------------- @@ -152,7 +138,7 @@ bool tty_supports_colors() { } int has_environment_color_overwrite() { - if (const char* color_enabled = std::getenv("SOI_COLOR")) { + if (const char *color_enabled = std::getenv("SOI_COLOR")) { if (!std::strcmp(color_enabled, "1")) return 1; if (!std::strcmp(color_enabled, "0")) @@ -172,12 +158,12 @@ bool are_colors_enabled() { // init and static variables static bool colors_enabled = false; -static const char* ANSI_DEBUG = ""; -static const char* ANSI_EXPRESSION = ""; -static const char* ANSI_VALUE = ""; -static const char* ANSI_TYPE = ""; -static const char* ANSI_MESSAGE = ""; -static const char* ANSI_RESET = ""; +static const char *ANSI_DEBUG = ""; +static const char *ANSI_EXPRESSION = ""; +static const char *ANSI_VALUE = ""; +static const char *ANSI_TYPE = ""; +static const char *ANSI_MESSAGE = ""; +static const char *ANSI_RESET = ""; void dbg_init(bool with_colors) { if (with_colors) { @@ -199,70 +185,51 @@ void dbg_init(bool with_colors) { } } -void dbg_init() { - dbg_init(are_colors_enabled()); -} +void dbg_init() { dbg_init(are_colors_enabled()); } // ---------------------------------------------------------------------------- // printer template -T&& dbg_print(T&& value, - static_string const& type, - char const* file, - int line, - char const* function_name, - char const* expression) { - const T& ref = value; - std::stringstream value_buffer; // avoid nesting of dbg macros within print functinos +T &&dbg_print(T &&value, static_string const &type, char const *file, int line, + char const *function_name, char const *expression) { + const T &ref = value; + std::stringstream + value_buffer; // avoid nesting of dbg macros within print functinos soi::print(value_buffer, ref); - std::cerr << ANSI_DEBUG - << "[" << file << ":" << line - << " (" << function_name << ")] " << ANSI_RESET - << ANSI_EXPRESSION << expression << ANSI_RESET - << " = " - << ANSI_VALUE << value_buffer.rdbuf() << ANSI_RESET - << " (" << ANSI_TYPE << type << ANSI_RESET << ")" + std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name + << ")] " << ANSI_RESET << ANSI_EXPRESSION << expression + << ANSI_RESET << " = " << ANSI_VALUE << value_buffer.rdbuf() + << ANSI_RESET << " (" << ANSI_TYPE << type << ANSI_RESET << ")" << '\n'; return std::forward(value); } -template -auto dbg_print(const char (&msg)[N], - static_string const&, - char const* file, - int line, - char const* function_name, - char const* expression) -> decltype(msg) { - std::cerr << ANSI_DEBUG - << "[" << file << ":" << line - << " (" << function_name << ")] " << ANSI_RESET - << ANSI_MESSAGE << msg << ANSI_RESET - << '\n'; +template +auto dbg_print(const char (&msg)[N], static_string const &, char const *file, + int line, char const *function_name, char const *expression) + -> decltype(msg) { + std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name + << ")] " << ANSI_RESET << ANSI_MESSAGE << msg << ANSI_RESET << '\n'; return msg; } -template -T&& identity(T&& t) { - return std::forward(t); -} +template T &&identity(T &&t) { return std::forward(t); } } // end namespace detail -} // end namespace dbg_macro +} // namespace soi #ifdef SOI_RELEASE #define dbg(...) dbg_macro::identity(__VA_ARGS__) #else -#define dbg(...) \ - soi::detail::dbg_print((__VA_ARGS__), \ - soi::detail::sanitized_type_name(), \ - __FILE__, \ - __LINE__, \ - __func__, \ - #__VA_ARGS__) +#define dbg(...) \ + soi::detail::dbg_print( \ + (__VA_ARGS__), \ + soi::detail::sanitized_type_name(), __FILE__, \ + __LINE__, __func__, #__VA_ARGS__) #endif -#endif // SOI_DBG +#endif // SOI_DBG diff --git a/include/bits/soi-deprecate.hpp b/include/bits/soi-deprecate.hpp index eae61d3..e6676ae 100644 --- a/include/bits/soi-deprecate.hpp +++ b/include/bits/soi-deprecate.hpp @@ -1,24 +1,32 @@ #pragma GCC diagnostic error "-Wdeprecated-declarations" -struct endl_is_evil_t {} endl_is_evil; -[[deprecated("endl is evil. Use '\\n' to print a newline.")]] std::ostream & operator<<(std::ostream &os, endl_is_evil_t); +struct endl_is_evil_t { +} endl_is_evil; +[[deprecated("endl is evil. Use '\\n' to print a newline.")]] std::ostream & +operator<<(std::ostream &os, endl_is_evil_t); #define endl endl_is_evil #define printf printf_is_evil #define fprintf fprintf_is_evil #define sprintf sprintf_is_evil #define snprintf snprintf_is_evil -[[deprecated("printf is evil. Use cout.")]] int printf(const char *format, ...); -[[deprecated("printf is evil. Use cout.")]] int fprintf(std::FILE *stream, const char *format, ...); -[[deprecated("printf is evil. Use cout.")]] int sprintf(char *buffer, const char *format, ...); -[[deprecated("printf is evil. Use cout.")]] int snprintf(char *buffer, std::size_t buf_size, const char *format, ...); +[[deprecated("printf is evil. Use cout.")]] int printf(const char *format, + ...); +[[deprecated("printf is evil. Use cout.")]] int +fprintf(std::FILE *stream, const char *format, ...); +[[deprecated("printf is evil. Use cout.")]] int +sprintf(char *buffer, const char *format, ...); +[[deprecated("printf is evil. Use cout.")]] int +snprintf(char *buffer, std::size_t buf_size, const char *format, ...); #define scanf scanf_is_evil #define fscanf fscanf_is_evil #define sscanf sscanf_is_evil [[deprecated("scanf is evil. Use cin.")]] int scanf(const char *format, ...); -[[deprecated("scanf is evil. Use cin.")]] int fscanf(std::FILE *stream, const char *format, ...); -[[deprecated("scanf is evil. Use cin.")]] int sscanf(const char *buffer, const char *format, ...); +[[deprecated("scanf is evil. Use cin.")]] int fscanf(std::FILE *stream, + const char *format, ...); +[[deprecated("scanf is evil. Use cin.")]] int sscanf(const char *buffer, + const char *format, ...); #define puts puts_is_evil #define fputs fputs_is_evil @@ -35,28 +43,45 @@ struct endl_is_evil_t {} endl_is_evil; #define fread fread_is_evil #define fwrite fwrite_is_evil [[deprecated(" is evil. Use cin/cout.")]] int puts(const char *str); -[[deprecated(" is evil. Use cin/cout.")]] int fputs(const char *str, FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] char *fgets(char *str, int count, FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] std::FILE *freopen(const char *filename, const char *mode, std::FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] std::FILE *fopen(const char *filename, const char *mode); -[[deprecated(" is evil. Use cin/cout.")]] int fclose(std::FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] int fflush(std::FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] int fputs(const char *str, + FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] char * +fgets(char *str, int count, FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] std::FILE * +freopen(const char *filename, const char *mode, std::FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] std::FILE * +fopen(const char *filename, const char *mode); +[[deprecated(" is evil. Use cin/cout.")]] int +fclose(std::FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] int +fflush(std::FILE *stream); [[deprecated(" is evil. Use cin/cout.")]] int getchar(); [[deprecated(" is evil. Use cin/cout.")]] int fgetc(std::FILE *stream); [[deprecated(" is evil. Use cin/cout.")]] int getc(std::FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] void setbuf(std::FILE *stream, char *buffer); -[[deprecated(" is evil. Use cin/cout.")]] int setvbuf(std::FILE *stream, char *buffer, int mode, std::size_t size); -[[deprecated(" is evil. Use cin/cout.")]] std::size_t fread(void *buffer, std::size_t size, std::size_t count, std::FILE *stream); -[[deprecated(" is evil. Use cin/cout.")]] std::size_t fwrite(const void *buffer, std::size_t size, std::size_t count, std::FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] void +setbuf(std::FILE *stream, char *buffer); +[[deprecated(" is evil. Use cin/cout.")]] int +setvbuf(std::FILE *stream, char *buffer, int mode, std::size_t size); +[[deprecated(" is evil. Use cin/cout.")]] std::size_t +fread(void *buffer, std::size_t size, std::size_t count, std::FILE *stream); +[[deprecated(" is evil. Use cin/cout.")]] std::size_t +fwrite(const void *buffer, std::size_t size, std::size_t count, + std::FILE *stream); #define malloc malloc_is_evil #define calloc calloc_is_evil #define realloc realloc_is_evil #define free free_is_evil -[[deprecated("malloc/free is evil. Use a vector.")]] void *malloc(std::size_t size); -[[deprecated("malloc/free is evil. Use a vector.")]] void *calloc(std::size_t num, std::size_t size); -[[deprecated("malloc/free is evil. Use a vector.")]] void *realloc(void *ptr, std::size_t new_size); -[[deprecated("malloc/free is evil. Use a vector.")]] void *free(void *ptr, std::size_t new_size); +[[deprecated("malloc/free is evil. Use a vector.")]] void * +malloc(std::size_t size); +[[deprecated("malloc/free is evil. Use a vector.")]] void * +calloc(std::size_t num, std::size_t size); +[[deprecated("malloc/free is evil. Use a vector.")]] void * +realloc(void *ptr, std::size_t new_size); +[[deprecated("malloc/free is evil. Use a vector.")]] void * +free(void *ptr, std::size_t new_size); -[[deprecated("new is evil. Use a vector.")]] void *operator new(std::size_t sz); -[[deprecated("delete is evil. Use a vector.")]] void operator delete(void *ptr) noexcept; +[[deprecated("new is evil. Use a vector.")]] void * +operator new(std::size_t sz); +[[deprecated("delete is evil. Use a vector.")]] void +operator delete(void *ptr) noexcept; diff --git a/include/bits/soi-pretty.hpp b/include/bits/soi-pretty.hpp index 13925a1..0cd802e 100644 --- a/include/bits/soi-pretty.hpp +++ b/include/bits/soi-pretty.hpp @@ -13,63 +13,88 @@ namespace soi { -template +template std::basic_ostream & -pretty_print(std::basic_ostream & stream, const bool& x) { +pretty_print(std::basic_ostream &stream, const bool &x) { return stream << (x ? "true" : "false"); } namespace detail { -template -void escape_char(std::basic_ostream & stream, char c) { +template +void escape_char(std::basic_ostream &stream, char c) { switch (c) { - case '\a': stream << "\\a"; break; - case '\b': stream << "\\b"; break; - case '\t': stream << "\\t"; break; - case '\n': stream << "\\n"; break; - case '\v': stream << "\\v"; break; - case '\f': stream << "\\f"; break; - case '\r': stream << "\\r"; break; - case '\e': stream << "\\e"; break; - case '\"': stream << "\\\""; break; - case '\'': stream << "\\'"; break; - case '\?': stream << "\\?"; break; - case '\\': stream << "\\\\"; break; - default: stream << c; + case '\a': + stream << "\\a"; + break; + case '\b': + stream << "\\b"; + break; + case '\t': + stream << "\\t"; + break; + case '\n': + stream << "\\n"; + break; + case '\v': + stream << "\\v"; + break; + case '\f': + stream << "\\f"; + break; + case '\r': + stream << "\\r"; + break; + case '\e': + stream << "\\e"; + break; + case '\"': + stream << "\\\""; + break; + case '\'': + stream << "\\'"; + break; + case '\?': + stream << "\\?"; + break; + case '\\': + stream << "\\\\"; + break; + default: + stream << c; } } -} +} // namespace detail -template +template std::basic_ostream & -pretty_print(std::basic_ostream & stream, const std::string& x) { +pretty_print(std::basic_ostream &stream, + const std::string &x) { stream << "\""; for (char c : x) detail::escape_char(stream, c); return stream << "\""; } -template +template std::basic_ostream & -pretty_print(std::basic_ostream & stream, char c) { +pretty_print(std::basic_ostream &stream, char c) { stream << "'"; detail::escape_char(stream, c); return stream << "'"; } -template -inline typename std::enable_if< !::soi::is_container::value, - std::basic_ostream &>::type -pretty_print(std::basic_ostream & stream, const T& x) { +template +inline typename std::enable_if::value, + std::basic_ostream &>::type +pretty_print(std::basic_ostream &stream, const T &x) { return stream << x; } - -template +template std::basic_ostream & -print(std::basic_ostream & stream, const T& x) { +print(std::basic_ostream &stream, const T &x) { return pretty_print(stream, x); } -} +} // namespace soi #endif // SOI_PRETTY diff --git a/include/soi b/include/soi index a3e57c8..8e3c092 100644 --- a/include/soi +++ b/include/soi @@ -5,20 +5,20 @@ have to understand every concept all at once. */ -#include #include "bits/soi-dbg.hpp" +#include namespace soi { void check_for_eof() { - if (!(std::cin >> std::ws).eof()) - std::cerr << "WARNING: didn't read the whole input\n"; + if (!(std::cin >> std::ws).eof()) + std::cerr << "WARNING: didn't read the whole input\n"; } void noninteractive_check_eof() { // make symbol 0x1A (Ctrl+Z) a whitespace struct console_ctype : std::ctype { - static const mask* get_table() { + static const mask *get_table() { static const std::array table = []() { std::array table; std::copy(classic_table(), classic_table() + table_size, table.begin()); @@ -27,14 +27,14 @@ void noninteractive_check_eof() { }(); return table.data(); } - console_ctype(std::size_t refs = 0) : ctype(get_table(), false, refs) {} + console_ctype(std::size_t refs = 0) : ctype(get_table(), false, refs) {} }; std::cin.imbue(std::locale(std::cin.getloc(), new console_ctype)); check_for_eof(); } bool should_check_for_eof() { - if (const char* eofcheck_enabled = std::getenv("SOI_EOFCHECK")) { + if (const char *eofcheck_enabled = std::getenv("SOI_EOFCHECK")) { if (!std::strcmp(eofcheck_enabled, "1")) return true; if (!std::strcmp(eofcheck_enabled, "0")) @@ -48,9 +48,9 @@ void initialize_debug() { std::cin.exceptions(std::ifstream::failbit | std::ifstream::badbit); std::ios::sync_with_stdio(false); - if (should_check_for_eof() && - std::atexit(noninteractive_check_eof) != 0) { - std::cerr << "WARNING: soi.h -- registration of sanity check at exit failed\n"; + if (should_check_for_eof() && std::atexit(noninteractive_check_eof) != 0) { + std::cerr + << "WARNING: soi.h -- registration of sanity check at exit failed\n"; } soi::detail::dbg_init(); }