• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #include "doctest_compatibility.h"
31 
32 #define private public
33 #include <nlohmann/json.hpp>
34 using nlohmann::json;
35 #undef private
36 
37 #include <deque>
38 #include <forward_list>
39 #include <list>
40 #include <set>
41 #include <unordered_map>
42 #include <unordered_set>
43 #include <valarray>
44 
45 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
46     #define JSON_HAS_CPP_17
47     #define JSON_HAS_CPP_14
48 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
49     #define JSON_HAS_CPP_14
50 #endif
51 
52 #if defined(JSON_HAS_CPP_17)
53     #include <string_view>
54 #endif
55 
56 TEST_CASE("value conversion")
57 {
58     SECTION("get an object (explicit)")
59     {
60         json::object_t o_reference = {{"object", json::object()},
61             {"array", {1, 2, 3, 4}},
62             {"number", 42},
63             {"boolean", false},
64             {"null", nullptr},
65             {"string", "Hello world"}
66         };
67         json j(o_reference);
68 
69         SECTION("json::object_t")
70         {
71             json::object_t o = j.get<json::object_t>();
72             CHECK(json(o) == j);
73         }
74 
75         SECTION("std::map<json::string_t, json>")
76         {
77             std::map<json::string_t, json> o =
78                 j.get<std::map<json::string_t, json>>();
79             CHECK(json(o) == j);
80         }
81 
82         SECTION("std::multimap<json::string_t, json>")
83         {
84             std::multimap<json::string_t, json> o =
85                 j.get<std::multimap<json::string_t, json>>();
86             CHECK(json(o) == j);
87         }
88 
89         SECTION("std::unordered_map<json::string_t, json>")
90         {
91             std::unordered_map<json::string_t, json> o =
92                 j.get<std::unordered_map<json::string_t, json>>();
93             CHECK(json(o) == j);
94         }
95 
96         SECTION("std::unordered_multimap<json::string_t, json>")
97         {
98             std::unordered_multimap<json::string_t, json> o =
99                 j.get<std::unordered_multimap<json::string_t, json>>();
100             CHECK(json(o) == j);
101         }
102 
103         SECTION("exception in case of a non-object type")
104         {
105             CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(),
106                             json::type_error&);
107             CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(),
108                             json::type_error&);
109             CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(),
110                             json::type_error&);
111             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(),
112                             json::type_error&);
113             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(),
114                             json::type_error&);
115             CHECK_THROWS_AS(
116                 json(json::value_t::number_unsigned).get<json::object_t>(),
117                 json::type_error&);
118             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(),
119                             json::type_error&);
120 
121             CHECK_THROWS_WITH(
122                 json(json::value_t::null).get<json::object_t>(),
123                 "[json.exception.type_error.302] type must be object, but is null");
124             CHECK_THROWS_WITH(
125                 json(json::value_t::array).get<json::object_t>(),
126                 "[json.exception.type_error.302] type must be object, but is array");
127             CHECK_THROWS_WITH(
128                 json(json::value_t::string).get<json::object_t>(),
129                 "[json.exception.type_error.302] type must be object, but is string");
130             CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),
131                               "[json.exception.type_error.302] type must be object, "
132                               "but is boolean");
133             CHECK_THROWS_WITH(
134                 json(json::value_t::number_integer).get<json::object_t>(),
135                 "[json.exception.type_error.302] type must be object, but is number");
136             CHECK_THROWS_WITH(
137                 json(json::value_t::number_unsigned).get<json::object_t>(),
138                 "[json.exception.type_error.302] type must be object, but is number");
139             CHECK_THROWS_WITH(
140                 json(json::value_t::number_float).get<json::object_t>(),
141                 "[json.exception.type_error.302] type must be object, but is number");
142         }
143     }
144 
145     SECTION("get an object (explicit, get_to)")
146     {
147         json::object_t o_reference = {{"object", json::object()},
148             {"array", {1, 2, 3, 4}},
149             {"number", 42},
150             {"boolean", false},
151             {"null", nullptr},
152             {"string", "Hello world"}
153         };
154         json j(o_reference);
155 
156         SECTION("json::object_t")
157         {
158             json::object_t o = {{"previous", "value"}};
159             j.get_to(o);
160             CHECK(json(o) == j);
161         }
162 
163         SECTION("std::map<json::string_t, json>")
164         {
165             std::map<json::string_t, json> o{{"previous", "value"}};
166             j.get_to(o);
167             CHECK(json(o) == j);
168         }
169 
170         SECTION("std::multimap<json::string_t, json>")
171         {
172             std::multimap<json::string_t, json> o{{"previous", "value"}};
173             j.get_to(o);
174             CHECK(json(o) == j);
175         }
176 
177         SECTION("std::unordered_map<json::string_t, json>")
178         {
179             std::unordered_map<json::string_t, json> o{{"previous", "value"}};
180             j.get_to(o);
181             CHECK(json(o) == j);
182         }
183 
184         SECTION("std::unordered_multimap<json::string_t, json>")
185         {
186             std::unordered_multimap<json::string_t, json> o{{"previous", "value"}};
187             j.get_to(o);
188             CHECK(json(o) == j);
189         }
190     }
191 
192 #if JSON_USE_IMPLICIT_CONVERSIONS
193     SECTION("get an object (implicit)")
194     {
195         json::object_t o_reference = {{"object", json::object()},
196             {"array", {1, 2, 3, 4}},
197             {"number", 42},
198             {"boolean", false},
199             {"null", nullptr},
200             {"string", "Hello world"}
201         };
202         json j(o_reference);
203 
204         SECTION("json::object_t")
205         {
206             json::object_t o = j;
207             CHECK(json(o) == j);
208         }
209 
210         SECTION("std::map<json::string_t, json>")
211         {
212             std::map<json::string_t, json> o = j;
213             CHECK(json(o) == j);
214         }
215 
216         SECTION("std::multimap<json::string_t, json>")
217         {
218             std::multimap<json::string_t, json> o = j;
219             CHECK(json(o) == j);
220         }
221 
222         SECTION("std::unordered_map<json::string_t, json>")
223         {
224             std::unordered_map<json::string_t, json> o = j;
225             CHECK(json(o) == j);
226         }
227 
228         SECTION("std::unordered_multimap<json::string_t, json>")
229         {
230             std::unordered_multimap<json::string_t, json> o = j;
231             CHECK(json(o) == j);
232         }
233     }
234 #endif
235 
236     SECTION("get an array (explicit)")
237     {
238         json::array_t a_reference{json(1),     json(1u),       json(2.2),
239                                   json(false), json("string"), json()};
240         json j(a_reference);
241 
242         SECTION("json::array_t")
243         {
244             json::array_t a = j.get<json::array_t>();
245             CHECK(json(a) == j);
246         }
247 
248         SECTION("std::list<json>")
249         {
250             std::list<json> a = j.get<std::list<json>>();
251             CHECK(json(a) == j);
252         }
253 
254         SECTION("std::forward_list<json>")
255         {
256             std::forward_list<json> a = j.get<std::forward_list<json>>();
257             CHECK(json(a) == j);
258 
259             CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(),
260                             json::type_error&);
261             CHECK_THROWS_WITH(
262                 json(json::value_t::null).get<std::forward_list<json>>(),
263                 "[json.exception.type_error.302] type must be array, but is null");
264         }
265 
266         SECTION("std::vector<json>")
267         {
268             std::vector<json> a = j.get<std::vector<json>>();
269             CHECK(json(a) == j);
270 
271             CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(),
272                             json::type_error&);
273             CHECK_THROWS_WITH(
274                 json(json::value_t::null).get<std::vector<json>>(),
275                 "[json.exception.type_error.302] type must be array, but is null");
276 
277 #if !defined(JSON_NOEXCEPTION)
278             SECTION("reserve is called on containers that supports it")
279             {
280                 // make sure all values are properly copied
281                 json j2({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
282                 auto v2 = j2.get<std::vector<int>>();
283                 CHECK(v2.size() == 10);
284             }
285 #endif
286         }
287 
288         SECTION("built-in arrays")
289         {
290             const char str[] = "a string";
291             const int nbs[] = {0, 1, 2};
292 
293             json j2 = nbs;
294             json j3 = str;
295 
296             auto v = j2.get<std::vector<int>>();
297             auto s = j3.get<std::string>();
298             CHECK(std::equal(v.begin(), v.end(), std::begin(nbs)));
299             CHECK(s == str);
300         }
301 
302         SECTION("std::deque<json>")
303         {
304             std::deque<json> a = j.get<std::deque<json>>();
305             CHECK(json(a) == j);
306         }
307 
308         SECTION("exception in case of a non-array type")
309         {
310             CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(),
311                             json::type_error&);
312             CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(),
313                             json::type_error&);
314             CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(),
315                             json::type_error&);
316             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(),
317                             json::type_error&);
318             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(),
319                             json::type_error&);
320             CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(),
321                             json::type_error&);
322             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(),
323                             json::type_error&);
324 
325             CHECK_THROWS_WITH(
326                 json(json::value_t::object).get<std::vector<int>>(),
327                 "[json.exception.type_error.302] type must be array, but is object");
328             CHECK_THROWS_WITH(
329                 json(json::value_t::null).get<json::array_t>(),
330                 "[json.exception.type_error.302] type must be array, but is null");
331             CHECK_THROWS_WITH(
332                 json(json::value_t::object).get<json::array_t>(),
333                 "[json.exception.type_error.302] type must be array, but is object");
334             CHECK_THROWS_WITH(
335                 json(json::value_t::string).get<json::array_t>(),
336                 "[json.exception.type_error.302] type must be array, but is string");
337             CHECK_THROWS_WITH(
338                 json(json::value_t::boolean).get<json::array_t>(),
339                 "[json.exception.type_error.302] type must be array, but is boolean");
340             CHECK_THROWS_WITH(
341                 json(json::value_t::number_integer).get<json::array_t>(),
342                 "[json.exception.type_error.302] type must be array, but is number");
343             CHECK_THROWS_WITH(
344                 json(json::value_t::number_unsigned).get<json::array_t>(),
345                 "[json.exception.type_error.302] type must be array, but is number");
346             CHECK_THROWS_WITH(
347                 json(json::value_t::number_float).get<json::array_t>(),
348                 "[json.exception.type_error.302] type must be array, but is number");
349         }
350     }
351 
352     SECTION("get an array (explicit, get_to)")
353     {
354         json::array_t a_reference{json(1),     json(1u),       json(2.2),
355                                   json(false), json("string"), json()};
356         json j(a_reference);
357 
358         SECTION("json::array_t")
359         {
360             json::array_t a{"previous", "value"};
361             j.get_to(a);
362             CHECK(json(a) == j);
363         }
364 
365         SECTION("std::valarray<json>")
366         {
367             std::valarray<json> a{"previous", "value"};
368             j.get_to(a);
369             CHECK(json(a) == j);
370         }
371 
372         SECTION("std::list<json>")
373         {
374             std::list<json> a{"previous", "value"};
375             j.get_to(a);
376             CHECK(json(a) == j);
377         }
378 
379         SECTION("std::forward_list<json>")
380         {
381             std::forward_list<json> a{"previous", "value"};
382             j.get_to(a);
383             CHECK(json(a) == j);
384         }
385 
386         SECTION("std::vector<json>")
387         {
388             std::vector<json> a{"previous", "value"};
389             j.get_to(a);
390             CHECK(json(a) == j);
391         }
392 
393         SECTION("built-in arrays")
394         {
395             const int nbs[] = {0, 1, 2};
396             int nbs2[] = {0, 0, 0};
397 
398             json j2 = nbs;
399             j2.get_to(nbs2);
400             CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2)));
401         }
402 
403         SECTION("std::deque<json>")
404         {
405             std::deque<json> a{"previous", "value"};
406             j.get_to(a);
407             CHECK(json(a) == j);
408         }
409     }
410 
411 #if JSON_USE_IMPLICIT_CONVERSIONS
412     SECTION("get an array (implicit)")
413     {
414         json::array_t a_reference{json(1),     json(1u),       json(2.2),
415                                   json(false), json("string"), json()};
416         json j(a_reference);
417 
418         SECTION("json::array_t")
419         {
420             json::array_t a = j;
421             CHECK(json(a) == j);
422         }
423 
424         SECTION("std::list<json>")
425         {
426             std::list<json> a = j;
427             CHECK(json(a) == j);
428         }
429 
430         SECTION("std::forward_list<json>")
431         {
432             std::forward_list<json> a = j;
433             CHECK(json(a) == j);
434         }
435 
436         SECTION("std::vector<json>")
437         {
438             std::vector<json> a = j;
439             CHECK(json(a) == j);
440         }
441 
442         SECTION("std::deque<json>")
443         {
444             std::deque<json> a = j;
445             CHECK(json(a) == j);
446         }
447     }
448 #endif
449 
450     SECTION("get a string (explicit)")
451     {
452         json::string_t s_reference{"Hello world"};
453         json j(s_reference);
454 
455         SECTION("string_t")
456         {
457             json::string_t s = j.get<json::string_t>();
458             CHECK(json(s) == j);
459         }
460 
461         SECTION("std::string")
462         {
463             std::string s = j.get<std::string>();
464             CHECK(json(s) == j);
465         }
466 #if defined(JSON_HAS_CPP_17)
467         SECTION("std::string_view")
468         {
469             std::string_view s = j.get<std::string_view>();
470             CHECK(json(s) == j);
471         }
472 #endif
473 
474         SECTION("exception in case of a non-string type")
475         {
476             CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(),
477                             json::type_error&);
478             CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(),
479                             json::type_error&);
480             CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(),
481                             json::type_error&);
482             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(),
483                             json::type_error&);
484             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(),
485                             json::type_error&);
486             CHECK_THROWS_AS(
487                 json(json::value_t::number_unsigned).get<json::string_t>(),
488                 json::type_error&);
489             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(),
490                             json::type_error&);
491 
492             CHECK_THROWS_WITH(
493                 json(json::value_t::null).get<json::string_t>(),
494                 "[json.exception.type_error.302] type must be string, but is null");
495             CHECK_THROWS_WITH(
496                 json(json::value_t::object).get<json::string_t>(),
497                 "[json.exception.type_error.302] type must be string, but is object");
498             CHECK_THROWS_WITH(
499                 json(json::value_t::array).get<json::string_t>(),
500                 "[json.exception.type_error.302] type must be string, but is array");
501             CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
502                               "[json.exception.type_error.302] type must be string, "
503                               "but is boolean");
504             CHECK_THROWS_WITH(
505                 json(json::value_t::number_integer).get<json::string_t>(),
506                 "[json.exception.type_error.302] type must be string, but is number");
507             CHECK_THROWS_WITH(
508                 json(json::value_t::number_unsigned).get<json::string_t>(),
509                 "[json.exception.type_error.302] type must be string, but is number");
510             CHECK_THROWS_WITH(
511                 json(json::value_t::number_float).get<json::string_t>(),
512                 "[json.exception.type_error.302] type must be string, but is number");
513         }
514 
515 #if defined(JSON_HAS_CPP_17)
516         SECTION("exception in case of a non-string type using string_view")
517         {
518             CHECK_THROWS_AS(json(json::value_t::null).get<std::string_view>(), json::type_error&);
519             CHECK_THROWS_AS(json(json::value_t::object).get<std::string_view>(), json::type_error&);
520             CHECK_THROWS_AS(json(json::value_t::array).get<std::string_view>(), json::type_error&);
521             CHECK_THROWS_AS(json(json::value_t::boolean).get<std::string_view>(), json::type_error&);
522             CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::string_view>(), json::type_error&);
523             CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::string_view>(), json::type_error&);
524             CHECK_THROWS_AS(json(json::value_t::number_float).get<std::string_view>(), json::type_error&);
525 
526             CHECK_THROWS_WITH(json(json::value_t::null).get<std::string_view>(),
527                               "[json.exception.type_error.302] type must be string, but is null");
528             CHECK_THROWS_WITH(json(json::value_t::object).get<std::string_view>(),
529                               "[json.exception.type_error.302] type must be string, but is object");
530             CHECK_THROWS_WITH(json(json::value_t::array).get<std::string_view>(),
531                               "[json.exception.type_error.302] type must be string, but is array");
532             CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::string_view>(),
533                               "[json.exception.type_error.302] type must be string, but is boolean");
534             CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::string_view>(),
535                               "[json.exception.type_error.302] type must be string, but is number");
536             CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::string_view>(),
537                               "[json.exception.type_error.302] type must be string, but is number");
538             CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::string_view>(),
539                               "[json.exception.type_error.302] type must be string, but is number");
540         }
541 #endif
542     }
543 
544     SECTION("get a string (explicit, get_to)")
545     {
546         json::string_t s_reference{"Hello world"};
547         json j(s_reference);
548 
549         SECTION("string_t")
550         {
551             json::string_t s = "previous value";
552             j.get_to(s);
553             CHECK(json(s) == j);
554         }
555 
556         SECTION("std::string")
557         {
558             std::string s = "previous value";
559             j.get_to(s);
560             CHECK(json(s) == j);
561         }
562 #if defined(JSON_HAS_CPP_17)
563         SECTION("std::string_view")
564         {
565             std::string s = "previous value";
566             std::string_view sv = s;
567             j.get_to(sv);
568             CHECK(json(sv) == j);
569         }
570 #endif
571     }
572 
573     SECTION("get null (explicit)")
574     {
575         std::nullptr_t n = nullptr;
576         json j(n);
577 
578         auto n2 = j.get<std::nullptr_t>();
579         CHECK(n2 == n);
580 
581         CHECK_THROWS_AS(json(json::value_t::string).get<std::nullptr_t>(), json::type_error&);
582         CHECK_THROWS_AS(json(json::value_t::object).get<std::nullptr_t>(), json::type_error&);
583         CHECK_THROWS_AS(json(json::value_t::array).get<std::nullptr_t>(), json::type_error&);
584         CHECK_THROWS_AS(json(json::value_t::boolean).get<std::nullptr_t>(), json::type_error&);
585         CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::nullptr_t>(), json::type_error&);
586         CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(), json::type_error&);
587         CHECK_THROWS_AS(json(json::value_t::number_float).get<std::nullptr_t>(), json::type_error&);
588 
589         CHECK_THROWS_WITH(json(json::value_t::string).get<std::nullptr_t>(),
590                           "[json.exception.type_error.302] type must be null, but is string");
591         CHECK_THROWS_WITH(json(json::value_t::object).get<std::nullptr_t>(),
592                           "[json.exception.type_error.302] type must be null, but is object");
593         CHECK_THROWS_WITH(json(json::value_t::array).get<std::nullptr_t>(),
594                           "[json.exception.type_error.302] type must be null, but is array");
595         CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::nullptr_t>(),
596                           "[json.exception.type_error.302] type must be null, but is boolean");
597         CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::nullptr_t>(),
598                           "[json.exception.type_error.302] type must be null, but is number");
599         CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::nullptr_t>(),
600                           "[json.exception.type_error.302] type must be null, but is number");
601         CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::nullptr_t>(),
602                           "[json.exception.type_error.302] type must be null, but is number");
603 
604     }
605 
606 #if JSON_USE_IMPLICIT_CONVERSIONS
607     SECTION("get a string (implicit)")
608     {
609         json::string_t s_reference{"Hello world"};
610         json j(s_reference);
611 
612         SECTION("string_t")
613         {
614             json::string_t s = j;
615             CHECK(json(s) == j);
616         }
617 
618 #if defined(JSON_HAS_CPP_17)
619         SECTION("std::string_view")
620         {
621             std::string_view s = j.get<std::string_view>();
622             CHECK(json(s) == j);
623         }
624 #endif
625 
626         SECTION("std::string")
627         {
628             std::string s = j;
629             CHECK(json(s) == j);
630         }
631     }
632 #endif
633 
634     SECTION("get a boolean (explicit)")
635     {
636         json::boolean_t b_reference{true};
637         json j(b_reference);
638 
639         SECTION("boolean_t")
640         {
641             json::boolean_t b = j.get<json::boolean_t>();
642             CHECK(json(b) == j);
643         }
644 
645         SECTION("uint8_t")
646         {
647             auto n = j.get<uint8_t>();
648             CHECK(n == 1);
649         }
650 
651         SECTION("bool")
652         {
653             bool b = j.get<bool>();
654             CHECK(json(b) == j);
655         }
656 
657         SECTION("exception in case of a non-number type")
658         {
659             CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(),
660                             json::type_error&);
661             CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(),
662                             json::type_error&);
663             CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(),
664                             json::type_error&);
665             CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(),
666                             json::type_error&);
667             CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(),
668                             json::type_error&);
669             CHECK_THROWS_AS(
670                 json(json::value_t::number_integer).get<json::boolean_t>(),
671                 json::type_error&);
672             CHECK_THROWS_AS(
673                 json(json::value_t::number_unsigned).get<json::boolean_t>(),
674                 json::type_error&);
675             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(),
676                             json::type_error&);
677 
678             CHECK_THROWS_WITH(
679                 json(json::value_t::null).get<json::boolean_t>(),
680                 "[json.exception.type_error.302] type must be boolean, but is null");
681             CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
682                               "[json.exception.type_error.302] type must be boolean, "
683                               "but is object");
684             CHECK_THROWS_WITH(
685                 json(json::value_t::array).get<json::boolean_t>(),
686                 "[json.exception.type_error.302] type must be boolean, but is array");
687             CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
688                               "[json.exception.type_error.302] type must be boolean, "
689                               "but is string");
690             CHECK_THROWS_WITH(
691                 json(json::value_t::number_integer).get<json::boolean_t>(),
692                 "[json.exception.type_error.302] type must be boolean, but is "
693                 "number");
694             CHECK_THROWS_WITH(
695                 json(json::value_t::number_unsigned).get<json::boolean_t>(),
696                 "[json.exception.type_error.302] type must be boolean, but is "
697                 "number");
698             CHECK_THROWS_WITH(
699                 json(json::value_t::number_float).get<json::boolean_t>(),
700                 "[json.exception.type_error.302] type must be boolean, but is "
701                 "number");
702         }
703     }
704 
705 #if JSON_USE_IMPLICIT_CONVERSIONS
706     SECTION("get a boolean (implicit)")
707     {
708         json::boolean_t b_reference{true};
709         json j(b_reference);
710 
711         SECTION("boolean_t")
712         {
713             json::boolean_t b = j;
714             CHECK(json(b) == j);
715         }
716 
717         SECTION("bool")
718         {
719             bool b = j;
720             CHECK(json(b) == j);
721         }
722     }
723 #endif
724 
725     SECTION("get an integer number (explicit)")
726     {
727         json::number_integer_t n_reference{42};
728         json j(n_reference);
729         json::number_unsigned_t n_unsigned_reference{42u};
730         json j_unsigned(n_unsigned_reference);
731 
732         SECTION("number_integer_t")
733         {
734             json::number_integer_t n = j.get<json::number_integer_t>();
735             CHECK(json(n) == j);
736         }
737 
738         SECTION("number_unsigned_t")
739         {
740             json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
741             CHECK(json(n) == j_unsigned);
742         }
743 
744         SECTION("short")
745         {
746             short n = j.get<short>();
747             CHECK(json(n) == j);
748         }
749 
750         SECTION("unsigned short")
751         {
752             unsigned short n = j.get<unsigned short>();
753             CHECK(json(n) == j);
754         }
755 
756         SECTION("int")
757         {
758             int n = j.get<int>();
759             CHECK(json(n) == j);
760         }
761 
762         SECTION("unsigned int")
763         {
764             unsigned int n = j.get<unsigned int>();
765             CHECK(json(n) == j);
766         }
767 
768         SECTION("long")
769         {
770             long n = j.get<long>();
771             CHECK(json(n) == j);
772         }
773 
774         SECTION("unsigned long")
775         {
776             unsigned long n = j.get<unsigned long>();
777             CHECK(json(n) == j);
778         }
779 
780         SECTION("long long")
781         {
782             long long n = j.get<long long>();
783             CHECK(json(n) == j);
784         }
785 
786         SECTION("unsigned long long")
787         {
788             unsigned long long n = j.get<unsigned long long>();
789             CHECK(json(n) == j);
790         }
791 
792         SECTION("int8_t")
793         {
794             int8_t n = j.get<int8_t>();
795             CHECK(json(n) == j);
796         }
797 
798         SECTION("int16_t")
799         {
800             int16_t n = j.get<int16_t>();
801             CHECK(json(n) == j);
802         }
803 
804         SECTION("int32_t")
805         {
806             int32_t n = j.get<int32_t>();
807             CHECK(json(n) == j);
808         }
809 
810         SECTION("int64_t")
811         {
812             int64_t n = j.get<int64_t>();
813             CHECK(json(n) == j);
814         }
815 
816         SECTION("int8_fast_t")
817         {
818             int_fast8_t n = j.get<int_fast8_t>();
819             CHECK(json(n) == j);
820         }
821 
822         SECTION("int16_fast_t")
823         {
824             int_fast16_t n = j.get<int_fast16_t>();
825             CHECK(json(n) == j);
826         }
827 
828         SECTION("int32_fast_t")
829         {
830             int_fast32_t n = j.get<int_fast32_t>();
831             CHECK(json(n) == j);
832         }
833 
834         SECTION("int64_fast_t")
835         {
836             int_fast64_t n = j.get<int_fast64_t>();
837             CHECK(json(n) == j);
838         }
839 
840         SECTION("int8_least_t")
841         {
842             int_least8_t n = j.get<int_least8_t>();
843             CHECK(json(n) == j);
844         }
845 
846         SECTION("int16_least_t")
847         {
848             int_least16_t n = j.get<int_least16_t>();
849             CHECK(json(n) == j);
850         }
851 
852         SECTION("int32_least_t")
853         {
854             int_least32_t n = j.get<int_least32_t>();
855             CHECK(json(n) == j);
856         }
857 
858         SECTION("int64_least_t")
859         {
860             int_least64_t n = j.get<int_least64_t>();
861             CHECK(json(n) == j);
862         }
863 
864         SECTION("uint8_t")
865         {
866             uint8_t n = j.get<uint8_t>();
867             CHECK(json(n) == j);
868         }
869 
870         SECTION("uint16_t")
871         {
872             uint16_t n = j.get<uint16_t>();
873             CHECK(json(n) == j);
874         }
875 
876         SECTION("uint32_t")
877         {
878             uint32_t n = j.get<uint32_t>();
879             CHECK(json(n) == j);
880         }
881 
882         SECTION("uint64_t")
883         {
884             uint64_t n = j.get<uint64_t>();
885             CHECK(json(n) == j);
886         }
887 
888         SECTION("uint8_fast_t")
889         {
890             uint_fast8_t n = j.get<uint_fast8_t>();
891             CHECK(json(n) == j);
892         }
893 
894         SECTION("uint16_fast_t")
895         {
896             uint_fast16_t n = j.get<uint_fast16_t>();
897             CHECK(json(n) == j);
898         }
899 
900         SECTION("uint32_fast_t")
901         {
902             uint_fast32_t n = j.get<uint_fast32_t>();
903             CHECK(json(n) == j);
904         }
905 
906         SECTION("uint64_fast_t")
907         {
908             uint_fast64_t n = j.get<uint_fast64_t>();
909             CHECK(json(n) == j);
910         }
911 
912         SECTION("uint8_least_t")
913         {
914             uint_least8_t n = j.get<uint_least8_t>();
915             CHECK(json(n) == j);
916         }
917 
918         SECTION("uint16_least_t")
919         {
920             uint_least16_t n = j.get<uint_least16_t>();
921             CHECK(json(n) == j);
922         }
923 
924         SECTION("uint32_least_t")
925         {
926             uint_least32_t n = j.get<uint_least32_t>();
927             CHECK(json(n) == j);
928         }
929 
930         SECTION("uint64_least_t")
931         {
932             uint_least64_t n = j.get<uint_least64_t>();
933             CHECK(json(n) == j);
934         }
935 
936         SECTION("exception in case of a non-number type")
937         {
938             CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(),
939                             json::type_error&);
940             CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(),
941                             json::type_error&);
942             CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(),
943                             json::type_error&);
944             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(),
945                             json::type_error&);
946             CHECK_THROWS_AS(
947                 json(json::value_t::boolean).get<json::number_integer_t>(),
948                 json::type_error&);
949 
950             CHECK_THROWS_WITH(
951                 json(json::value_t::null).get<json::number_integer_t>(),
952                 "[json.exception.type_error.302] type must be number, but is null");
953             CHECK_THROWS_WITH(
954                 json(json::value_t::object).get<json::number_integer_t>(),
955                 "[json.exception.type_error.302] type must be number, but is object");
956             CHECK_THROWS_WITH(
957                 json(json::value_t::array).get<json::number_integer_t>(),
958                 "[json.exception.type_error.302] type must be number, but is array");
959             CHECK_THROWS_WITH(
960                 json(json::value_t::string).get<json::number_integer_t>(),
961                 "[json.exception.type_error.302] type must be number, but is string");
962             CHECK_THROWS_WITH(
963                 json(json::value_t::boolean).get<json::number_integer_t>(),
964                 "[json.exception.type_error.302] type must be number, but is "
965                 "boolean");
966 
967             CHECK_NOTHROW(
968                 json(json::value_t::number_float).get<json::number_integer_t>());
969             CHECK_NOTHROW(
970                 json(json::value_t::number_float).get<json::number_unsigned_t>());
971         }
972     }
973 
974 #if JSON_USE_IMPLICIT_CONVERSIONS
975     SECTION("get an integer number (implicit)")
976     {
977         json::number_integer_t n_reference{42};
978         json j(n_reference);
979         json::number_unsigned_t n_unsigned_reference{42u};
980         json j_unsigned(n_unsigned_reference);
981 
982         SECTION("number_integer_t")
983         {
984             json::number_integer_t n = j.get<json::number_integer_t>();
985             CHECK(json(n) == j);
986         }
987 
988         SECTION("number_unsigned_t")
989         {
990             json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
991             CHECK(json(n) == j_unsigned);
992         }
993 
994         SECTION("short")
995         {
996             short n = j;
997             CHECK(json(n) == j);
998         }
999 
1000         SECTION("unsigned short")
1001         {
1002             unsigned short n = j_unsigned;
1003             CHECK(json(n) == j_unsigned);
1004         }
1005 
1006         SECTION("int")
1007         {
1008             int n = j;
1009             CHECK(json(n) == j);
1010         }
1011 
1012         SECTION("unsigned int")
1013         {
1014             unsigned int n = j_unsigned;
1015             CHECK(json(n) == j_unsigned);
1016         }
1017 
1018         SECTION("long")
1019         {
1020             long n = j;
1021             CHECK(json(n) == j);
1022         }
1023 
1024         SECTION("unsigned long")
1025         {
1026             unsigned long n = j_unsigned;
1027             CHECK(json(n) == j_unsigned);
1028         }
1029 
1030         SECTION("long long")
1031         {
1032             long long n = j;
1033             CHECK(json(n) == j);
1034         }
1035 
1036         SECTION("unsigned long long")
1037         {
1038             unsigned long long n = j_unsigned;
1039             CHECK(json(n) == j_unsigned);
1040         }
1041 
1042         SECTION("int8_t")
1043         {
1044             int8_t n = j;
1045             CHECK(json(n) == j);
1046         }
1047 
1048         SECTION("int16_t")
1049         {
1050             int16_t n = j;
1051             CHECK(json(n) == j);
1052         }
1053 
1054         SECTION("int32_t")
1055         {
1056             int32_t n = j;
1057             CHECK(json(n) == j);
1058         }
1059 
1060         SECTION("int64_t")
1061         {
1062             int64_t n = j;
1063             CHECK(json(n) == j);
1064         }
1065 
1066         SECTION("int8_fast_t")
1067         {
1068             int_fast8_t n = j;
1069             CHECK(json(n) == j);
1070         }
1071 
1072         SECTION("int16_fast_t")
1073         {
1074             int_fast16_t n = j;
1075             CHECK(json(n) == j);
1076         }
1077 
1078         SECTION("int32_fast_t")
1079         {
1080             int_fast32_t n = j;
1081             CHECK(json(n) == j);
1082         }
1083 
1084         SECTION("int64_fast_t")
1085         {
1086             int_fast64_t n = j;
1087             CHECK(json(n) == j);
1088         }
1089 
1090         SECTION("int8_least_t")
1091         {
1092             int_least8_t n = j;
1093             CHECK(json(n) == j);
1094         }
1095 
1096         SECTION("int16_least_t")
1097         {
1098             int_least16_t n = j;
1099             CHECK(json(n) == j);
1100         }
1101 
1102         SECTION("int32_least_t")
1103         {
1104             int_least32_t n = j;
1105             CHECK(json(n) == j);
1106         }
1107 
1108         SECTION("int64_least_t")
1109         {
1110             int_least64_t n = j;
1111             CHECK(json(n) == j);
1112         }
1113 
1114         SECTION("uint8_t")
1115         {
1116             uint8_t n = j_unsigned;
1117             CHECK(json(n) == j_unsigned);
1118         }
1119 
1120         SECTION("uint16_t")
1121         {
1122             uint16_t n = j_unsigned;
1123             CHECK(json(n) == j_unsigned);
1124         }
1125 
1126         SECTION("uint32_t")
1127         {
1128             uint32_t n = j_unsigned;
1129             CHECK(json(n) == j_unsigned);
1130         }
1131 
1132         SECTION("uint64_t")
1133         {
1134             uint64_t n = j_unsigned;
1135             CHECK(json(n) == j_unsigned);
1136         }
1137 
1138         SECTION("uint8_fast_t")
1139         {
1140             uint_fast8_t n = j_unsigned;
1141             CHECK(json(n) == j_unsigned);
1142         }
1143 
1144         SECTION("uint16_fast_t")
1145         {
1146             uint_fast16_t n = j_unsigned;
1147             CHECK(json(n) == j_unsigned);
1148         }
1149 
1150         SECTION("uint32_fast_t")
1151         {
1152             uint_fast32_t n = j_unsigned;
1153             CHECK(json(n) == j_unsigned);
1154         }
1155 
1156         SECTION("uint64_fast_t")
1157         {
1158             uint_fast64_t n = j_unsigned;
1159             CHECK(json(n) == j_unsigned);
1160         }
1161 
1162         SECTION("uint8_least_t")
1163         {
1164             uint_least8_t n = j_unsigned;
1165             CHECK(json(n) == j_unsigned);
1166         }
1167 
1168         SECTION("uint16_least_t")
1169         {
1170             uint_least16_t n = j_unsigned;
1171             CHECK(json(n) == j_unsigned);
1172         }
1173 
1174         SECTION("uint32_least_t")
1175         {
1176             uint_least32_t n = j_unsigned;
1177             CHECK(json(n) == j_unsigned);
1178         }
1179 
1180         SECTION("uint64_least_t")
1181         {
1182             uint_least64_t n = j_unsigned;
1183             CHECK(json(n) == j_unsigned);
1184         }
1185     }
1186 #endif
1187 
1188     SECTION("get a floating-point number (explicit)")
1189     {
1190         json::number_float_t n_reference{42.23};
1191         json j(n_reference);
1192 
1193         SECTION("number_float_t")
1194         {
1195             json::number_float_t n = j.get<json::number_float_t>();
1196             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1197         }
1198 
1199         SECTION("float")
1200         {
1201             float n = j.get<float>();
1202             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1203         }
1204 
1205         SECTION("double")
1206         {
1207             double n = j.get<double>();
1208             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1209         }
1210 
1211         SECTION("exception in case of a non-string type")
1212         {
1213             CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(),
1214                             json::type_error&);
1215             CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(),
1216                             json::type_error&);
1217             CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(),
1218                             json::type_error&);
1219             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(),
1220                             json::type_error&);
1221             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(),
1222                             json::type_error&);
1223 
1224             CHECK_THROWS_WITH(
1225                 json(json::value_t::null).get<json::number_float_t>(),
1226                 "[json.exception.type_error.302] type must be number, but is null");
1227             CHECK_THROWS_WITH(
1228                 json(json::value_t::object).get<json::number_float_t>(),
1229                 "[json.exception.type_error.302] type must be number, but is object");
1230             CHECK_THROWS_WITH(
1231                 json(json::value_t::array).get<json::number_float_t>(),
1232                 "[json.exception.type_error.302] type must be number, but is array");
1233             CHECK_THROWS_WITH(
1234                 json(json::value_t::string).get<json::number_float_t>(),
1235                 "[json.exception.type_error.302] type must be number, but is string");
1236             CHECK_THROWS_WITH(
1237                 json(json::value_t::boolean).get<json::number_float_t>(),
1238                 "[json.exception.type_error.302] type must be number, but is "
1239                 "boolean");
1240 
1241             CHECK_NOTHROW(
1242                 json(json::value_t::number_integer).get<json::number_float_t>());
1243             CHECK_NOTHROW(
1244                 json(json::value_t::number_unsigned).get<json::number_float_t>());
1245         }
1246     }
1247 
1248 #if JSON_USE_IMPLICIT_CONVERSIONS
1249     SECTION("get a floating-point number (implicit)")
1250     {
1251         json::number_float_t n_reference{42.23};
1252         json j(n_reference);
1253 
1254         SECTION("number_float_t")
1255         {
1256             json::number_float_t n = j;
1257             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1258         }
1259 
1260         SECTION("float")
1261         {
1262             float n = j;
1263             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1264         }
1265 
1266         SECTION("double")
1267         {
1268             double n = j;
1269             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1270         }
1271     }
1272 #endif
1273 
1274     SECTION("get a binary value (explicit)")
1275     {
1276         json::binary_t n_reference{{1, 2, 3}};
1277         json j(n_reference);
1278 
1279         SECTION("binary_t")
1280         {
1281             json::binary_t b = j.get<json::binary_t>();
1282             CHECK(*json(b).m_value.binary == *j.m_value.binary);
1283         }
1284 
1285         SECTION("get_binary()")
1286         {
1287             SECTION("non-const")
1288             {
1289                 auto& b = j.get_binary();
1290                 CHECK(*json(b).m_value.binary == *j.m_value.binary);
1291             }
1292 
1293             SECTION("non-const")
1294             {
1295                 const json j_const = j;
1296                 const auto& b = j_const.get_binary();
1297                 CHECK(*json(b).m_value.binary == *j.m_value.binary);
1298             }
1299         }
1300 
1301         SECTION("exception in case of a non-string type")
1302         {
1303             json j_null(json::value_t::null);
1304             json j_object(json::value_t::object);
1305             json j_array(json::value_t::array);
1306             json j_string(json::value_t::string);
1307             json j_boolean(json::value_t::boolean);
1308             const json j_null_const(json::value_t::null);
1309             const json j_object_const(json::value_t::object);
1310             const json j_array_const(json::value_t::array);
1311             const json j_string_const(json::value_t::string);
1312             const json j_boolean_const(json::value_t::boolean);
1313 
1314             CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),
1315                                  "[json.exception.type_error.302] type must be binary, but is null",
1316                                  json::type_error&);
1317             CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),
1318                                  "[json.exception.type_error.302] type must be binary, but is object",
1319                                  json::type_error&);
1320             CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),
1321                                  "[json.exception.type_error.302] type must be binary, but is array",
1322                                  json::type_error&);
1323             CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),
1324                                  "[json.exception.type_error.302] type must be binary, but is string",
1325                                  json::type_error&);
1326             CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),
1327                                  "[json.exception.type_error.302] type must be binary, but is boolean",
1328                                  json::type_error&);
1329 
1330             CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),
1331                                  "[json.exception.type_error.302] type must be binary, but is null",
1332                                  json::type_error&);
1333             CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),
1334                                  "[json.exception.type_error.302] type must be binary, but is object",
1335                                  json::type_error&);
1336             CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),
1337                                  "[json.exception.type_error.302] type must be binary, but is array",
1338                                  json::type_error&);
1339             CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),
1340                                  "[json.exception.type_error.302] type must be binary, but is string",
1341                                  json::type_error&);
1342             CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
1343                                  "[json.exception.type_error.302] type must be binary, but is boolean",
1344                                  json::type_error&);
1345 
1346             CHECK_THROWS_WITH_AS(j_null.get_binary(),
1347                                  "[json.exception.type_error.302] type must be binary, but is null",
1348                                  json::type_error&);
1349             CHECK_THROWS_WITH_AS(j_object.get_binary(),
1350                                  "[json.exception.type_error.302] type must be binary, but is object",
1351                                  json::type_error&);
1352             CHECK_THROWS_WITH_AS(j_array.get_binary(),
1353                                  "[json.exception.type_error.302] type must be binary, but is array",
1354                                  json::type_error&);
1355             CHECK_THROWS_WITH_AS(j_string.get_binary(),
1356                                  "[json.exception.type_error.302] type must be binary, but is string",
1357                                  json::type_error&);
1358             CHECK_THROWS_WITH_AS(j_boolean.get_binary(),
1359                                  "[json.exception.type_error.302] type must be binary, but is boolean",
1360                                  json::type_error&);
1361 
1362             CHECK_THROWS_WITH_AS(j_null_const.get_binary(),
1363                                  "[json.exception.type_error.302] type must be binary, but is null",
1364                                  json::type_error&);
1365             CHECK_THROWS_WITH_AS(j_object_const.get_binary(),
1366                                  "[json.exception.type_error.302] type must be binary, but is object",
1367                                  json::type_error&);
1368             CHECK_THROWS_WITH_AS(j_array_const.get_binary(),
1369                                  "[json.exception.type_error.302] type must be binary, but is array",
1370                                  json::type_error&);
1371             CHECK_THROWS_WITH_AS(j_string_const.get_binary(),
1372                                  "[json.exception.type_error.302] type must be binary, but is string",
1373                                  json::type_error&);
1374             CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),
1375                                  "[json.exception.type_error.302] type must be binary, but is boolean",
1376                                  json::type_error&);
1377         }
1378     }
1379 
1380 #if JSON_USE_IMPLICIT_CONVERSIONS
1381     SECTION("get a binary value (implicit)")
1382     {
1383         json::binary_t n_reference{{1, 2, 3}};
1384         json j(n_reference);
1385 
1386         SECTION("binary_t")
1387         {
1388             json::binary_t b = j;
1389             CHECK(*json(b).m_value.binary == *j.m_value.binary);
1390         }
1391     }
1392 #endif
1393 
1394     SECTION("get an enum")
1395     {
1396         enum c_enum { value_1, value_2 };
1397         enum class cpp_enum { value_1, value_2 };
1398 
1399         CHECK(json(value_1).get<c_enum>() == value_1);
1400         CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
1401     }
1402 
1403     SECTION("more involved conversions")
1404     {
1405         SECTION("object-like STL containers")
1406         {
1407             json j1 = {{"one", 1}, {"two", 2}, {"three", 3}};
1408             json j2 = {{"one", 1u}, {"two", 2u}, {"three", 3u}};
1409             json j3 = {{"one", 1.1}, {"two", 2.2}, {"three", 3.3}};
1410             json j4 = {{"one", true}, {"two", false}, {"three", true}};
1411             json j5 = {{"one", "eins"}, {"two", "zwei"}, {"three", "drei"}};
1412 
1413             SECTION("std::map")
1414             {
1415                 j1.get<std::map<std::string, int>>();
1416                 j2.get<std::map<std::string, unsigned int>>();
1417                 j3.get<std::map<std::string, double>>();
1418                 j4.get<std::map<std::string, bool>>();
1419                 j5.get<std::map<std::string, std::string>>();
1420             }
1421 
1422             SECTION("std::unordered_map")
1423             {
1424                 j1.get<std::unordered_map<std::string, int>>();
1425                 j2.get<std::unordered_map<std::string, unsigned int>>();
1426                 j3.get<std::unordered_map<std::string, double>>();
1427                 j4.get<std::unordered_map<std::string, bool>>();
1428                 j5.get<std::unordered_map<std::string, std::string>>();
1429                 // CHECK(m5["one"] == "eins");
1430             }
1431 
1432             SECTION("std::multimap")
1433             {
1434                 j1.get<std::multimap<std::string, int>>();
1435                 j2.get<std::multimap<std::string, unsigned int>>();
1436                 j3.get<std::multimap<std::string, double>>();
1437                 j4.get<std::multimap<std::string, bool>>();
1438                 j5.get<std::multimap<std::string, std::string>>();
1439                 // CHECK(m5["one"] == "eins");
1440             }
1441 
1442             SECTION("std::unordered_multimap")
1443             {
1444                 j1.get<std::unordered_multimap<std::string, int>>();
1445                 j2.get<std::unordered_multimap<std::string, unsigned int>>();
1446                 j3.get<std::unordered_multimap<std::string, double>>();
1447                 j4.get<std::unordered_multimap<std::string, bool>>();
1448                 j5.get<std::unordered_multimap<std::string, std::string>>();
1449                 // CHECK(m5["one"] == "eins");
1450             }
1451 
1452             SECTION("exception in case of a non-object type")
1453             {
1454                 CHECK_THROWS_AS((json().get<std::map<std::string, int>>()),
1455                                 json::type_error&);
1456                 CHECK_THROWS_WITH(
1457                     (json().get<std::map<std::string, int>>()),
1458                     "[json.exception.type_error.302] type must be object, but is null");
1459             }
1460         }
1461 
1462         SECTION("array-like STL containers")
1463         {
1464             json j1 = {1, 2, 3, 4};
1465             json j2 = {1u, 2u, 3u, 4u};
1466             json j3 = {1.2, 2.3, 3.4, 4.5};
1467             json j4 = {true, false, true};
1468             json j5 = {"one", "two", "three"};
1469 
1470             SECTION("std::list")
1471             {
1472                 j1.get<std::list<int>>();
1473                 j2.get<std::list<unsigned int>>();
1474                 j3.get<std::list<double>>();
1475                 j4.get<std::list<bool>>();
1476                 j5.get<std::list<std::string>>();
1477             }
1478 
1479             SECTION("std::forward_list")
1480             {
1481                 j1.get<std::forward_list<int>>();
1482                 j2.get<std::forward_list<unsigned int>>();
1483                 j3.get<std::forward_list<double>>();
1484                 j4.get<std::forward_list<bool>>();
1485                 j5.get<std::forward_list<std::string>>();
1486             }
1487 
1488             SECTION("std::array")
1489             {
1490                 j1.get<std::array<int, 4>>();
1491                 j2.get<std::array<unsigned int, 3>>();
1492                 j3.get<std::array<double, 4>>();
1493                 j4.get<std::array<bool, 3>>();
1494                 j5.get<std::array<std::string, 3>>();
1495 
1496                 SECTION("std::array is larger than JSON")
1497                 {
1498                     std::array<int, 6> arr6 = {{1, 2, 3, 4, 5, 6}};
1499                     CHECK_THROWS_AS(j1.get_to(arr6), json::out_of_range&);
1500                     CHECK_THROWS_WITH(j1.get_to(arr6), "[json.exception.out_of_range.401] "
1501                                       "array index 4 is out of range");
1502                 }
1503 
1504                 SECTION("std::array is smaller than JSON")
1505                 {
1506                     std::array<int, 2> arr2 = {{8, 9}};
1507                     j1.get_to(arr2);
1508                     CHECK(arr2[0] == 1);
1509                     CHECK(arr2[1] == 2);
1510                 }
1511             }
1512 
1513             SECTION("std::valarray")
1514             {
1515                 j1.get<std::valarray<int>>();
1516                 j2.get<std::valarray<unsigned int>>();
1517                 j3.get<std::valarray<double>>();
1518                 j4.get<std::valarray<bool>>();
1519                 j5.get<std::valarray<std::string>>();
1520             }
1521 
1522             SECTION("std::vector")
1523             {
1524                 j1.get<std::vector<int>>();
1525                 j2.get<std::vector<unsigned int>>();
1526                 j3.get<std::vector<double>>();
1527                 j4.get<std::vector<bool>>();
1528                 j5.get<std::vector<std::string>>();
1529             }
1530 
1531             SECTION("std::deque")
1532             {
1533                 j1.get<std::deque<int>>();
1534                 j2.get<std::deque<unsigned int>>();
1535                 j2.get<std::deque<double>>();
1536                 j4.get<std::deque<bool>>();
1537                 j5.get<std::deque<std::string>>();
1538             }
1539 
1540             SECTION("std::set")
1541             {
1542                 j1.get<std::set<int>>();
1543                 j2.get<std::set<unsigned int>>();
1544                 j3.get<std::set<double>>();
1545                 j4.get<std::set<bool>>();
1546                 j5.get<std::set<std::string>>();
1547             }
1548 
1549             SECTION("std::unordered_set")
1550             {
1551                 j1.get<std::unordered_set<int>>();
1552                 j2.get<std::unordered_set<unsigned int>>();
1553                 j3.get<std::unordered_set<double>>();
1554                 j4.get<std::unordered_set<bool>>();
1555                 j5.get<std::unordered_set<std::string>>();
1556             }
1557 
1558             SECTION("std::map (array of pairs)")
1559             {
1560                 std::map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
1561                 json j6 = m;
1562 
1563                 auto m2 = j6.get<std::map<int, int>>();
1564                 CHECK(m == m2);
1565 
1566                 json j7 = {0, 1, 2, 3};
1567                 json j8 = 2;
1568                 CHECK_THROWS_AS((j7.get<std::map<int, int>>()), json::type_error&);
1569                 CHECK_THROWS_AS((j8.get<std::map<int, int>>()), json::type_error&);
1570                 CHECK_THROWS_WITH((j7.get<std::map<int, int>>()),
1571                                   "[json.exception.type_error.302] type must be array, "
1572                                   "but is number");
1573                 CHECK_THROWS_WITH((j8.get<std::map<int, int>>()),
1574                                   "[json.exception.type_error.302] type must be array, "
1575                                   "but is number");
1576 
1577                 SECTION("superfluous entries")
1578                 {
1579                     json j9 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
1580                     m2 = j9.get<std::map<int, int>>();
1581                     CHECK(m == m2);
1582                 }
1583             }
1584 
1585             SECTION("std::unordered_map (array of pairs)")
1586             {
1587                 std::unordered_map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
1588                 json j6 = m;
1589 
1590                 auto m2 = j6.get<std::unordered_map<int, int>>();
1591                 CHECK(m == m2);
1592 
1593                 json j7 = {0, 1, 2, 3};
1594                 json j8 = 2;
1595                 CHECK_THROWS_AS((j7.get<std::unordered_map<int, int>>()), json::type_error&);
1596                 CHECK_THROWS_AS((j8.get<std::unordered_map<int, int>>()), json::type_error&);
1597                 CHECK_THROWS_WITH((j7.get<std::unordered_map<int, int>>()),
1598                                   "[json.exception.type_error.302] type must be array, "
1599                                   "but is number");
1600                 CHECK_THROWS_WITH((j8.get<std::unordered_map<int, int>>()),
1601                                   "[json.exception.type_error.302] type must be array, "
1602                                   "but is number");
1603 
1604                 SECTION("superfluous entries")
1605                 {
1606                     json j9{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
1607                     m2 = j9.get<std::unordered_map<int, int>>();
1608                     CHECK(m == m2);
1609                 }
1610             }
1611 
1612             SECTION("exception in case of a non-object type")
1613             {
1614                 CHECK_THROWS_AS((json().get<std::list<int>>()), json::type_error&);
1615                 CHECK_THROWS_AS((json().get<std::vector<int>>()), json::type_error&);
1616                 CHECK_THROWS_AS((json().get<std::vector<json>>()), json::type_error&);
1617                 CHECK_THROWS_AS((json().get<std::list<json>>()), json::type_error&);
1618                 CHECK_THROWS_AS((json().get<std::valarray<int>>()), json::type_error&);
1619 
1620                 // does type really must be an array? or it rather must not be null?
1621                 // that's what I thought when other test like this one broke
1622                 CHECK_THROWS_WITH(
1623                     (json().get<std::list<int>>()),
1624                     "[json.exception.type_error.302] type must be array, but is null");
1625                 CHECK_THROWS_WITH(
1626                     (json().get<std::vector<int>>()),
1627                     "[json.exception.type_error.302] type must be array, but is null");
1628                 CHECK_THROWS_WITH(
1629                     (json().get<std::vector<json>>()),
1630                     "[json.exception.type_error.302] type must be array, but is null");
1631                 CHECK_THROWS_WITH(
1632                     (json().get<std::list<json>>()),
1633                     "[json.exception.type_error.302] type must be array, but is null");
1634                 CHECK_THROWS_WITH(
1635                     (json().get<std::valarray<int>>()),
1636                     "[json.exception.type_error.302] type must be array, but is null");
1637                 CHECK_THROWS_WITH(
1638                     (json().get<std::map<int, int>>()),
1639                     "[json.exception.type_error.302] type must be array, but is null");
1640             }
1641         }
1642     }
1643 }
1644 
1645 enum class cards {kreuz, pik, herz, karo};
1646 
1647 NLOHMANN_JSON_SERIALIZE_ENUM(cards,
1648 {
1649     {cards::kreuz, "kreuz"},
1650     {cards::pik, "pik"},
1651     {cards::pik, "puk"},  // second entry for cards::puk; will not be used
1652     {cards::herz, "herz"},
1653     {cards::karo, "karo"}
1654 })
1655 
1656 enum TaskState
1657 {
1658     TS_STOPPED,
1659     TS_RUNNING,
1660     TS_COMPLETED,
1661     TS_INVALID = -1,
1662 };
1663 
1664 NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
1665 {
1666     {TS_INVALID, nullptr},
1667     {TS_STOPPED, "stopped"},
1668     {TS_RUNNING, "running"},
1669     {TS_COMPLETED, "completed"},
1670 })
1671 
1672 TEST_CASE("JSON to enum mapping")
1673 {
1674     SECTION("enum class")
1675     {
1676         // enum -> json
1677         CHECK(json(cards::kreuz) == "kreuz");
1678         CHECK(json(cards::pik) == "pik");
1679         CHECK(json(cards::herz) == "herz");
1680         CHECK(json(cards::karo) == "karo");
1681 
1682         // json -> enum
1683         CHECK(cards::kreuz == json("kreuz"));
1684         CHECK(cards::pik == json("pik"));
1685         CHECK(cards::herz == json("herz"));
1686         CHECK(cards::karo == json("karo"));
1687 
1688         // invalid json -> first enum
1689         CHECK(cards::kreuz == json("what?").get<cards>());
1690     }
1691 
1692     SECTION("traditional enum")
1693     {
1694         // enum -> json
1695         CHECK(json(TS_STOPPED) == "stopped");
1696         CHECK(json(TS_RUNNING) == "running");
1697         CHECK(json(TS_COMPLETED) == "completed");
1698         CHECK(json(TS_INVALID) == json());
1699 
1700         // json -> enum
1701         CHECK(TS_STOPPED == json("stopped"));
1702         CHECK(TS_RUNNING == json("running"));
1703         CHECK(TS_COMPLETED == json("completed"));
1704         CHECK(TS_INVALID == json());
1705 
1706         // invalid json -> first enum
1707         CHECK(TS_INVALID == json("what?").get<TaskState>());
1708     }
1709 }
1710