]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/json/test/value_from.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / json / test / value_from.cpp
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/json
9 //
10
11 // Test that header file is self-contained.
12 #include <boost/json/value_from.hpp>
13
14 #include <boost/json/value.hpp> // prevent intellisense bugs
15 #include <boost/json/serialize.hpp>
16
17 #include "test_suite.hpp"
18
19 #include <array>
20 #include <string>
21 #include <vector>
22 #include <tuple>
23 #include <map>
24 #include <unordered_map>
25
26 //----------------------------------------------------------
27
28 namespace value_from_test_ns {
29
30 //----------------------------------------------------------
31
32 struct T1
33 {
34 int i = 42;
35 };
36
37 void
38 tag_invoke(
39 ::boost::json::value_from_tag,
40 ::boost::json::value& jv,
41 T1 const& t)
42 {
43 jv = t.i;
44 }
45
46 //----------------------------------------------------------
47
48 // member function
49 // uses generic algorithms
50 struct T2
51 {
52 std::vector<int> v;
53 std::string s;
54
55 T2()
56 : v({1,2,3, 4})
57 , s("test")
58 {
59 }
60 };
61
62 void
63 tag_invoke(
64 ::boost::json::value_from_tag,
65 ::boost::json::value& jv,
66 T2 const& t)
67 {
68 jv = { t.v, t.s };
69 }
70
71 struct T3
72 {
73 };
74
75 BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T3>::value);
76
77 struct T4
78 {
79 operator ::boost::json::value()
80 {
81 return nullptr;
82 }
83 };
84
85 BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T4>::value);
86
87 //----------------------------------------------------------
88
89 struct T5 : std::vector<int>
90 {
91 using std::vector<int>::vector;
92 };
93
94 void
95 tag_invoke(
96 ::boost::json::value_from_tag,
97 ::boost::json::value& jv,
98 T5 const&)
99 {
100 jv = "T5";
101 }
102
103
104 //----------------------------------------------------------
105
106 } // value_from_test_ns
107
108 template<class T>
109 static
110 void
111 check(
112 ::boost::json::string_view s,
113 T const& t)
114 {
115 {
116 auto const jv = value_from(t,
117 ::boost::json::storage_ptr{});
118 auto const js =
119 ::boost::json::serialize(jv);
120 BOOST_TEST(js == s);
121 }
122 {
123 auto const jv =
124 ::boost::json::value_from(t);
125 auto const js =
126 ::boost::json::serialize(jv);
127 BOOST_TEST(js == s);
128 }
129 }
130
131 BOOST_JSON_NS_BEGIN
132
133 namespace {
134
135 template<class T>
136 static
137 void
138 testValueCtor(T const& t)
139 {
140 BOOST_TEST( serialize(value_from(t)) == serialize(value(t)) );
141 }
142
143 template<class T>
144 static
145 void
146 testValueCtor()
147 {
148 testValueCtor(T{});
149 }
150
151 } // namespace
152
153 // integral
154 BOOST_STATIC_ASSERT(has_value_from<int>::value);
155 BOOST_STATIC_ASSERT(has_value_from<int&>::value);
156 BOOST_STATIC_ASSERT(has_value_from<int&&>::value);
157 // array
158 BOOST_STATIC_ASSERT(has_value_from<int[4]>::value);
159 BOOST_STATIC_ASSERT(has_value_from<int(&)[4]>::value);
160 BOOST_STATIC_ASSERT(has_value_from<int(&&)[4]>::value);
161 // forward range
162 BOOST_STATIC_ASSERT(has_value_from<std::vector<int>>::value);
163 BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&>::value);
164 BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&&>::value);
165 // tuple-like
166 BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>>::value);
167 BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&>::value);
168 BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&&>::value);
169 BOOST_STATIC_ASSERT(has_value_from<key_value_pair>::value);
170 BOOST_STATIC_ASSERT(has_value_from<key_value_pair&>::value);
171 BOOST_STATIC_ASSERT(has_value_from<key_value_pair&&>::value);
172
173 // object-like
174 BOOST_STATIC_ASSERT(has_value_from<std::map<string_view, int>>::value);
175
176 class value_from_test
177 {
178 public:
179 static
180 void
181 testValueCtors()
182 {
183 // value_from supports every value constructor
184
185 testValueCtor<value>();
186
187 char const* s = "5";
188 testValueCtor(s);
189 }
190
191 static
192 void
193 testGeneral()
194 {
195 {
196 int a[4] = {1, 2, 3, 4};
197 value b{1, 2, 3, 4};
198 value c = value_from(a);
199 BOOST_TEST(c.is_array());
200 BOOST_TEST(serialize(c) == serialize(b));
201 }
202 {
203 std::tuple<int, string, int, bool> a{1, "2", 42, true};
204 value b{1, "2", 42, true};
205 value c = value_from(a);
206 BOOST_TEST(c.is_array());
207 BOOST_TEST(serialize(c) == serialize(b));
208 }
209 {
210 std::array<int, 1000> a;
211 a.fill(0);
212
213 value b;
214 array& b_arr = b.emplace_array();
215 b_arr.insert(b_arr.end(), a.begin(), a.end());
216
217 BOOST_TEST(value_from(a) == b);
218 }
219 {
220 std::pair<int, string> a{1, string("2")};
221 value b{1, "2"};
222 value c = value_from(a);
223 BOOST_TEST(c.is_array());
224 BOOST_TEST(serialize(c) == serialize(b));
225 }
226 {
227 // ensures that this isn't parsed as a key value pair
228 std::pair<string_view, int> a{"2", 1};
229 value b{"2", 1};
230 value c = value_from(a);
231 BOOST_TEST(c.is_array());
232 BOOST_TEST(serialize(c) == serialize(b));
233 }
234 {
235 key_value_pair a{"2", 1};
236 value b{"2", 1};
237 value c = value_from(a);
238 BOOST_TEST(c.is_array());
239 BOOST_TEST(serialize(c) == serialize(b));
240 }
241 }
242
243 static
244 void
245 testAssociative()
246 {
247 {
248 std::map<string_view, int> a =
249 {{"a", 1}, {"b", 2}, {"c", 3}};
250 value b = {{"a", 1}, {"b", 2}, {"c", 3}};
251 value c = value_from(a);
252 BOOST_TEST(c.is_object());
253 BOOST_TEST(a.size() == c.as_object().size());
254 BOOST_TEST(b.as_object().size() == c.as_object().size());
255 }
256 {
257 std::unordered_map<std::string, int> a =
258 {{"a", 1}, {"b", 2}, {"c", 3}};
259 value b = {{"a", 1}, {"b", 2}, {"c", 3}};
260 value c = value_from(a);
261 BOOST_TEST(c.is_object());
262 BOOST_TEST(a.size() == c.as_object().size());
263 BOOST_TEST(b.as_object().size() == c.as_object().size());
264 }
265 {
266 std::map<int, int> a =
267 {{1, 1}, {2, 2}, {3, 3}};
268 value b = {{1, 1}, {2, 2}, {3, 3}};
269 value c = value_from(a);
270 BOOST_TEST(!c.is_object());
271 BOOST_TEST(a.size() == c.as_array().size());
272 BOOST_TEST(b.as_array().size() == c.as_array().size());
273 }
274 {
275 std::unordered_map<int, int> a =
276 {{1, 1}, {2, 2}, {3, 3}};
277 value b = {{1, 1}, {2, 2}, {3, 3}};
278 value c = value_from(a);
279 BOOST_TEST(!c.is_object());
280 BOOST_TEST(a.size() == c.as_array().size());
281 BOOST_TEST(b.as_array().size() == c.as_array().size());
282 }
283 }
284
285 static
286 void
287 testPreferUserCustomizations()
288 {
289 value_from_test_ns::T5 t5;
290 BOOST_TEST((::boost::json::value_from(t5) == "T5"));
291 }
292
293 void
294 run()
295 {
296 check("42", ::value_from_test_ns::T1{});
297 check("[[1,2,3,4],\"test\"]", ::value_from_test_ns::T2{});
298
299 testValueCtors();
300 testGeneral();
301 testAssociative();
302 testPreferUserCustomizations();
303 }
304 };
305
306 TEST_SUITE(value_from_test, "boost.json.value_from");
307
308 BOOST_JSON_NS_END