SUNphi  1.0
Sequence.hpp
Go to the documentation of this file.
1 #ifndef _SERIALIZE_SEQUENCE_HPP
2 #define _SERIALIZE_SEQUENCE_HPP
3 
4 /// \file serialize/Sequence.hpp
5 ///
6 /// \brief Container mapping a sequence
7 ///
8 /// A Serializable container contains a begin, end and size methods,
9 /// as an STL container
10 
11 #include <cstddef>
12 
13 #include <metaprogramming/TypeTraits.hpp>
14 #include <serialize/Binarize.hpp>
15 #include <serialize/Default.hpp>
16 #include <tuple/TupleElements.hpp>
17 
18 namespace SUNphi
19 {
20  /// Class providing sequence node for the serializer
21  ///
22  /// Provides name and default value
23  template <typename S>
25  : public S
27  {
28 
29  /// Fundamental type
30  using T=
31  decltype((*static_cast<S*>(nullptr))[0]);
32 
33  public:
34 
35  /// Name used to refer
36  const char* name;
37 
38  /// Default value
39  const S def;
40 
41  /// Returns whether the container is default
42  bool isDefault()
43  const
44  {
45  return
46  static_cast<const S&>(*this)==def;
47  }
48 
49  /// Put to default value
50  void putToDefault()
51  {
52  static_cast<S>(*this)=
53  def;
54  }
55 
56  /// Creates a serializable vector with name
57  template <typename...TDef>
58  SerializableSequence(const char* name, ///< Name of the sequence
59  TDef&&...def) ///< Initializer
60  : S(def...)
61  , name(name)
62  , def(def...)
63  {
64  }
65 
66  /// Access the value
67  const S& operator()()
68  const
69  {
70  return
71  static_cast<const S&>(*this);
72  }
73 
75 
76  /// Returns a YAML node after serializing to it
77  YAML::Node serialize(YAML::Node& node,
78  const bool& onlyNonDefault=false)
79  const
80  {
81  if(not (onlyNonDefault and isDefault()))
82  {
83  /// Create the subnode
84  YAML::Node subNode=
85  node[name];
86 
87  if constexpr(isTupleLike<S>)
88  forEach(static_cast<const S&>(*this),[&](auto&& s)
89  {
90  if constexpr(hasMember_serialize<S>)
91  subNode.push_back(s.serialize(onlyNonDefault));
92  else
93  subNode.push_back(s);
94  });
95  else
96  for(auto& s: static_cast<const S&>(*this))
97  {
98  if constexpr(hasMember_serialize<decltype(s)>)
99  subNode.push_back(s.serialize(onlyNonDefault));
100  else
101  subNode.push_back(s);
102  }
103  }
104 
105  return
106  node;
107  }
108 
109  /// Returns a YAML node
110  YAML::Node serialize(const bool& onlyNonDefault=false)
111  const
112  {
113  /// Returned value
114  YAML::Node node;
115 
116  return
117  serialize(node,onlyNonDefault);
118  }
119 
120  /// Convert from a YAML node
121  bool deSerialize(const YAML::Node& node) ///< Node from which to convert
122  {
123  if(not node[name])
124  this->putToDefault();
125  else
126  (*this)()=
127  node[name].template as<S>();
128 
129  return
130  true;
131  }
132 
133  /// Copy assignment operator
135  {
136  (*this)()=
137  (oth)();
138 
139  return
140  *this;
141  }
142  };
143 
144  /// Create a serializable sequence with a given tag
145 #define SERIALIZABLE_SEQUENCE_WITH_TAG(CONTAINER,
146  NAME,
147  TAG,
148  ...)
149  SerializableSequence<CONTAINER>
150  NAME{TAG,__VA_ARGS__}
151 
152  /// Create a serializable sequence
153 #define SERIALIZABLE_SEQUENCE(CONTAINER,
154  NAME,
155  ...)
156  SERIALIZABLE_SEQUENCE_WITH_TAG(CONTAINER,NAME,#NAME,__VA_ARGS__)
157 
158  /// Create a serializable vector with a given tag
159 #define SERIALIZABLE_VECTOR_WITH_TAG(TYPE,
160  NAME,
161  TAG,
162  ...)
163  SERIALIZABLE_SEQUENCE_WITH_TAG(std::vector<TYPE>,NAME,TAG,__VA_ARGS__)
164 
165  /// Create a serializable vector
166 #define SERIALIZABLE_VECTOR(TYPE,
167  NAME,
168  ...)
169  SERIALIZABLE_VECTOR_WITH_TAG(TYPE,NAME,#NAME,__VA_ARGS__)
170 
171  /// Create a serializable pair with a given tag
172 #define SERIALIZABLE_PAIR_WITH_TAG(TYPE1,
173  TYPE2,
174  NAME,
175  TAG,
176  ...)
177  SerializableSequence<std::pair<TYPE1,TYPE2>>
178  NAME{TAG,__VA_ARGS__}
179 
180  /// Create a serializable pair
181 #define SERIALIZABLE_PAIR(TYPE1,
182  TYPE2,
183  NAME,
184  ...)
185  SERIALIZABLE_PAIR_WITH_TAG(TYPE1,TYPE2,NAME,#NAME,__VA_ARGS__)
186 
188 }
189 
190 #endif
YAML::Node serialize(YAML::Node &node, const bool &onlyNonDefault=false) const
Returns a YAML node after serializing to it.
Definition: Sequence.hpp:77
Add binarizable functionality via CRTP.
Definition: Binarize.hpp:213
const char * name
Name used to refer.
Definition: Sequence.hpp:36
bool deSerialize(const YAML::Node &node)
Convert from a YAML node.
Definition: Sequence.hpp:121
YAML::Node serialize(const bool &onlyNonDefault=false) const
Returns a YAML node.
Definition: Sequence.hpp:110
SerializableSequence(const char *name, TDef &&...def)
Creates a serializable vector with name.
Definition: Sequence.hpp:58
const S & operator()() const
Access the value.
Definition: Sequence.hpp:67
void putToDefault()
Put to default value.
Definition: Sequence.hpp:50
#define DEFINE_IS_THE_TEMPLATED_CLASS(CLASS)
Provides a check returning whether the class is of a given kind.
Definition: TypeTraits.hpp:716
#define SERIALIZABLE_SEQUENCE_WITH_TAG(CONTAINER,NAME,TAG,...)
Create a serializable sequence with a given tag.
Definition: Sequence.hpp:145
SerializableSequence & operator=(const SerializableSequence &oth)
Copy assignment operator.
Definition: Sequence.hpp:134
#define SERIALIZABLE_PAIR_WITH_TAG(TYPE1,TYPE2,NAME,TAG,...)
Create a serializable pair with a given tag.
Definition: Sequence.hpp:172
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
#define PROVIDE_ALSO_NON_CONST_METHOD(NAME)
Definition: TypeTraits.hpp:376
static bool decode(const Node &node, T &rhs)
Decode from a node.
Definition: Base.hpp:86
decltype(auto) operator()(Ts &&...ts)
Definition: Sequence.hpp:74
#define SERIALIZABLE_VECTOR_WITH_TAG(TYPE,NAME,TAG,...)
Create a serializable vector with a given tag.
Definition: Sequence.hpp:159
const S def
Default value.
Definition: Sequence.hpp:39
bool isDefault() const
Returns whether the container is default.
Definition: Sequence.hpp:42