pupene  0.2.0
pupper.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "traits.h"
4 
5 /** \file
6  * Pupper base class.
7  */
8 namespace pupene {
9 
10  /**
11  * Controls an object's pup() behavior. It's possible
12  * for a Pupper to opt-out of invoking pup on its members.
13  *
14  * @see pupene::fns::begin
15  * @see pupene::fns::pup_object
16  */
17  enum class PupPolicy {
18  /** pup object using its component pup functions */
19  pup_object,
20 
21  /**
22  * Pupper deals with object as-is, no associated
23  * pup functions will be invoked.
24  */
26  };
27 
28  /**
29  * Base class for working with _puppable_ types. Puppers can conceptually
30  * be divided into serialization and utility-based.
31  *
32  * #### Serialization puppers
33  *
34  * `pupene` does not internally distinguish between serialization/deserialization;
35  * each target format is therefore implemented as a reader/writer pair:
36  * - [BinaryReader](@ref BinaryReader) and [BinaryWriter](@ref BinaryWriter)
37  * - JsonReader and JsonWriter
38  *
39  *
40  * #### Utility puppers
41  * Custom and utility-related puppers are usually singular:
42  * - DebugPupper: Wraps another Pupper and prints everything reaching it.
43  * - NullPupper: Does nothing. Can be combined with DebugPupper.
44  * - [EditorPupper](https://github.com/junkdog/pupene_example), auto-generates editor
45  * UI:s for objects, using [imgui](https://github.com/ocornut/imgui).
46  *
47  *
48  * #### Creating puppers: Minimal exemplar
49  *
50  * ```{.cpp}
51  * class MinimalPupper : public Pupper<MinimalPupper> {
52  * public:
53  *
54  * template<typename T>
55  * PupPolicy begin(T& value, const Meta& meta) {
56  * return PupPolicy::pup_object;
57  * }
58  *
59  * template<typename T>
60  * void pup(T& value, const Meta& meta) {
61  * // T is integer, floating point or std::string
62  * }
63  *
64  * void end(const Meta& meta) {}
65  * };
66  * ```
67  *
68  * When a pupper is better equipped to deal with an object as-is, without
69  * pupping its component parts, begin() can return PupPolicy::consume_object, e.g.
70  * by using a template specialization:
71  *
72  * ```{.cpp}
73  * template <>
74  * inline void MinimalPupper::begin(Color& value, const Meta& meta) {
75  * set_background(value);
76  * return PupPolicy::consume_object; // pup not invoked for members
77  * }
78  * ```
79  *
80  * @tparam Derived
81  */
82  template<typename Derived>
83  class Pupper {
84 
85  public:
86 
87  explicit Pupper() = default;
88  virtual ~Pupper() = default;
89 
90  template<typename T>
91  PupPolicy begin_impl(T& value, const Meta& meta) {
92  return static_cast<Derived*>(this)->begin(value, meta);
93  }
94 
95  template<typename T, typename = enable_if_puppable<T>>
96  void pup_impl(T& value, const Meta& meta) {
97  static_cast<Derived*>(this)->pup(value, meta);
98  }
99 
100  void end_impl(const Meta& meta) {
101  static_cast<Derived*>(this)->end(meta);
102  }
103  };
104 }
pup object using its component pup functions
Definition: debug.cpp:4
Holds name and type of objects.
Definition: traits.h:7
PupPolicy begin_impl(T &value, const Meta &meta)
Definition: pupper.h:91
Pupper deals with object as-is, no associated pup functions will be invoked.
Pupper()=default
void end_impl(const Meta &meta)
Definition: pupper.h:100
void pup_impl(T &value, const Meta &meta)
Definition: pupper.h:96
PupPolicy
Controls an object&#39;s pup() behavior.
Definition: pupper.h:17
virtual ~Pupper()=default
Base class for working with puppable types.
Definition: pupper.h:83