cphot 0.1
A C++ tool for computing photometry from spectra.
prettyprint.hpp
Go to the documentation of this file.
1 /**
2  * @brief A pretty printing library for C++ containers.
3  *
4  * Just add "#include "prettyprint.hpp" to your source file and make sure
5  * that prettyprint.hpp is findable.
6  *
7  * https://github.com/louisdx/cxx-prettyprint/blob/master/prettyprint.hpp
8  */
9 // Distributed under the Boost Software License, Version 1.0.
10 // (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // A pretty printing library for C++
14 //
15 // Usage:
16 // Include this header, and operator<< will "just work".
17 #ifndef H_PRETTY_PRINT
18 #define H_PRETTY_PRINT
19 
20 #include <cstddef>
21 #include <iterator>
22 #include <memory>
23 #include <ostream>
24 #include <set>
25 #include <tuple>
26 #include <type_traits>
27 #include <unordered_set>
28 #include <utility>
29 #include <valarray>
30 
31 namespace pretty_print
32 {
33  namespace detail
34  {
35  // SFINAE type trait to detect whether T::const_iterator exists.
36 
37  struct sfinae_base
38  {
39  using yes = char;
40  using no = yes[2];
41  };
42 
43  template <typename T>
45  {
46  private:
47  template <typename C> static yes & test(typename C::const_iterator*);
48  template <typename C> static no & test(...);
49  public:
50  static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
51  using type = T;
52  };
53 
54  template <typename T>
55  struct has_begin_end : private sfinae_base
56  {
57  private:
58  template <typename C>
59  static yes & f(typename std::enable_if<
60  std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)),
61  typename C::const_iterator(C::*)() const>::value>::type *);
62 
63  template <typename C> static no & f(...);
64 
65  template <typename C>
66  static yes & g(typename std::enable_if<
67  std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)),
68  typename C::const_iterator(C::*)() const>::value, void>::type*);
69 
70  template <typename C> static no & g(...);
71 
72  public:
73  static bool const beg_value = sizeof(f<T>(nullptr)) == sizeof(yes);
74  static bool const end_value = sizeof(g<T>(nullptr)) == sizeof(yes);
75  };
76 
77  } // namespace detail
78 
79 
80  // Holds the delimiter values for a specific character type
81 
82  template <typename TChar>
84  {
85  using char_type = TChar;
86  const char_type * prefix;
88  const char_type * postfix;
89  };
90 
91 
92  // Defines the delimiter values for a specific container and character type
93 
94  template <typename T, typename TChar>
95  struct delimiters
96  {
98  static const type values;
99  };
100 
101 
102  // Functor to print containers. You can use this directly if you want
103  // to specificy a non-default delimiters type. The printing logic can
104  // be customized by specializing the nested template.
105 
106  template <typename T,
107  typename TChar = char,
108  typename TCharTraits = ::std::char_traits<TChar>,
109  typename TDelimiters = delimiters<T, TChar>>
111  {
112  using delimiters_type = TDelimiters;
113  using ostream_type = std::basic_ostream<TChar, TCharTraits>;
114 
115  template <typename U>
116  struct printer
117  {
118  static void print_body(const U & c, ostream_type & stream)
119  {
120  using std::begin;
121  using std::end;
122 
123  auto it = begin(c);
124  const auto the_end = end(c);
125 
126  if (it != the_end)
127  {
128  for ( ; ; )
129  {
130  stream << *it;
131 
132  if (++it == the_end) break;
133 
134  if (delimiters_type::values.delimiter != NULL)
135  stream << delimiters_type::values.delimiter;
136  }
137  }
138  }
139  };
140 
141  print_container_helper(const T & container)
142  : container_(container)
143  { }
144 
145  inline void operator()(ostream_type & stream) const
146  {
147  if (delimiters_type::values.prefix != NULL)
148  stream << delimiters_type::values.prefix;
149 
150  printer<T>::print_body(container_, stream);
151 
152  if (delimiters_type::values.postfix != NULL)
153  stream << delimiters_type::values.postfix;
154  }
155 
156  private:
157  const T & container_;
158  };
159 
160  // Specialization for pairs
161 
162  template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
163  template <typename T1, typename T2>
164  struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>>
165  {
167 
168  static void print_body(const std::pair<T1, T2> & c, ostream_type & stream)
169  {
170  stream << c.first;
172  stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
173  stream << c.second;
174  }
175  };
176 
177  // Specialization for tuples
178 
179  template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
180  template <typename ...Args>
181  struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>>
182  {
184  using element_type = std::tuple<Args...>;
185 
186  template <std::size_t I> struct Int { };
187 
188  static void print_body(const element_type & c, ostream_type & stream)
189  {
190  tuple_print(c, stream, Int<0>());
191  }
192 
193  static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>)
194  {
195  }
196 
197  static void tuple_print(const element_type & c, ostream_type & stream,
198  typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type)
199  {
200  stream << std::get<0>(c);
201  tuple_print(c, stream, Int<1>());
202  }
203 
204  template <std::size_t N>
205  static void tuple_print(const element_type & c, ostream_type & stream, Int<N>)
206  {
208  stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
209 
210  stream << std::get<N>(c);
211 
212  tuple_print(c, stream, Int<N + 1>());
213  }
214  };
215 
216  // Prints a print_container_helper to the specified stream.
217 
218  template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
219  inline std::basic_ostream<TChar, TCharTraits> & operator<<(
220  std::basic_ostream<TChar, TCharTraits> & stream,
222  {
223  helper(stream);
224  return stream;
225  }
226 
227 
228  // Basic is_container template; specialize to derive from std::true_type for all desired container types
229 
230  template <typename T>
231  struct is_container : public std::integral_constant<bool,
232  detail::has_const_iterator<T>::value &&
233  detail::has_begin_end<T>::beg_value &&
234  detail::has_begin_end<T>::end_value> { };
235 
236  template <typename T, std::size_t N>
237  struct is_container<T[N]> : std::true_type { };
238 
239  template <std::size_t N>
240  struct is_container<char[N]> : std::false_type { };
241 
242  template <typename T>
243  struct is_container<std::valarray<T>> : std::true_type { };
244 
245  template <typename T1, typename T2>
246  struct is_container<std::pair<T1, T2>> : std::true_type { };
247 
248  template <typename ...Args>
249  struct is_container<std::tuple<Args...>> : std::true_type { };
250 
251 
252  // Default delimiters
253 
254  template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; };
255  template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" };
256  template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; };
257  template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" };
258 
259 
260  // Delimiters for (multi)set and unordered_(multi)set
261 
262  template <typename T, typename TComp, typename TAllocator>
263  struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
264 
265  template <typename T, typename TComp, typename TAllocator>
266  const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
267 
268  template <typename T, typename TComp, typename TAllocator>
269  struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
270 
271  template <typename T, typename TComp, typename TAllocator>
272  const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
273 
274  template <typename T, typename TComp, typename TAllocator>
275  struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
276 
277  template <typename T, typename TComp, typename TAllocator>
278  const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
279 
280  template <typename T, typename TComp, typename TAllocator>
281  struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
282 
283  template <typename T, typename TComp, typename TAllocator>
284  const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
285 
286  template <typename T, typename THash, typename TEqual, typename TAllocator>
287  struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
288 
289  template <typename T, typename THash, typename TEqual, typename TAllocator>
291 
292  template <typename T, typename THash, typename TEqual, typename TAllocator>
293  struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
294 
295  template <typename T, typename THash, typename TEqual, typename TAllocator>
297 
298  template <typename T, typename THash, typename TEqual, typename TAllocator>
299  struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
300 
301  template <typename T, typename THash, typename TEqual, typename TAllocator>
303 
304  template <typename T, typename THash, typename TEqual, typename TAllocator>
305  struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
306 
307  template <typename T, typename THash, typename TEqual, typename TAllocator>
309 
310 
311  // Delimiters for pair and tuple
312 
313  template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; };
314  template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" };
315  template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; };
316  template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" };
317 
318  template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; };
319  template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" };
320  template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; };
321  template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" };
322 
323 
324  // Type-erasing helper class for easy use of custom delimiters.
325  // Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar.
326  // Usage: "cout << pretty_print::custom_delims<MyDelims>(x)".
327 
329  {
330  virtual ~custom_delims_base() { }
331  virtual std::ostream & stream(::std::ostream &) = 0;
332  virtual std::wostream & stream(::std::wostream &) = 0;
333  };
334 
335  template <typename T, typename Delims>
337  {
338  custom_delims_wrapper(const T & t_) : t(t_) { }
339 
340  std::ostream & stream(std::ostream & s)
341  {
342  return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t);
343  }
344 
345  std::wostream & stream(std::wostream & s)
346  {
347  return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t);
348  }
349 
350  private:
351  const T & t;
352  };
353 
354  template <typename Delims>
356  {
357  template <typename Container>
358  custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { }
359 
360  std::unique_ptr<custom_delims_base> base;
361  };
362 
363  template <typename TChar, typename TCharTraits, typename Delims>
364  inline std::basic_ostream<TChar, TCharTraits> & operator<<(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p)
365  {
366  return p.base->stream(s);
367  }
368 
369 
370  // A wrapper for a C-style array given as pointer-plus-size.
371  // Usage: std::cout << pretty_print_array(arr, n) << std::endl;
372 
373  template<typename T>
375  {
376  typedef const T * const_iterator;
377  typedef T value_type;
378 
379  array_wrapper_n(const T * const a, size_t n) : _array(a), _n(n) { }
380  inline const_iterator begin() const { return _array; }
381  inline const_iterator end() const { return _array + _n; }
382 
383  private:
384  const T * const _array;
385  size_t _n;
386  };
387 
388 
389  // A wrapper for hash-table based containers that offer local iterators to each bucket.
390  // Usage: std::cout << bucket_print(m, 4) << std::endl; (Prints bucket 5 of container m.)
391 
392  template <typename T>
394  {
395  typedef typename T::const_local_iterator const_iterator;
396  typedef typename T::size_type size_type;
397 
399  {
400  return m_map.cbegin(n);
401  }
402 
404  {
405  return m_map.cend(n);
406  }
407 
408  bucket_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { }
409 
410  private:
411  const T & m_map;
412  const size_type n;
413  };
414 
415 } // namespace pretty_print
416 
417 
418 // Global accessor functions for the convenience wrappers
419 
420 template<typename T>
421 inline pretty_print::array_wrapper_n<T> pretty_print_array(const T * const a, size_t n)
422 {
424 }
425 
426 template <typename T> pretty_print::bucket_print_wrapper<T>
427 bucket_print(const T & m, typename T::size_type n)
428 {
430 }
431 
432 
433 // Main magic entry point: An overload snuck into namespace std.
434 // Can we do better?
435 
436 namespace std
437 {
438  // Prints a container to the stream using default delimiters
439 
440  template<typename T, typename TChar, typename TCharTraits>
442  basic_ostream<TChar, TCharTraits> &>::type
443  operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container)
444  {
445  return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container);
446  }
447 }
448 
449 
450 
451 #endif // H_PRETTY_PRINT
pretty_print::delimiters< ::std::multiset< T, TComp, TAllocator >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:281
pretty_print::custom_delims_wrapper
Definition: prettyprint.hpp:336
pretty_print::custom_delims::base
std::unique_ptr< custom_delims_base > base
Definition: prettyprint.hpp:360
pretty_print::delimiters< std::tuple< Args... >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:318
pretty_print::custom_delims_base::~custom_delims_base
virtual ~custom_delims_base()
Definition: prettyprint.hpp:330
pretty_print::print_container_helper::printer::print_body
static void print_body(const U &c, ostream_type &stream)
Definition: prettyprint.hpp:118
pretty_print::detail::sfinae_base::yes
char yes
Definition: prettyprint.hpp:39
pretty_print::delimiters< ::std::multiset< T, TComp, TAllocator >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:275
pretty_print::delimiters_values::prefix
const char_type * prefix
Definition: prettyprint.hpp:86
pretty_print::array_wrapper_n::begin
const_iterator begin() const
Definition: prettyprint.hpp:380
pretty_print::custom_delims_wrapper::stream
std::ostream & stream(std::ostream &s)
Definition: prettyprint.hpp:340
pretty_print::print_container_helper::printer< std::pair< T1, T2 > >::ostream_type
typename print_container_helper< T, TChar, TCharTraits, TDelimiters >::ostream_type ostream_type
Definition: prettyprint.hpp:166
pretty_print::custom_delims_wrapper::stream
std::wostream & stream(std::wostream &s)
Definition: prettyprint.hpp:345
pretty_print::bucket_print_wrapper::end
const_iterator end() const
Definition: prettyprint.hpp:403
pretty_print::delimiters_values::postfix
const char_type * postfix
Definition: prettyprint.hpp:88
pretty_print::delimiters< ::std::unordered_set< T, THash, TEqual, TAllocator >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:293
pretty_print::print_container_helper::printer< std::tuple< Args... > >::ostream_type
typename print_container_helper< T, TChar, TCharTraits, TDelimiters >::ostream_type ostream_type
Definition: prettyprint.hpp:183
pretty_print::delimiters< T, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:256
pretty_print::detail::has_const_iterator::value
static const bool value
Definition: prettyprint.hpp:50
pretty_print::print_container_helper::delimiters_type
TDelimiters delimiters_type
Definition: prettyprint.hpp:112
pretty_print::custom_delims
Definition: prettyprint.hpp:355
pretty_print::print_container_helper::printer< std::tuple< Args... > >::element_type
std::tuple< Args... > element_type
Definition: prettyprint.hpp:184
pretty_print::print_container_helper::printer< std::pair< T1, T2 > >::print_body
static void print_body(const std::pair< T1, T2 > &c, ostream_type &stream)
Definition: prettyprint.hpp:168
pretty_print::custom_delims_wrapper::custom_delims_wrapper
custom_delims_wrapper(const T &t_)
Definition: prettyprint.hpp:338
pretty_print::bucket_print_wrapper::const_iterator
T::const_local_iterator const_iterator
Definition: prettyprint.hpp:395
pretty_print::operator<<
std::basic_ostream< TChar, TCharTraits > & operator<<(std::basic_ostream< TChar, TCharTraits > &stream, const print_container_helper< T, TChar, TCharTraits, TDelimiters > &helper)
Definition: prettyprint.hpp:219
pretty_print::detail::has_begin_end::beg_value
static const bool beg_value
Definition: prettyprint.hpp:73
pretty_print
A pretty printing library for C++ containers.
Definition: prettyprint.hpp:31
pretty_print::delimiters_values
Definition: prettyprint.hpp:83
pretty_print::array_wrapper_n
Definition: prettyprint.hpp:374
pretty_print::detail::sfinae_base::no
yes[2] no
Definition: prettyprint.hpp:40
pretty_print::delimiters< std::pair< T1, T2 >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:313
pretty_print::delimiters_values::delimiter
const char_type * delimiter
Definition: prettyprint.hpp:87
pretty_print::delimiters< ::std::set< T, TComp, TAllocator >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:263
pretty_print::delimiters
Definition: prettyprint.hpp:95
pretty_print::delimiters::values
static const type values
Definition: prettyprint.hpp:98
bucket_print
pretty_print::bucket_print_wrapper< T > bucket_print(const T &m, typename T::size_type n)
Definition: prettyprint.hpp:427
pretty_print::detail::has_const_iterator::type
T type
Definition: prettyprint.hpp:51
pretty_print::array_wrapper_n::end
const_iterator end() const
Definition: prettyprint.hpp:381
a
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1121
pretty_print::detail::sfinae_base
Definition: prettyprint.hpp:37
c
constexpr QSpeed c
Definition: rquantities.hpp:351
pretty_print::print_container_helper::printer< std::tuple< Args... > >::tuple_print
static void tuple_print(const element_type &c, ostream_type &stream, Int< N >)
Definition: prettyprint.hpp:205
pretty_print::custom_delims_base::stream
virtual std::ostream & stream(::std::ostream &)=0
pretty_print::is_container
Definition: prettyprint.hpp:231
pretty_print::detail::has_begin_end
Definition: prettyprint.hpp:55
pretty_print::print_container_helper::ostream_type
std::basic_ostream< TChar, TCharTraits > ostream_type
Definition: prettyprint.hpp:113
pretty_print::bucket_print_wrapper::size_type
T::size_type size_type
Definition: prettyprint.hpp:396
pretty_print::delimiters< ::std::unordered_multiset< T, THash, TEqual, TAllocator >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:305
pretty_print::delimiters_values::char_type
TChar char_type
Definition: prettyprint.hpp:85
pretty_print_array
pretty_print::array_wrapper_n< T > pretty_print_array(const T *const a, size_t n)
Definition: prettyprint.hpp:421
pretty_print::array_wrapper_n::value_type
T value_type
Definition: prettyprint.hpp:377
pretty_print::delimiters< T, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:254
pretty_print::print_container_helper::operator()
void operator()(ostream_type &stream) const
Definition: prettyprint.hpp:145
pretty_print::bucket_print_wrapper::bucket_print_wrapper
bucket_print_wrapper(const T &m, size_type bucket)
Definition: prettyprint.hpp:408
pretty_print::delimiters< ::std::tuple< Args... >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:320
pretty_print::detail::has_begin_end::end_value
static const bool end_value
Definition: prettyprint.hpp:74
pretty_print::bucket_print_wrapper::begin
const_iterator begin() const
Definition: prettyprint.hpp:398
pretty_print::delimiters< ::std::unordered_multiset< T, THash, TEqual, TAllocator >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:299
pretty_print::array_wrapper_n::array_wrapper_n
array_wrapper_n(const T *const a, size_t n)
Definition: prettyprint.hpp:379
pretty_print::delimiters< ::std::set< T, TComp, TAllocator >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:269
pretty_print::detail::has_const_iterator
Definition: prettyprint.hpp:44
pretty_print::bucket_print_wrapper
Definition: prettyprint.hpp:393
pretty_print::print_container_helper
Definition: prettyprint.hpp:110
pretty_print::print_container_helper::printer< std::tuple< Args... > >::tuple_print
static void tuple_print(const element_type &, ostream_type &, Int< sizeof...(Args)>)
Definition: prettyprint.hpp:193
pretty_print::print_container_helper::printer< std::tuple< Args... > >::print_body
static void print_body(const element_type &c, ostream_type &stream)
Definition: prettyprint.hpp:188
pretty_print::array_wrapper_n::const_iterator
const typedef T * const_iterator
Definition: prettyprint.hpp:376
pretty_print::custom_delims_base
Definition: prettyprint.hpp:328
pretty_print::delimiters< ::std::unordered_set< T, THash, TEqual, TAllocator >, char >::values
static const delimiters_values< char > values
Definition: prettyprint.hpp:287
value
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1222
pretty_print::print_container_helper::print_container_helper
print_container_helper(const T &container)
Definition: prettyprint.hpp:141
pretty_print::delimiters< ::std::pair< T1, T2 >, wchar_t >::values
static const delimiters_values< wchar_t > values
Definition: prettyprint.hpp:315
pretty_print::print_container_helper::printer< std::tuple< Args... > >::tuple_print
static void tuple_print(const element_type &c, ostream_type &stream, typename std::conditional< sizeof...(Args) !=0, Int< 0 >, std::nullptr_t >::type)
Definition: prettyprint.hpp:197
pretty_print::print_container_helper::printer
Definition: prettyprint.hpp:116
pretty_print::custom_delims::custom_delims
custom_delims(const Container &c)
Definition: prettyprint.hpp:358