/src/trafficserver/lib/yamlcpp/include/yaml-cpp/node/convert.h
Line | Count | Source |
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 <cmath> |
12 | | #include <limits> |
13 | | #include <list> |
14 | | #include <map> |
15 | | #include <unordered_map> |
16 | | #include <sstream> |
17 | | #include <type_traits> |
18 | | #include <valarray> |
19 | | #include <vector> |
20 | | |
21 | | #if __cplusplus >= 201703L |
22 | | #include <string_view> |
23 | | #endif |
24 | | |
25 | | #include "yaml-cpp/binary.h" |
26 | | #include "yaml-cpp/node/impl.h" |
27 | | #include "yaml-cpp/node/iterator.h" |
28 | | #include "yaml-cpp/node/node.h" |
29 | | #include "yaml-cpp/node/type.h" |
30 | | #include "yaml-cpp/null.h" |
31 | | |
32 | | |
33 | | namespace YAML { |
34 | | class Binary; |
35 | | struct _Null; |
36 | | template <typename T> |
37 | | struct convert; |
38 | | } // namespace YAML |
39 | | |
40 | | namespace YAML { |
41 | | namespace conversion { |
42 | 0 | inline bool IsInfinity(const std::string& input) { |
43 | 0 | return input == ".inf" || input == ".Inf" || input == ".INF" || |
44 | 0 | input == "+.inf" || input == "+.Inf" || input == "+.INF"; |
45 | 0 | } |
46 | | |
47 | 0 | inline bool IsNegativeInfinity(const std::string& input) { |
48 | 0 | return input == "-.inf" || input == "-.Inf" || input == "-.INF"; |
49 | 0 | } |
50 | | |
51 | 0 | inline bool IsNaN(const std::string& input) { |
52 | 0 | return input == ".nan" || input == ".NaN" || input == ".NAN"; |
53 | 0 | } |
54 | | } |
55 | | |
56 | | // Node |
57 | | template <> |
58 | | struct convert<Node> { |
59 | 0 | static Node encode(const Node& rhs) { return rhs; } |
60 | | |
61 | 0 | static bool decode(const Node& node, Node& rhs) { |
62 | 0 | rhs.reset(node); |
63 | 0 | return true; |
64 | 0 | } |
65 | | }; |
66 | | |
67 | | // std::string |
68 | | template <> |
69 | | struct convert<std::string> { |
70 | 0 | static Node encode(const std::string& rhs) { return Node(rhs); } |
71 | | |
72 | 19.3k | static bool decode(const Node& node, std::string& rhs) { |
73 | 19.3k | if (!node.IsScalar()) |
74 | 5.41k | return false; |
75 | 13.9k | rhs = node.Scalar(); |
76 | 13.9k | return true; |
77 | 19.3k | } |
78 | | }; |
79 | | |
80 | | // C-strings can only be encoded |
81 | | template <> |
82 | | struct convert<const char*> { |
83 | 0 | static Node encode(const char* rhs) { return Node(rhs); } |
84 | | }; |
85 | | |
86 | | template <> |
87 | | struct convert<char*> { |
88 | 0 | static Node encode(const char* rhs) { return Node(rhs); } |
89 | | }; |
90 | | |
91 | | template <std::size_t N> |
92 | | struct convert<char[N]> { |
93 | | static Node encode(const char* rhs) { return Node(rhs); } |
94 | | }; |
95 | | |
96 | | #if __cplusplus >= 201703L |
97 | | template <> |
98 | | struct convert<std::string_view> { |
99 | 0 | static Node encode(std::string_view rhs) { return Node(std::string(rhs)); } |
100 | | |
101 | 0 | static bool decode(const Node& node, std::string_view& rhs) { |
102 | 0 | if (!node.IsScalar()) |
103 | 0 | return false; |
104 | 0 | rhs = node.Scalar(); |
105 | 0 | return true; |
106 | 0 | } |
107 | | }; |
108 | | #endif |
109 | | |
110 | | template <> |
111 | | struct convert<_Null> { |
112 | 0 | static Node encode(const _Null& /* rhs */) { return Node(); } |
113 | | |
114 | 0 | static bool decode(const Node& node, _Null& /* rhs */) { |
115 | 0 | return node.IsNull(); |
116 | 0 | } |
117 | | }; |
118 | | |
119 | | namespace conversion { |
120 | | template <typename T> |
121 | | typename std::enable_if< std::is_floating_point<T>::value, void>::type |
122 | 0 | inner_encode(const T& rhs, std::stringstream& stream){ |
123 | 0 | if (std::isnan(rhs)) { |
124 | 0 | stream << ".nan"; |
125 | 0 | } else if (std::isinf(rhs)) { |
126 | 0 | if (std::signbit(rhs)) { |
127 | 0 | stream << "-.inf"; |
128 | 0 | } else { |
129 | 0 | stream << ".inf"; |
130 | 0 | } |
131 | 0 | } else { |
132 | 0 | stream << rhs; |
133 | 0 | } |
134 | 0 | } Unexecuted instantiation: std::__1::enable_if<is_floating_point<float>::value, void>::type YAML::conversion::inner_encode<float>(float const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<is_floating_point<double>::value, void>::type YAML::conversion::inner_encode<double>(double const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<is_floating_point<long double>::value, void>::type YAML::conversion::inner_encode<long double>(long double const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) |
135 | | |
136 | | template <typename T> |
137 | | typename std::enable_if<!std::is_floating_point<T>::value, void>::type |
138 | 0 | inner_encode(const T& rhs, std::stringstream& stream){ |
139 | 0 | stream << rhs; |
140 | 0 | } Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<int>::value, void>::type YAML::conversion::inner_encode<int>(int const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<short>::value, void>::type YAML::conversion::inner_encode<short>(short const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<long>::value, void>::type YAML::conversion::inner_encode<long>(long const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<long long>::value, void>::type YAML::conversion::inner_encode<long long>(long long const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<unsigned int>::value, void>::type YAML::conversion::inner_encode<unsigned int>(unsigned int const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<unsigned short>::value, void>::type YAML::conversion::inner_encode<unsigned short>(unsigned short const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<unsigned long>::value, void>::type YAML::conversion::inner_encode<unsigned long>(unsigned long const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<unsigned long long>::value, void>::type YAML::conversion::inner_encode<unsigned long long>(unsigned long long const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<char>::value, void>::type YAML::conversion::inner_encode<char>(char const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<signed char>::value, void>::type YAML::conversion::inner_encode<signed char>(signed char const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) Unexecuted instantiation: std::__1::enable_if<!std::is_floating_point<unsigned char>::value, void>::type YAML::conversion::inner_encode<unsigned char>(unsigned char const&, std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) |
141 | | |
142 | | template <typename T> |
143 | | typename std::enable_if<(std::is_same<T, unsigned char>::value || |
144 | | std::is_same<T, signed char>::value), bool>::type |
145 | 0 | ConvertStreamTo(std::stringstream& stream, T& rhs) { |
146 | 0 | int num; |
147 | 0 | if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { |
148 | 0 | if (num >= (std::numeric_limits<T>::min)() && |
149 | 0 | num <= (std::numeric_limits<T>::max)()) { |
150 | 0 | rhs = static_cast<T>(num); |
151 | 0 | return true; |
152 | 0 | } |
153 | 0 | } |
154 | 0 | return false; |
155 | 0 | } Unexecuted instantiation: std::__1::enable_if<std::is_same<signed char, unsigned char>::value||std::is_same<signed char, signed char>::value, bool>::type YAML::conversion::ConvertStreamTo<signed char>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, signed char&) Unexecuted instantiation: std::__1::enable_if<std::is_same<unsigned char, unsigned char>::value||std::is_same<unsigned char, signed char>::value, bool>::type YAML::conversion::ConvertStreamTo<unsigned char>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned char&) |
156 | | |
157 | | template <typename T> |
158 | | typename std::enable_if<!(std::is_same<T, unsigned char>::value || |
159 | | std::is_same<T, signed char>::value), bool>::type |
160 | 0 | ConvertStreamTo(std::stringstream& stream, T& rhs) { |
161 | 0 | if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { |
162 | 0 | return true; |
163 | 0 | } |
164 | 0 | return false; |
165 | 0 | } Unexecuted instantiation: std::__1::enable_if<!(std::is_same<int, unsigned char>::value||std::is_same<int, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<int>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<short, unsigned char>::value||std::is_same<short, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<short>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, short&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<long, unsigned char>::value||std::is_same<long, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<long>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, long&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<long long, unsigned char>::value||std::is_same<long long, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<long long>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, long long&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<unsigned int, unsigned char>::value||std::is_same<unsigned int, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<unsigned int>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<unsigned short, unsigned char>::value||std::is_same<unsigned short, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<unsigned short>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned short&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<unsigned long, unsigned char>::value||std::is_same<unsigned long, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<unsigned long>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<unsigned long long, unsigned char>::value||std::is_same<unsigned long long, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<unsigned long long>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long long&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<char, unsigned char>::value||std::is_same<char, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<char>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, char&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<float, unsigned char>::value||std::is_same<float, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<float>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, float&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<double, unsigned char>::value||std::is_same<double, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<double>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, double&) Unexecuted instantiation: std::__1::enable_if<!(std::is_same<long double, unsigned char>::value||std::is_same<long double, signed char>::value), bool>::type YAML::conversion::ConvertStreamTo<long double>(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, long double&) |
166 | | } |
167 | | |
168 | | #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ |
169 | | template <> \ |
170 | | struct convert<type> { \ |
171 | | \ |
172 | 0 | static Node encode(const type& rhs) { \ |
173 | 0 | std::stringstream stream; \ |
174 | 0 | stream.precision(std::numeric_limits<type>::max_digits10); \ |
175 | 0 | conversion::inner_encode(rhs, stream); \ |
176 | 0 | return Node(stream.str()); \ |
177 | 0 | } \ Unexecuted instantiation: YAML::convert<int>::encode(int const&) Unexecuted instantiation: YAML::convert<short>::encode(short const&) Unexecuted instantiation: YAML::convert<long>::encode(long const&) Unexecuted instantiation: YAML::convert<long long>::encode(long long const&) Unexecuted instantiation: YAML::convert<unsigned int>::encode(unsigned int const&) Unexecuted instantiation: YAML::convert<unsigned short>::encode(unsigned short const&) Unexecuted instantiation: YAML::convert<unsigned long>::encode(unsigned long const&) Unexecuted instantiation: YAML::convert<unsigned long long>::encode(unsigned long long const&) Unexecuted instantiation: YAML::convert<char>::encode(char const&) Unexecuted instantiation: YAML::convert<signed char>::encode(signed char const&) Unexecuted instantiation: YAML::convert<unsigned char>::encode(unsigned char const&) Unexecuted instantiation: YAML::convert<float>::encode(float const&) Unexecuted instantiation: YAML::convert<double>::encode(double const&) Unexecuted instantiation: YAML::convert<long double>::encode(long double const&) |
178 | | \ |
179 | 0 | static bool decode(const Node& node, type& rhs) { \ |
180 | 0 | if (node.Type() != NodeType::Scalar) { \ |
181 | 0 | return false; \ |
182 | 0 | } \ |
183 | 0 | const std::string& input = node.Scalar(); \ |
184 | 0 | std::stringstream stream(input); \ |
185 | 0 | stream.unsetf(std::ios::dec); \ |
186 | 0 | if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \ |
187 | 0 | return false; \ |
188 | 0 | } \ |
189 | 0 | if (conversion::ConvertStreamTo(stream, rhs)) { \ |
190 | 0 | return true; \ |
191 | 0 | } \ |
192 | 0 | if (std::numeric_limits<type>::has_infinity) { \ |
193 | 0 | if (conversion::IsInfinity(input)) { \ |
194 | 0 | rhs = std::numeric_limits<type>::infinity(); \ |
195 | 0 | return true; \ |
196 | 0 | } else if (conversion::IsNegativeInfinity(input)) { \ |
197 | 0 | rhs = negative_op std::numeric_limits<type>::infinity(); \ |
198 | 0 | return true; \ |
199 | 0 | } \ |
200 | 0 | } \ |
201 | 0 | \ |
202 | 0 | if (std::numeric_limits<type>::has_quiet_NaN) { \ |
203 | 0 | if (conversion::IsNaN(input)) { \ |
204 | 0 | rhs = std::numeric_limits<type>::quiet_NaN(); \ |
205 | 0 | return true; \ |
206 | 0 | } \ |
207 | 0 | } \ |
208 | 0 | \ |
209 | 0 | return false; \ |
210 | 0 | } \ Unexecuted instantiation: YAML::convert<int>::decode(YAML::Node const&, int&) Unexecuted instantiation: YAML::convert<short>::decode(YAML::Node const&, short&) Unexecuted instantiation: YAML::convert<long>::decode(YAML::Node const&, long&) Unexecuted instantiation: YAML::convert<long long>::decode(YAML::Node const&, long long&) Unexecuted instantiation: YAML::convert<unsigned int>::decode(YAML::Node const&, unsigned int&) Unexecuted instantiation: YAML::convert<unsigned short>::decode(YAML::Node const&, unsigned short&) Unexecuted instantiation: YAML::convert<unsigned long>::decode(YAML::Node const&, unsigned long&) Unexecuted instantiation: YAML::convert<unsigned long long>::decode(YAML::Node const&, unsigned long long&) Unexecuted instantiation: YAML::convert<char>::decode(YAML::Node const&, char&) Unexecuted instantiation: YAML::convert<signed char>::decode(YAML::Node const&, signed char&) Unexecuted instantiation: YAML::convert<unsigned char>::decode(YAML::Node const&, unsigned char&) Unexecuted instantiation: YAML::convert<float>::decode(YAML::Node const&, float&) Unexecuted instantiation: YAML::convert<double>::decode(YAML::Node const&, double&) Unexecuted instantiation: YAML::convert<long double>::decode(YAML::Node const&, long double&) |
211 | | } |
212 | | |
213 | | #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ |
214 | | YAML_DEFINE_CONVERT_STREAMABLE(type, -) |
215 | | |
216 | | #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ |
217 | | YAML_DEFINE_CONVERT_STREAMABLE(type, +) |
218 | | |
219 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); |
220 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); |
221 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); |
222 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); |
223 | | YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); |
224 | | YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); |
225 | | YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); |
226 | | YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); |
227 | | |
228 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); |
229 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char); |
230 | | YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); |
231 | | |
232 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); |
233 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); |
234 | | YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); |
235 | | |
236 | | #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED |
237 | | #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED |
238 | | #undef YAML_DEFINE_CONVERT_STREAMABLE |
239 | | |
240 | | // bool |
241 | | template <> |
242 | | struct convert<bool> { |
243 | 0 | static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } |
244 | | |
245 | | YAML_CPP_API static bool decode(const Node& node, bool& rhs); |
246 | | }; |
247 | | |
248 | | // std::map |
249 | | template <typename K, typename V, typename C, typename A> |
250 | | struct convert<std::map<K, V, C, A>> { |
251 | | static Node encode(const std::map<K, V, C, A>& rhs) { |
252 | | Node node(NodeType::Map); |
253 | | for (const auto& element : rhs) |
254 | | node.force_insert(element.first, element.second); |
255 | | return node; |
256 | | } |
257 | | |
258 | | static bool decode(const Node& node, std::map<K, V, C, A>& rhs) { |
259 | | if (!node.IsMap()) |
260 | | return false; |
261 | | |
262 | | rhs.clear(); |
263 | | for (const auto& element : node) |
264 | | #if defined(__GNUC__) && __GNUC__ < 4 |
265 | | // workaround for GCC 3: |
266 | | rhs[element.first.template as<K>()] = element.second.template as<V>(); |
267 | | #else |
268 | | rhs[element.first.as<K>()] = element.second.as<V>(); |
269 | | #endif |
270 | | return true; |
271 | | } |
272 | | }; |
273 | | |
274 | | // std::unordered_map |
275 | | template <typename K, typename V, typename H, typename P, typename A> |
276 | | struct convert<std::unordered_map<K, V, H, P, A>> { |
277 | | static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) { |
278 | | Node node(NodeType::Map); |
279 | | for (const auto& element : rhs) |
280 | | node.force_insert(element.first, element.second); |
281 | | return node; |
282 | | } |
283 | | |
284 | | static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) { |
285 | | if (!node.IsMap()) |
286 | | return false; |
287 | | |
288 | | rhs.clear(); |
289 | | for (const auto& element : node) |
290 | | #if defined(__GNUC__) && __GNUC__ < 4 |
291 | | // workaround for GCC 3: |
292 | | rhs[element.first.template as<K>()] = element.second.template as<V>(); |
293 | | #else |
294 | | rhs[element.first.as<K>()] = element.second.as<V>(); |
295 | | #endif |
296 | | return true; |
297 | | } |
298 | | }; |
299 | | |
300 | | // std::vector |
301 | | template <typename T, typename A> |
302 | | struct convert<std::vector<T, A>> { |
303 | | static Node encode(const std::vector<T, A>& rhs) { |
304 | | Node node(NodeType::Sequence); |
305 | | for (const auto& element : rhs) |
306 | | node.push_back(element); |
307 | | return node; |
308 | | } |
309 | | |
310 | | static bool decode(const Node& node, std::vector<T, A>& rhs) { |
311 | | if (!node.IsSequence()) |
312 | | return false; |
313 | | |
314 | | rhs.clear(); |
315 | | for (const auto& element : node) |
316 | | #if defined(__GNUC__) && __GNUC__ < 4 |
317 | | // workaround for GCC 3: |
318 | | rhs.push_back(element.template as<T>()); |
319 | | #else |
320 | | rhs.push_back(element.as<T>()); |
321 | | #endif |
322 | | return true; |
323 | | } |
324 | | }; |
325 | | |
326 | | // std::list |
327 | | template <typename T, typename A> |
328 | | struct convert<std::list<T,A>> { |
329 | | static Node encode(const std::list<T,A>& rhs) { |
330 | | Node node(NodeType::Sequence); |
331 | | for (const auto& element : rhs) |
332 | | node.push_back(element); |
333 | | return node; |
334 | | } |
335 | | |
336 | | static bool decode(const Node& node, std::list<T,A>& rhs) { |
337 | | if (!node.IsSequence()) |
338 | | return false; |
339 | | |
340 | | rhs.clear(); |
341 | | for (const auto& element : node) |
342 | | #if defined(__GNUC__) && __GNUC__ < 4 |
343 | | // workaround for GCC 3: |
344 | | rhs.push_back(element.template as<T>()); |
345 | | #else |
346 | | rhs.push_back(element.as<T>()); |
347 | | #endif |
348 | | return true; |
349 | | } |
350 | | }; |
351 | | |
352 | | // std::array |
353 | | template <typename T, std::size_t N> |
354 | | struct convert<std::array<T, N>> { |
355 | | static Node encode(const std::array<T, N>& rhs) { |
356 | | Node node(NodeType::Sequence); |
357 | | for (const auto& element : rhs) { |
358 | | node.push_back(element); |
359 | | } |
360 | | return node; |
361 | | } |
362 | | |
363 | | static bool decode(const Node& node, std::array<T, N>& rhs) { |
364 | | if (!isNodeValid(node)) { |
365 | | return false; |
366 | | } |
367 | | |
368 | | for (auto i = 0u; i < node.size(); ++i) { |
369 | | #if defined(__GNUC__) && __GNUC__ < 4 |
370 | | // workaround for GCC 3: |
371 | | rhs[i] = node[i].template as<T>(); |
372 | | #else |
373 | | rhs[i] = node[i].as<T>(); |
374 | | #endif |
375 | | } |
376 | | return true; |
377 | | } |
378 | | |
379 | | private: |
380 | | static bool isNodeValid(const Node& node) { |
381 | | return node.IsSequence() && node.size() == N; |
382 | | } |
383 | | }; |
384 | | |
385 | | |
386 | | // std::valarray |
387 | | template <typename T> |
388 | | struct convert<std::valarray<T>> { |
389 | | static Node encode(const std::valarray<T>& rhs) { |
390 | | Node node(NodeType::Sequence); |
391 | | for (const auto& element : rhs) { |
392 | | node.push_back(element); |
393 | | } |
394 | | return node; |
395 | | } |
396 | | |
397 | | static bool decode(const Node& node, std::valarray<T>& rhs) { |
398 | | if (!node.IsSequence()) { |
399 | | return false; |
400 | | } |
401 | | |
402 | | rhs.resize(node.size()); |
403 | | for (auto i = 0u; i < node.size(); ++i) { |
404 | | #if defined(__GNUC__) && __GNUC__ < 4 |
405 | | // workaround for GCC 3: |
406 | | rhs[i] = node[i].template as<T>(); |
407 | | #else |
408 | | rhs[i] = node[i].as<T>(); |
409 | | #endif |
410 | | } |
411 | | return true; |
412 | | } |
413 | | }; |
414 | | |
415 | | |
416 | | // std::pair |
417 | | template <typename T, typename U> |
418 | | struct convert<std::pair<T, U>> { |
419 | | static Node encode(const std::pair<T, U>& rhs) { |
420 | | Node node(NodeType::Sequence); |
421 | | node.push_back(rhs.first); |
422 | | node.push_back(rhs.second); |
423 | | return node; |
424 | | } |
425 | | |
426 | | static bool decode(const Node& node, std::pair<T, U>& rhs) { |
427 | | if (!node.IsSequence()) |
428 | | return false; |
429 | | if (node.size() != 2) |
430 | | return false; |
431 | | |
432 | | #if defined(__GNUC__) && __GNUC__ < 4 |
433 | | // workaround for GCC 3: |
434 | | rhs.first = node[0].template as<T>(); |
435 | | #else |
436 | | rhs.first = node[0].as<T>(); |
437 | | #endif |
438 | | #if defined(__GNUC__) && __GNUC__ < 4 |
439 | | // workaround for GCC 3: |
440 | | rhs.second = node[1].template as<U>(); |
441 | | #else |
442 | | rhs.second = node[1].as<U>(); |
443 | | #endif |
444 | | return true; |
445 | | } |
446 | | }; |
447 | | |
448 | | // binary |
449 | | template <> |
450 | | struct convert<Binary> { |
451 | 0 | static Node encode(const Binary& rhs) { |
452 | 0 | return Node(EncodeBase64(rhs.data(), rhs.size())); |
453 | 0 | } |
454 | | |
455 | 0 | static bool decode(const Node& node, Binary& rhs) { |
456 | 0 | if (!node.IsScalar()) |
457 | 0 | return false; |
458 | 0 |
|
459 | 0 | std::vector<unsigned char> data = DecodeBase64(node.Scalar()); |
460 | 0 | if (data.empty() && !node.Scalar().empty()) |
461 | 0 | return false; |
462 | 0 |
|
463 | 0 | rhs.swap(data); |
464 | 0 | return true; |
465 | 0 | } |
466 | | }; |
467 | | } |
468 | | |
469 | | #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 |