"mmdet3d/models/layers/norm.py" did not exist on "99db60dd4b474ee25660a7f24e9c27bcdbeb32a9"
prettyprint.h 15.7 KB
Newer Older
zhangwenwei's avatar
zhangwenwei committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//          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>

zhangwenwei's avatar
zhangwenwei committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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;
zhangwenwei's avatar
zhangwenwei committed
123
        }
zhangwenwei's avatar
zhangwenwei committed
124
      }
zhangwenwei's avatar
zhangwenwei committed
125
    }
zhangwenwei's avatar
zhangwenwei committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  };

  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;
}
zhangwenwei's avatar
zhangwenwei committed
222

zhangwenwei's avatar
zhangwenwei committed
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
// 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);
}
zhangwenwei's avatar
zhangwenwei committed
423

zhangwenwei's avatar
zhangwenwei committed
424
425
// A wrapper for a C-style array given as pointer-plus-size.
// Usage: std::cout << pretty_print_array(arr, n) << std::endl;
zhangwenwei's avatar
zhangwenwei committed
426

zhangwenwei's avatar
zhangwenwei committed
427
428
429
430
template <typename T>
struct array_wrapper_n {
  typedef const T *const_iterator;
  typedef T value_type;
zhangwenwei's avatar
zhangwenwei committed
431

zhangwenwei's avatar
zhangwenwei committed
432
433
434
  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; }
zhangwenwei's avatar
zhangwenwei committed
435

zhangwenwei's avatar
zhangwenwei committed
436
437
438
439
 private:
  const T *const _array;
  size_t _n;
};
zhangwenwei's avatar
zhangwenwei committed
440

zhangwenwei's avatar
zhangwenwei committed
441
442
443
// 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.)
zhangwenwei's avatar
zhangwenwei committed
444

zhangwenwei's avatar
zhangwenwei committed
445
446
447
448
template <typename T>
struct bucket_print_wrapper {
  typedef typename T::const_local_iterator const_iterator;
  typedef typename T::size_type size_type;
zhangwenwei's avatar
zhangwenwei committed
449

zhangwenwei's avatar
zhangwenwei committed
450
  const_iterator begin() const { return m_map.cbegin(n); }
zhangwenwei's avatar
zhangwenwei committed
451

zhangwenwei's avatar
zhangwenwei committed
452
  const_iterator end() const { return m_map.cend(n); }
zhangwenwei's avatar
zhangwenwei committed
453

zhangwenwei's avatar
zhangwenwei committed
454
  bucket_print_wrapper(const T &m, size_type bucket) : m_map(m), n(bucket) {}
zhangwenwei's avatar
zhangwenwei committed
455

zhangwenwei's avatar
zhangwenwei committed
456
457
458
459
 private:
  const T &m_map;
  const size_type n;
};
zhangwenwei's avatar
zhangwenwei committed
460

zhangwenwei's avatar
zhangwenwei committed
461
}  // namespace pretty_print
zhangwenwei's avatar
zhangwenwei committed
462
463
464

// Global accessor functions for the convenience wrappers

zhangwenwei's avatar
zhangwenwei committed
465
466
467
468
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);
zhangwenwei's avatar
zhangwenwei committed
469
470
}

zhangwenwei's avatar
zhangwenwei committed
471
472
473
474
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);
zhangwenwei's avatar
zhangwenwei committed
475
476
477
478
479
}

// Main magic entry point: An overload snuck into namespace std.
// Can we do better?

zhangwenwei's avatar
zhangwenwei committed
480
481
namespace std {
// Prints a container to the stream using default delimiters
zhangwenwei's avatar
zhangwenwei committed
482

zhangwenwei's avatar
zhangwenwei committed
483
484
485
486
487
488
489
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);
zhangwenwei's avatar
zhangwenwei committed
490
}
zhangwenwei's avatar
zhangwenwei committed
491
}  // namespace std
zhangwenwei's avatar
zhangwenwei committed
492

zhangwenwei's avatar
zhangwenwei committed
493
#endif  // H_PRETTY_PRINT