diff options
Diffstat (limited to 'third_party/immer/tools/include/prettyprint.hpp')
-rw-r--r-- | third_party/immer/tools/include/prettyprint.hpp | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/third_party/immer/tools/include/prettyprint.hpp b/third_party/immer/tools/include/prettyprint.hpp deleted file mode 100644 index f75683ccdd51..000000000000 --- a/third_party/immer/tools/include/prettyprint.hpp +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright Louis Delacroix 2010 - 2014. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// A pretty printing library for C++ -// -// Usage: -// Include this header, and operator<< will "just work". - -#ifndef H_PRETTY_PRINT -#define H_PRETTY_PRINT - -#include <cstddef> -#include <iterator> -#include <memory> -#include <ostream> -#include <set> -#include <tuple> -#include <type_traits> -#include <unordered_set> -#include <utility> -#include <valarray> - -namespace pretty_print -{ - namespace detail - { - // SFINAE type trait to detect whether T::const_iterator exists. - - struct sfinae_base - { - using yes = char; - using no = yes[2]; - }; - - template <typename T> - struct has_const_iterator : private sfinae_base - { - private: - template <typename C> static yes & test(typename C::const_iterator*); - template <typename C> static no & test(...); - public: - static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes); - using type = T; - }; - - template <typename T> - struct has_begin_end : private sfinae_base - { - private: - template <typename C> - static yes & f(typename std::enable_if< - std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)), - typename C::const_iterator(C::*)() const>::value>::type *); - - template <typename C> static no & f(...); - - template <typename C> - static yes & g(typename std::enable_if< - std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)), - typename C::const_iterator(C::*)() const>::value, void>::type*); - - template <typename C> static no & g(...); - - public: - static bool const beg_value = sizeof(f<T>(nullptr)) == sizeof(yes); - static bool const end_value = sizeof(g<T>(nullptr)) == sizeof(yes); - }; - - } // namespace detail - - - // Holds the delimiter values for a specific character type - - template <typename TChar> - 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 <typename T, typename TChar> - struct delimiters - { - using type = delimiters_values<TChar>; - static const type values; - }; - - - // Functor to print containers. You can use this directly if you want - // to specificy a non-default delimiters type. The printing logic can - // be customized by specializing the nested template. - - template <typename T, - typename TChar = char, - typename TCharTraits = ::std::char_traits<TChar>, - typename TDelimiters = delimiters<T, TChar>> - struct print_container_helper - { - using delimiters_type = TDelimiters; - using ostream_type = std::basic_ostream<TChar, TCharTraits>; - - template <typename U> - struct printer - { - static void print_body(const U & c, ostream_type & stream) - { - using std::begin; - using std::end; - - auto it = begin(c); - const auto the_end = end(c); - - if (it != the_end) - { - for ( ; ; ) - { - stream << *it; - - if (++it == the_end) break; - - if (delimiters_type::values.delimiter != NULL) - stream << delimiters_type::values.delimiter; - } - } - } - }; - - print_container_helper(const T & container) - : container_(container) - { } - - inline void operator()(ostream_type & stream) const - { - if (delimiters_type::values.prefix != NULL) - stream << delimiters_type::values.prefix; - - printer<T>::print_body(container_, stream); - - if (delimiters_type::values.postfix != NULL) - stream << delimiters_type::values.postfix; - } - - private: - const T & container_; - }; - - // Specialization for pairs - - template <typename T, typename TChar, typename TCharTraits, typename TDelimiters> - template <typename T1, typename T2> - struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>> - { - using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type; - - static void print_body(const std::pair<T1, T2> & c, ostream_type & stream) - { - stream << c.first; - if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL) - stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter; - stream << c.second; - } - }; - - // Specialization for tuples - - template <typename T, typename TChar, typename TCharTraits, typename TDelimiters> - template <typename ...Args> - struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>> - { - using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type; - using element_type = std::tuple<Args...>; - - template <std::size_t I> struct Int { }; - - static void print_body(const element_type & c, ostream_type & stream) - { - tuple_print(c, stream, Int<0>()); - } - - static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>) - { - } - - static void tuple_print(const element_type & c, ostream_type & stream, - typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type) - { - stream << std::get<0>(c); - tuple_print(c, stream, Int<1>()); - } - - template <std::size_t N> - static void tuple_print(const element_type & c, ostream_type & stream, Int<N>) - { - if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL) - stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter; - - stream << std::get<N>(c); - - tuple_print(c, stream, Int<N + 1>()); - } - }; - - // Prints a print_container_helper to the specified stream. - - template<typename T, typename TChar, typename TCharTraits, typename TDelimiters> - inline std::basic_ostream<TChar, TCharTraits> & operator<<( - std::basic_ostream<TChar, TCharTraits> & stream, - const print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper) - { - helper(stream); - return stream; - } - - - // Basic is_container template; specialize to derive from std::true_type for all desired container types - - template <typename T> - struct is_container : public std::integral_constant<bool, - detail::has_const_iterator<T>::value && - detail::has_begin_end<T>::beg_value && - detail::has_begin_end<T>::end_value> { }; - - template <typename T, std::size_t N> - struct is_container<T[N]> : std::true_type { }; - - template <std::size_t N> - struct is_container<char[N]> : std::false_type { }; - - template <typename T> - struct is_container<std::valarray<T>> : std::true_type { }; - - template <typename T1, typename T2> - struct is_container<std::pair<T1, T2>> : std::true_type { }; - - template <typename ...Args> - struct is_container<std::tuple<Args...>> : std::true_type { }; - - - // Default delimiters - - template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; }; - template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" }; - template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" }; - - - // Delimiters for (multi)set and unordered_(multi)set - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<char> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<char> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - - // Delimiters for pair and tuple - - template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; }; - template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" }; - template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" }; - - template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; }; - template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" }; - template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" }; - - - // Type-erasing helper class for easy use of custom delimiters. - // Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar. - // Usage: "cout << pretty_print::custom_delims<MyDelims>(x)". - - struct custom_delims_base - { - virtual ~custom_delims_base() { } - virtual std::ostream & stream(::std::ostream &) = 0; - virtual std::wostream & stream(::std::wostream &) = 0; - }; - - template <typename T, typename Delims> - struct custom_delims_wrapper : custom_delims_base - { - custom_delims_wrapper(const T & t_) : t(t_) { } - - std::ostream & stream(std::ostream & s) - { - return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t); - } - - std::wostream & stream(std::wostream & s) - { - return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t); - } - - private: - const T & t; - }; - - template <typename Delims> - struct custom_delims - { - template <typename Container> - custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { } - - std::unique_ptr<custom_delims_base> base; - }; - - template <typename TChar, typename TCharTraits, typename Delims> - inline std::basic_ostream<TChar, TCharTraits> & operator<<(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p) - { - return p.base->stream(s); - } - - - // A wrapper for a C-style array given as pointer-plus-size. - // Usage: std::cout << pretty_print_array(arr, n) << std::endl; - - template<typename T> - 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; } - - private: - 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_print(m, 4) << std::endl; (Prints bucket 5 of container m.) - - template <typename T> - struct bucket_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 end() const - { - return m_map.cend(n); - } - - bucket_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { } - - private: - const T & m_map; - const size_type n; - }; - -} // namespace pretty_print - - -// Global accessor functions for the convenience wrappers - -template<typename T> -inline pretty_print::array_wrapper_n<T> pretty_print_array(const T * const a, size_t n) -{ - return pretty_print::array_wrapper_n<T>(a, n); -} - -template <typename T> pretty_print::bucket_print_wrapper<T> -bucket_print(const T & m, typename T::size_type n) -{ - return pretty_print::bucket_print_wrapper<T>(m, n); -} - - -// Main magic entry point: An overload snuck into namespace std. -// Can we do better? - -namespace std -{ - // Prints a container to the stream using default delimiters - - template<typename T, typename TChar, typename TCharTraits> - inline typename enable_if< ::pretty_print::is_container<T>::value, - basic_ostream<TChar, TCharTraits> &>::type - operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container) - { - return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container); - } -} - - - -#endif // H_PRETTY_PRINT |