BRE12
convert.h
1 #ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) || \
5  (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6  (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include <array>
11 #include <limits>
12 #include <list>
13 #include <map>
14 #include <sstream>
15 #include <vector>
16 
17 #include "yaml-cpp/binary.h"
18 #include "yaml-cpp/node/impl.h"
19 #include "yaml-cpp/node/iterator.h"
20 #include "yaml-cpp/node/node.h"
21 #include "yaml-cpp/node/type.h"
22 #include "yaml-cpp/null.h"
23 
24 namespace YAML {
25 class Binary;
26 struct _Null;
27 template <typename T>
28 struct convert;
29 } // namespace YAML
30 
31 namespace YAML {
32 namespace conversion {
33 inline bool IsInfinity(const std::string& input) {
34  return input == ".inf" || input == ".Inf" || input == ".INF" ||
35  input == "+.inf" || input == "+.Inf" || input == "+.INF";
36 }
37 
38 inline bool IsNegativeInfinity(const std::string& input) {
39  return input == "-.inf" || input == "-.Inf" || input == "-.INF";
40 }
41 
42 inline bool IsNaN(const std::string& input) {
43  return input == ".nan" || input == ".NaN" || input == ".NAN";
44 }
45 }
46 
47 // Node
48 template <>
49 struct convert<Node> {
50  static Node encode(const Node& rhs) { return rhs; }
51 
52  static bool decode(const Node& node, Node& rhs) {
53  rhs.reset(node);
54  return true;
55  }
56 };
57 
58 // std::string
59 template <>
60 struct convert<std::string> {
61  static Node encode(const std::string& rhs) { return Node(rhs); }
62 
63  static bool decode(const Node& node, std::string& rhs) {
64  if (!node.IsScalar())
65  return false;
66  rhs = node.Scalar();
67  return true;
68  }
69 };
70 
71 // C-strings can only be encoded
72 template <>
73 struct convert<const char*> {
74  static Node encode(const char*& rhs) { return Node(rhs); }
75 };
76 
77 template <std::size_t N>
78 struct convert<const char[N]> {
79  static Node encode(const char(&rhs)[N]) { return Node(rhs); }
80 };
81 
82 template <>
83 struct convert<_Null> {
84  static Node encode(const _Null& /* rhs */) { return Node(); }
85 
86  static bool decode(const Node& node, _Null& /* rhs */) {
87  return node.IsNull();
88  }
89 };
90 
91 #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
92  template <> \
93  struct convert<type> { \
94  static Node encode(const type& rhs) { \
95  std::stringstream stream; \
96  stream.precision(std::numeric_limits<type>::digits10 + 1); \
97  stream << rhs; \
98  return Node(stream.str()); \
99  } \
100  \
101  static bool decode(const Node& node, type& rhs) { \
102  if (node.Type() != NodeType::Scalar) \
103  return false; \
104  const std::string& input = node.Scalar(); \
105  std::stringstream stream(input); \
106  stream.unsetf(std::ios::dec); \
107  if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
108  return true; \
109  if (std::numeric_limits<type>::has_infinity) { \
110  if (conversion::IsInfinity(input)) { \
111  rhs = std::numeric_limits<type>::infinity(); \
112  return true; \
113  } else if (conversion::IsNegativeInfinity(input)) { \
114  rhs = negative_op std::numeric_limits<type>::infinity(); \
115  return true; \
116  } \
117  } \
118  \
119  if (std::numeric_limits<type>::has_quiet_NaN && \
120  conversion::IsNaN(input)) { \
121  rhs = std::numeric_limits<type>::quiet_NaN(); \
122  return true; \
123  } \
124  \
125  return false; \
126  } \
127  }
128 
129 #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
130  YAML_DEFINE_CONVERT_STREAMABLE(type, -)
131 
132 #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
133  YAML_DEFINE_CONVERT_STREAMABLE(type, +)
134 
135 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
136 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
137 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
138 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
139 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
140 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
141 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
142 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
143 
144 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
145 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char);
146 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
147 
148 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
149 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
150 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
151 
152 #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
153 #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
154 #undef YAML_DEFINE_CONVERT_STREAMABLE
155 
156 // bool
157 template <>
158 struct convert<bool> {
159  static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
160 
161  YAML_CPP_API static bool decode(const Node& node, bool& rhs);
162 };
163 
164 // std::map
165 template <typename K, typename V>
166 struct convert<std::map<K, V>> {
167  static Node encode(const std::map<K, V>& rhs) {
168  Node node(NodeType::Map);
169  for (typename std::map<K, V>::const_iterator it = rhs.begin();
170  it != rhs.end(); ++it)
171  node.force_insert(it->first, it->second);
172  return node;
173  }
174 
175  static bool decode(const Node& node, std::map<K, V>& rhs) {
176  if (!node.IsMap())
177  return false;
178 
179  rhs.clear();
180  for (const_iterator it = node.begin(); it != node.end(); ++it)
181 #if defined(__GNUC__) && __GNUC__ < 4
182  // workaround for GCC 3:
183  rhs[it->first.template as<K>()] = it->second.template as<V>();
184 #else
185  rhs[it->first.as<K>()] = it->second.as<V>();
186 #endif
187  return true;
188  }
189 };
190 
191 // std::vector
192 template <typename T>
193 struct convert<std::vector<T>> {
194  static Node encode(const std::vector<T>& rhs) {
195  Node node(NodeType::Sequence);
196  for (typename std::vector<T>::const_iterator it = rhs.begin();
197  it != rhs.end(); ++it)
198  node.push_back(*it);
199  return node;
200  }
201 
202  static bool decode(const Node& node, std::vector<T>& rhs) {
203  if (!node.IsSequence())
204  return false;
205 
206  rhs.clear();
207  for (const_iterator it = node.begin(); it != node.end(); ++it)
208 #if defined(__GNUC__) && __GNUC__ < 4
209  // workaround for GCC 3:
210  rhs.push_back(it->template as<T>());
211 #else
212  rhs.push_back(it->as<T>());
213 #endif
214  return true;
215  }
216 };
217 
218 // std::list
219 template <typename T>
220 struct convert<std::list<T>> {
221  static Node encode(const std::list<T>& rhs) {
222  Node node(NodeType::Sequence);
223  for (typename std::list<T>::const_iterator it = rhs.begin();
224  it != rhs.end(); ++it)
225  node.push_back(*it);
226  return node;
227  }
228 
229  static bool decode(const Node& node, std::list<T>& rhs) {
230  if (!node.IsSequence())
231  return false;
232 
233  rhs.clear();
234  for (const_iterator it = node.begin(); it != node.end(); ++it)
235 #if defined(__GNUC__) && __GNUC__ < 4
236  // workaround for GCC 3:
237  rhs.push_back(it->template as<T>());
238 #else
239  rhs.push_back(it->as<T>());
240 #endif
241  return true;
242  }
243 };
244 
245 // std::array
246 template <typename T, std::size_t N>
247 struct convert<std::array<T, N>> {
248  static Node encode(const std::array<T, N>& rhs) {
249  Node node(NodeType::Sequence);
250  for (const auto& element : rhs) {
251  node.push_back(element);
252  }
253  return node;
254  }
255 
256  static bool decode(const Node& node, std::array<T, N>& rhs) {
257  if (!isNodeValid(node)) {
258  return false;
259  }
260 
261  for (auto i = 0u; i < node.size(); ++i) {
262 #if defined(__GNUC__) && __GNUC__ < 4
263  // workaround for GCC 3:
264  rhs[i] = node[i].template as<T>();
265 #else
266  rhs[i] = node[i].as<T>();
267 #endif
268  }
269  return true;
270  }
271 
272  private:
273  static bool isNodeValid(const Node& node) {
274  return node.IsSequence() && node.size() == N;
275  }
276 };
277 
278 // std::pair
279 template <typename T, typename U>
280 struct convert<std::pair<T, U>> {
281  static Node encode(const std::pair<T, U>& rhs) {
282  Node node(NodeType::Sequence);
283  node.push_back(rhs.first);
284  node.push_back(rhs.second);
285  return node;
286  }
287 
288  static bool decode(const Node& node, std::pair<T, U>& rhs) {
289  if (!node.IsSequence())
290  return false;
291  if (node.size() != 2)
292  return false;
293 
294 #if defined(__GNUC__) && __GNUC__ < 4
295  // workaround for GCC 3:
296  rhs.first = node[0].template as<T>();
297 #else
298  rhs.first = node[0].as<T>();
299 #endif
300 #if defined(__GNUC__) && __GNUC__ < 4
301  // workaround for GCC 3:
302  rhs.second = node[1].template as<U>();
303 #else
304  rhs.second = node[1].as<U>();
305 #endif
306  return true;
307  }
308 };
309 
310 // binary
311 template <>
312 struct convert<Binary> {
313  static Node encode(const Binary& rhs) {
314  return Node(EncodeBase64(rhs.data(), rhs.size()));
315  }
316 
317  static bool decode(const Node& node, Binary& rhs) {
318  if (!node.IsScalar())
319  return false;
320 
321  std::vector<unsigned char> data = DecodeBase64(node.Scalar());
322  if (data.empty() && !node.Scalar().empty())
323  return false;
324 
325  rhs.swap(data);
326  return true;
327  }
328 };
329 }
330 
331 #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: binary.h:20
Definition: iterator.h:21
Definition: _tbb_windef.h:37
Definition: convert.h:28
Definition: null.h:16
Definition: DrawableObjectLoader.h:10
Definition: node.h:29