pupene  0.2.0
debug-pupper.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "null-pupper.h"
4 #include <iostream>
5 
6 /** \file
7  * Introspect objects as they reach puppers.
8  */
9 namespace pupene {
10  /**
11  * This pupper wraps another pupper, logging each call to
12  * Wrapped::begin(), Wrapped::pup() and wrapped::end(). If the
13  * wrapped pupper returns PupPolicy::consume_object for any
14  * object/member-of-object, the associated pup() functions will
15  * not be invoked.
16  *
17  * #### Example
18  *
19  * ```{.cpp}
20  * using pupene;
21  * using int_string_pair = std::pair<uint32_t, std::string>;
22  *
23  * std::vector<int_string_pair> pairs =
24  * {{1, "one"}, {2, "two"}, {4, "four"}};
25  *
26  * // alternative 1 - pups to std::cout
27  * auto pupper = debug_pupper();
28  * pup(pupper, pairs, {});
29  *
30  * // alternative 2 - save output to string
31  * std::string debug_str = to_debug(pairs);
32  * ```
33  *
34  * Annotated DebugPupper output:
35  *
36  * ```
37  * object() // begin Meta::Type::Object
38  * pup(size, 3) // pup
39  * array(data) // begin Meta::Type::Array
40  * object()
41  * pup(key, 1)
42  * pup(value, one)
43  * ~object()
44  * object()
45  * pup(key, 2)
46  * pup(value, two)
47  * ~object()
48  * object()
49  * pup(key, 4)
50  * pup(value, four)
51  * ~object()
52  * ~array(data) // end Meta::Type::Array
53  * ~object() // end Meta::Type::Object
54  * ```
55  *
56  * @see debug_pupper
57  * @see do_pup
58  * @tparam Wrapped
59  */
60  template<typename Wrapped>
61  class DebugPupper : public Pupper<DebugPupper<Wrapped>> {
62  public:
63  explicit DebugPupper(Wrapped& pupper,
64  std::ostream& out)
65  : wrapped(pupper), out(out) {}
66 
67  ~DebugPupper() override = default;
68 
69  template <typename T>
70  PupPolicy begin(T& value, const Meta& meta) {
71  out << indent()
72  << to_string(meta)
73  << "(" << meta.name << ")"
74  << std::endl;
75 
76  depth++;
77 
78  return wrapped.begin(value, meta);
79  }
80 
81  void end(const Meta& meta) {
82  depth--;
83 
84  out << indent()
85  << "~" << to_string(meta)
86  << "(" << meta.name << ")"
87  << std::endl;
88 
89  wrapped.end(meta);
90  }
91 
92  template<typename T>
93  void pup(T& value, const Meta& meta) {
94  out << indent() << "pup(" << meta.name;
95  wrapped.pup(value, meta);
96  if constexpr (is_puppable<T>()) {
97  out << ", " << value << ")" << std::endl;
98  } else {
99  out << ", " << "PUPPER" << ")" << std::endl;
100  }
101  }
102 
103  private:
104  Wrapped& wrapped;
105  std::ostream& out;
106  uint16_t depth = 0;
107 
108  std::string indent() {
109  return std::string(depth * 2ul, ' ');
110  }
111 
112  std::string to_string(const Meta& meta) const {
113  switch (meta.type) {
114  case Meta::Type::Array:
115  return "array";
116  case Meta::Type::Object:
117  return "object";
118  case Meta::Type::Value:
119  return "value";
120  }
121  }
122  };
123 }
This pupper wraps another pupper, logging each call to Wrapped::begin(), Wrapped::pup() and wrapped::...
Definition: debug-pupper.h:61
PupPolicy begin(T &value, const Meta &meta)
Definition: debug-pupper.h:70
Definition: debug.cpp:4
const char * name
The name typically matches the name of the represented field.
Definition: traits.h:18
Holds name and type of objects.
Definition: traits.h:7
~DebugPupper() override=default
const Type type
Definition: traits.h:19
void pup(T &value, const Meta &meta)
Definition: debug-pupper.h:93
PupPolicy
Controls an object&#39;s pup() behavior.
Definition: pupper.h:17
void end(const Meta &meta)
Definition: debug-pupper.h:81
DebugPupper(Wrapped &pupper, std::ostream &out)
Definition: debug-pupper.h:63
Base class for working with puppable types.
Definition: pupper.h:83