• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.7.3
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 
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 
235     SECTION("get an array (explicit)")
236     {
237         json::array_t a_reference{json(1),     json(1u),       json(2.2),
238                                   json(false), json("string"), json()};
239         json j(a_reference);
240 
241         SECTION("json::array_t")
242         {
243             json::array_t a = j.get<json::array_t>();
244             CHECK(json(a) == j);
245         }
246 
247         SECTION("std::list<json>")
248         {
249             std::list<json> a = j.get<std::list<json>>();
250             CHECK(json(a) == j);
251         }
252 
253         SECTION("std::forward_list<json>")
254         {
255             std::forward_list<json> a = j.get<std::forward_list<json>>();
256             CHECK(json(a) == j);
257 
258             CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(),
259                             json::type_error&);
260             CHECK_THROWS_WITH(
261                 json(json::value_t::null).get<std::forward_list<json>>(),
262                 "[json.exception.type_error.302] type must be array, but is null");
263         }
264 
265         SECTION("std::vector<json>")
266         {
267             std::vector<json> a = j.get<std::vector<json>>();
268             CHECK(json(a) == j);
269 
270             CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(),
271                             json::type_error&);
272             CHECK_THROWS_WITH(
273                 json(json::value_t::null).get<std::vector<json>>(),
274                 "[json.exception.type_error.302] type must be array, but is null");
275 
276 #if not defined(JSON_NOEXCEPTION)
277             SECTION("reserve is called on containers that supports it")
278             {
279                 // make sure all values are properly copied
280                 std::vector<int> v2 = json({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
281                 CHECK(v2.size() == 10);
282             }
283 #endif
284         }
285 
286         SECTION("built-in arrays")
287         {
288             const char str[] = "a string";
289             const int nbs[] = {0, 1, 2};
290 
291             json j2 = nbs;
292             json j3 = str;
293 
294             auto v = j2.get<std::vector<int>>();
295             auto s = j3.get<std::string>();
296             CHECK(std::equal(v.begin(), v.end(), std::begin(nbs)));
297             CHECK(s == str);
298         }
299 
300         SECTION("std::deque<json>")
301         {
302             std::deque<json> a = j.get<std::deque<json>>();
303             CHECK(json(a) == j);
304         }
305 
306         SECTION("exception in case of a non-array type")
307         {
308             CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(),
309                             json::type_error&);
310             CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(),
311                             json::type_error&);
312             CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(),
313                             json::type_error&);
314             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(),
315                             json::type_error&);
316             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(),
317                             json::type_error&);
318             CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(),
319                             json::type_error&);
320             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(),
321                             json::type_error&);
322 
323             CHECK_THROWS_WITH(
324                 json(json::value_t::object).get<std::vector<int>>(),
325                 "[json.exception.type_error.302] type must be array, but is object");
326             CHECK_THROWS_WITH(
327                 json(json::value_t::null).get<json::array_t>(),
328                 "[json.exception.type_error.302] type must be array, but is null");
329             CHECK_THROWS_WITH(
330                 json(json::value_t::object).get<json::array_t>(),
331                 "[json.exception.type_error.302] type must be array, but is object");
332             CHECK_THROWS_WITH(
333                 json(json::value_t::string).get<json::array_t>(),
334                 "[json.exception.type_error.302] type must be array, but is string");
335             CHECK_THROWS_WITH(
336                 json(json::value_t::boolean).get<json::array_t>(),
337                 "[json.exception.type_error.302] type must be array, but is boolean");
338             CHECK_THROWS_WITH(
339                 json(json::value_t::number_integer).get<json::array_t>(),
340                 "[json.exception.type_error.302] type must be array, but is number");
341             CHECK_THROWS_WITH(
342                 json(json::value_t::number_unsigned).get<json::array_t>(),
343                 "[json.exception.type_error.302] type must be array, but is number");
344             CHECK_THROWS_WITH(
345                 json(json::value_t::number_float).get<json::array_t>(),
346                 "[json.exception.type_error.302] type must be array, but is number");
347         }
348     }
349 
350     SECTION("get an array (explicit, get_to)")
351     {
352         json::array_t a_reference{json(1),     json(1u),       json(2.2),
353                                   json(false), json("string"), json()};
354         json j(a_reference);
355 
356         SECTION("json::array_t")
357         {
358             json::array_t a{"previous", "value"};
359             j.get_to(a);
360             CHECK(json(a) == j);
361         }
362 
363         SECTION("std::valarray<json>")
364         {
365             std::valarray<json> a{"previous", "value"};
366             j.get_to(a);
367             CHECK(json(a) == j);
368         }
369 
370         SECTION("std::list<json>")
371         {
372             std::list<json> a{"previous", "value"};
373             j.get_to(a);
374             CHECK(json(a) == j);
375         }
376 
377         SECTION("std::forward_list<json>")
378         {
379             std::forward_list<json> a{"previous", "value"};
380             j.get_to(a);
381             CHECK(json(a) == j);
382         }
383 
384         SECTION("std::vector<json>")
385         {
386             std::vector<json> a{"previous", "value"};
387             j.get_to(a);
388             CHECK(json(a) == j);
389         }
390 
391         SECTION("built-in arrays")
392         {
393             const int nbs[] = {0, 1, 2};
394             int nbs2[] = {0, 0, 0};
395 
396             json j2 = nbs;
397             j2.get_to(nbs2);
398             CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2)));
399         }
400 
401         SECTION("std::deque<json>")
402         {
403             std::deque<json> a{"previous", "value"};
404             j.get_to(a);
405             CHECK(json(a) == j);
406         }
407     }
408 
409     SECTION("get an array (implicit)")
410     {
411         json::array_t a_reference{json(1),     json(1u),       json(2.2),
412                                   json(false), json("string"), json()};
413         json j(a_reference);
414 
415         SECTION("json::array_t")
416         {
417             json::array_t a = j;
418             CHECK(json(a) == j);
419         }
420 
421         SECTION("std::list<json>")
422         {
423             std::list<json> a = j;
424             CHECK(json(a) == j);
425         }
426 
427         SECTION("std::forward_list<json>")
428         {
429             std::forward_list<json> a = j;
430             CHECK(json(a) == j);
431         }
432 
433         SECTION("std::vector<json>")
434         {
435             std::vector<json> a = j;
436             CHECK(json(a) == j);
437         }
438 
439         SECTION("std::deque<json>")
440         {
441             std::deque<json> a = j;
442             CHECK(json(a) == j);
443         }
444     }
445 
446     SECTION("get a string (explicit)")
447     {
448         json::string_t s_reference{"Hello world"};
449         json j(s_reference);
450 
451         SECTION("string_t")
452         {
453             json::string_t s = j.get<json::string_t>();
454             CHECK(json(s) == j);
455         }
456 
457         SECTION("std::string")
458         {
459             std::string s = j.get<std::string>();
460             CHECK(json(s) == j);
461         }
462 #if defined(JSON_HAS_CPP_17)
463         SECTION("std::string_view")
464         {
465             std::string_view s = j.get<std::string_view>();
466             CHECK(json(s) == j);
467         }
468 #endif
469 
470         SECTION("exception in case of a non-string type")
471         {
472             CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(),
473                             json::type_error&);
474             CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(),
475                             json::type_error&);
476             CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(),
477                             json::type_error&);
478             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(),
479                             json::type_error&);
480             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(),
481                             json::type_error&);
482             CHECK_THROWS_AS(
483                 json(json::value_t::number_unsigned).get<json::string_t>(),
484                 json::type_error&);
485             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(),
486                             json::type_error&);
487 
488             CHECK_THROWS_WITH(
489                 json(json::value_t::null).get<json::string_t>(),
490                 "[json.exception.type_error.302] type must be string, but is null");
491             CHECK_THROWS_WITH(
492                 json(json::value_t::object).get<json::string_t>(),
493                 "[json.exception.type_error.302] type must be string, but is object");
494             CHECK_THROWS_WITH(
495                 json(json::value_t::array).get<json::string_t>(),
496                 "[json.exception.type_error.302] type must be string, but is array");
497             CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
498                               "[json.exception.type_error.302] type must be string, "
499                               "but is boolean");
500             CHECK_THROWS_WITH(
501                 json(json::value_t::number_integer).get<json::string_t>(),
502                 "[json.exception.type_error.302] type must be string, but is number");
503             CHECK_THROWS_WITH(
504                 json(json::value_t::number_unsigned).get<json::string_t>(),
505                 "[json.exception.type_error.302] type must be string, but is number");
506             CHECK_THROWS_WITH(
507                 json(json::value_t::number_float).get<json::string_t>(),
508                 "[json.exception.type_error.302] type must be string, but is number");
509         }
510 
511 #if defined(JSON_HAS_CPP_17)
512         SECTION("exception in case of a non-string type using string_view")
513         {
514             CHECK_THROWS_AS(json(json::value_t::null).get<std::string_view>(), json::type_error&);
515             CHECK_THROWS_AS(json(json::value_t::object).get<std::string_view>(), json::type_error&);
516             CHECK_THROWS_AS(json(json::value_t::array).get<std::string_view>(), json::type_error&);
517             CHECK_THROWS_AS(json(json::value_t::boolean).get<std::string_view>(), json::type_error&);
518             CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::string_view>(), json::type_error&);
519             CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::string_view>(), json::type_error&);
520             CHECK_THROWS_AS(json(json::value_t::number_float).get<std::string_view>(), json::type_error&);
521 
522             CHECK_THROWS_WITH(json(json::value_t::null).get<std::string_view>(),
523                               "[json.exception.type_error.302] type must be string, but is null");
524             CHECK_THROWS_WITH(json(json::value_t::object).get<std::string_view>(),
525                               "[json.exception.type_error.302] type must be string, but is object");
526             CHECK_THROWS_WITH(json(json::value_t::array).get<std::string_view>(),
527                               "[json.exception.type_error.302] type must be string, but is array");
528             CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::string_view>(),
529                               "[json.exception.type_error.302] type must be string, but is boolean");
530             CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::string_view>(),
531                               "[json.exception.type_error.302] type must be string, but is number");
532             CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::string_view>(),
533                               "[json.exception.type_error.302] type must be string, but is number");
534             CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::string_view>(),
535                               "[json.exception.type_error.302] type must be string, but is number");
536         }
537 #endif
538     }
539 
540     SECTION("get a string (explicit, get_to)")
541     {
542         json::string_t s_reference{"Hello world"};
543         json j(s_reference);
544 
545         SECTION("string_t")
546         {
547             json::string_t s = "previous value";
548             j.get_to(s);
549             CHECK(json(s) == j);
550         }
551 
552         SECTION("std::string")
553         {
554             std::string s = "previous value";
555             j.get_to(s);
556             CHECK(json(s) == j);
557         }
558 #if defined(JSON_HAS_CPP_17)
559         SECTION("std::string_view")
560         {
561             std::string s = "previous value";
562             std::string_view sv = s;
563             j.get_to(sv);
564             CHECK(json(sv) == j);
565         }
566 #endif
567     }
568 
569     SECTION("get null (explicit)")
570     {
571         std::nullptr_t n = nullptr;
572         json j(n);
573 
574         auto n2 = j.get<std::nullptr_t>();
575         CHECK(n2 == n);
576 
577         CHECK_THROWS_AS(json(json::value_t::string).get<std::nullptr_t>(), json::type_error&);
578         CHECK_THROWS_AS(json(json::value_t::object).get<std::nullptr_t>(), json::type_error&);
579         CHECK_THROWS_AS(json(json::value_t::array).get<std::nullptr_t>(), json::type_error&);
580         CHECK_THROWS_AS(json(json::value_t::boolean).get<std::nullptr_t>(), json::type_error&);
581         CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::nullptr_t>(), json::type_error&);
582         CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(), json::type_error&);
583         CHECK_THROWS_AS(json(json::value_t::number_float).get<std::nullptr_t>(), json::type_error&);
584 
585         CHECK_THROWS_WITH(json(json::value_t::string).get<std::nullptr_t>(),
586                           "[json.exception.type_error.302] type must be null, but is string");
587         CHECK_THROWS_WITH(json(json::value_t::object).get<std::nullptr_t>(),
588                           "[json.exception.type_error.302] type must be null, but is object");
589         CHECK_THROWS_WITH(json(json::value_t::array).get<std::nullptr_t>(),
590                           "[json.exception.type_error.302] type must be null, but is array");
591         CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::nullptr_t>(),
592                           "[json.exception.type_error.302] type must be null, but is boolean");
593         CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::nullptr_t>(),
594                           "[json.exception.type_error.302] type must be null, but is number");
595         CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::nullptr_t>(),
596                           "[json.exception.type_error.302] type must be null, but is number");
597         CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::nullptr_t>(),
598                           "[json.exception.type_error.302] type must be null, but is number");
599 
600     }
601 
602     SECTION("get a string (implicit)")
603     {
604         json::string_t s_reference{"Hello world"};
605         json j(s_reference);
606 
607         SECTION("string_t")
608         {
609             json::string_t s = j;
610             CHECK(json(s) == j);
611         }
612 
613 #if defined(JSON_HAS_CPP_17)
614         SECTION("std::string_view")
615         {
616             std::string_view s = j.get<std::string_view>();
617             CHECK(json(s) == j);
618         }
619 #endif
620 
621         SECTION("std::string")
622         {
623             std::string s = j;
624             CHECK(json(s) == j);
625         }
626     }
627 
628     SECTION("get a boolean (explicit)")
629     {
630         json::boolean_t b_reference{true};
631         json j(b_reference);
632 
633         SECTION("boolean_t")
634         {
635             json::boolean_t b = j.get<json::boolean_t>();
636             CHECK(json(b) == j);
637         }
638 
639         SECTION("uint8_t")
640         {
641             auto n = j.get<uint8_t>();
642             CHECK(n == 1);
643         }
644 
645         SECTION("bool")
646         {
647             bool b = j.get<bool>();
648             CHECK(json(b) == j);
649         }
650 
651         SECTION("exception in case of a non-number type")
652         {
653             CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(),
654                             json::type_error&);
655             CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(),
656                             json::type_error&);
657             CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(),
658                             json::type_error&);
659             CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(),
660                             json::type_error&);
661             CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(),
662                             json::type_error&);
663             CHECK_THROWS_AS(
664                 json(json::value_t::number_integer).get<json::boolean_t>(),
665                 json::type_error&);
666             CHECK_THROWS_AS(
667                 json(json::value_t::number_unsigned).get<json::boolean_t>(),
668                 json::type_error&);
669             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(),
670                             json::type_error&);
671 
672             CHECK_THROWS_WITH(
673                 json(json::value_t::null).get<json::boolean_t>(),
674                 "[json.exception.type_error.302] type must be boolean, but is null");
675             CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
676                               "[json.exception.type_error.302] type must be boolean, "
677                               "but is object");
678             CHECK_THROWS_WITH(
679                 json(json::value_t::array).get<json::boolean_t>(),
680                 "[json.exception.type_error.302] type must be boolean, but is array");
681             CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
682                               "[json.exception.type_error.302] type must be boolean, "
683                               "but is string");
684             CHECK_THROWS_WITH(
685                 json(json::value_t::number_integer).get<json::boolean_t>(),
686                 "[json.exception.type_error.302] type must be boolean, but is "
687                 "number");
688             CHECK_THROWS_WITH(
689                 json(json::value_t::number_unsigned).get<json::boolean_t>(),
690                 "[json.exception.type_error.302] type must be boolean, but is "
691                 "number");
692             CHECK_THROWS_WITH(
693                 json(json::value_t::number_float).get<json::boolean_t>(),
694                 "[json.exception.type_error.302] type must be boolean, but is "
695                 "number");
696         }
697     }
698 
699     SECTION("get a boolean (implicit)")
700     {
701         json::boolean_t b_reference{true};
702         json j(b_reference);
703 
704         SECTION("boolean_t")
705         {
706             json::boolean_t b = j;
707             CHECK(json(b) == j);
708         }
709 
710         SECTION("bool")
711         {
712             bool b = j;
713             CHECK(json(b) == j);
714         }
715     }
716 
717     SECTION("get an integer number (explicit)")
718     {
719         json::number_integer_t n_reference{42};
720         json j(n_reference);
721         json::number_unsigned_t n_unsigned_reference{42u};
722         json j_unsigned(n_unsigned_reference);
723 
724         SECTION("number_integer_t")
725         {
726             json::number_integer_t n = j.get<json::number_integer_t>();
727             CHECK(json(n) == j);
728         }
729 
730         SECTION("number_unsigned_t")
731         {
732             json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
733             CHECK(json(n) == j_unsigned);
734         }
735 
736         SECTION("short")
737         {
738             short n = j.get<short>();
739             CHECK(json(n) == j);
740         }
741 
742         SECTION("unsigned short")
743         {
744             unsigned short n = j.get<unsigned short>();
745             CHECK(json(n) == j);
746         }
747 
748         SECTION("int")
749         {
750             int n = j.get<int>();
751             CHECK(json(n) == j);
752         }
753 
754         SECTION("unsigned int")
755         {
756             unsigned int n = j.get<unsigned int>();
757             CHECK(json(n) == j);
758         }
759 
760         SECTION("long")
761         {
762             long n = j.get<long>();
763             CHECK(json(n) == j);
764         }
765 
766         SECTION("unsigned long")
767         {
768             unsigned long n = j.get<unsigned long>();
769             CHECK(json(n) == j);
770         }
771 
772         SECTION("long long")
773         {
774             long long n = j.get<long long>();
775             CHECK(json(n) == j);
776         }
777 
778         SECTION("unsigned long long")
779         {
780             unsigned long long n = j.get<unsigned long long>();
781             CHECK(json(n) == j);
782         }
783 
784         SECTION("int8_t")
785         {
786             int8_t n = j.get<int8_t>();
787             CHECK(json(n) == j);
788         }
789 
790         SECTION("int16_t")
791         {
792             int16_t n = j.get<int16_t>();
793             CHECK(json(n) == j);
794         }
795 
796         SECTION("int32_t")
797         {
798             int32_t n = j.get<int32_t>();
799             CHECK(json(n) == j);
800         }
801 
802         SECTION("int64_t")
803         {
804             int64_t n = j.get<int64_t>();
805             CHECK(json(n) == j);
806         }
807 
808         SECTION("int8_fast_t")
809         {
810             int_fast8_t n = j.get<int_fast8_t>();
811             CHECK(json(n) == j);
812         }
813 
814         SECTION("int16_fast_t")
815         {
816             int_fast16_t n = j.get<int_fast16_t>();
817             CHECK(json(n) == j);
818         }
819 
820         SECTION("int32_fast_t")
821         {
822             int_fast32_t n = j.get<int_fast32_t>();
823             CHECK(json(n) == j);
824         }
825 
826         SECTION("int64_fast_t")
827         {
828             int_fast64_t n = j.get<int_fast64_t>();
829             CHECK(json(n) == j);
830         }
831 
832         SECTION("int8_least_t")
833         {
834             int_least8_t n = j.get<int_least8_t>();
835             CHECK(json(n) == j);
836         }
837 
838         SECTION("int16_least_t")
839         {
840             int_least16_t n = j.get<int_least16_t>();
841             CHECK(json(n) == j);
842         }
843 
844         SECTION("int32_least_t")
845         {
846             int_least32_t n = j.get<int_least32_t>();
847             CHECK(json(n) == j);
848         }
849 
850         SECTION("int64_least_t")
851         {
852             int_least64_t n = j.get<int_least64_t>();
853             CHECK(json(n) == j);
854         }
855 
856         SECTION("uint8_t")
857         {
858             uint8_t n = j.get<uint8_t>();
859             CHECK(json(n) == j);
860         }
861 
862         SECTION("uint16_t")
863         {
864             uint16_t n = j.get<uint16_t>();
865             CHECK(json(n) == j);
866         }
867 
868         SECTION("uint32_t")
869         {
870             uint32_t n = j.get<uint32_t>();
871             CHECK(json(n) == j);
872         }
873 
874         SECTION("uint64_t")
875         {
876             uint64_t n = j.get<uint64_t>();
877             CHECK(json(n) == j);
878         }
879 
880         SECTION("uint8_fast_t")
881         {
882             uint_fast8_t n = j.get<uint_fast8_t>();
883             CHECK(json(n) == j);
884         }
885 
886         SECTION("uint16_fast_t")
887         {
888             uint_fast16_t n = j.get<uint_fast16_t>();
889             CHECK(json(n) == j);
890         }
891 
892         SECTION("uint32_fast_t")
893         {
894             uint_fast32_t n = j.get<uint_fast32_t>();
895             CHECK(json(n) == j);
896         }
897 
898         SECTION("uint64_fast_t")
899         {
900             uint_fast64_t n = j.get<uint_fast64_t>();
901             CHECK(json(n) == j);
902         }
903 
904         SECTION("uint8_least_t")
905         {
906             uint_least8_t n = j.get<uint_least8_t>();
907             CHECK(json(n) == j);
908         }
909 
910         SECTION("uint16_least_t")
911         {
912             uint_least16_t n = j.get<uint_least16_t>();
913             CHECK(json(n) == j);
914         }
915 
916         SECTION("uint32_least_t")
917         {
918             uint_least32_t n = j.get<uint_least32_t>();
919             CHECK(json(n) == j);
920         }
921 
922         SECTION("uint64_least_t")
923         {
924             uint_least64_t n = j.get<uint_least64_t>();
925             CHECK(json(n) == j);
926         }
927 
928         SECTION("exception in case of a non-number type")
929         {
930             CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(),
931                             json::type_error&);
932             CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(),
933                             json::type_error&);
934             CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(),
935                             json::type_error&);
936             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(),
937                             json::type_error&);
938             CHECK_THROWS_AS(
939                 json(json::value_t::boolean).get<json::number_integer_t>(),
940                 json::type_error&);
941 
942             CHECK_THROWS_WITH(
943                 json(json::value_t::null).get<json::number_integer_t>(),
944                 "[json.exception.type_error.302] type must be number, but is null");
945             CHECK_THROWS_WITH(
946                 json(json::value_t::object).get<json::number_integer_t>(),
947                 "[json.exception.type_error.302] type must be number, but is object");
948             CHECK_THROWS_WITH(
949                 json(json::value_t::array).get<json::number_integer_t>(),
950                 "[json.exception.type_error.302] type must be number, but is array");
951             CHECK_THROWS_WITH(
952                 json(json::value_t::string).get<json::number_integer_t>(),
953                 "[json.exception.type_error.302] type must be number, but is string");
954             CHECK_THROWS_WITH(
955                 json(json::value_t::boolean).get<json::number_integer_t>(),
956                 "[json.exception.type_error.302] type must be number, but is "
957                 "boolean");
958 
959             CHECK_NOTHROW(
960                 json(json::value_t::number_float).get<json::number_integer_t>());
961             CHECK_NOTHROW(
962                 json(json::value_t::number_float).get<json::number_unsigned_t>());
963         }
964     }
965 
966     SECTION("get an integer number (implicit)")
967     {
968         json::number_integer_t n_reference{42};
969         json j(n_reference);
970         json::number_unsigned_t n_unsigned_reference{42u};
971         json j_unsigned(n_unsigned_reference);
972 
973         SECTION("number_integer_t")
974         {
975             json::number_integer_t n = j.get<json::number_integer_t>();
976             CHECK(json(n) == j);
977         }
978 
979         SECTION("number_unsigned_t")
980         {
981             json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
982             CHECK(json(n) == j_unsigned);
983         }
984 
985         SECTION("short")
986         {
987             short n = j;
988             CHECK(json(n) == j);
989         }
990 
991         SECTION("unsigned short")
992         {
993             unsigned short n = j_unsigned;
994             CHECK(json(n) == j_unsigned);
995         }
996 
997         SECTION("int")
998         {
999             int n = j;
1000             CHECK(json(n) == j);
1001         }
1002 
1003         SECTION("unsigned int")
1004         {
1005             unsigned int n = j_unsigned;
1006             CHECK(json(n) == j_unsigned);
1007         }
1008 
1009         SECTION("long")
1010         {
1011             long n = j;
1012             CHECK(json(n) == j);
1013         }
1014 
1015         SECTION("unsigned long")
1016         {
1017             unsigned long n = j_unsigned;
1018             CHECK(json(n) == j_unsigned);
1019         }
1020 
1021         SECTION("long long")
1022         {
1023             long long n = j;
1024             CHECK(json(n) == j);
1025         }
1026 
1027         SECTION("unsigned long long")
1028         {
1029             unsigned long long n = j_unsigned;
1030             CHECK(json(n) == j_unsigned);
1031         }
1032 
1033         SECTION("int8_t")
1034         {
1035             int8_t n = j;
1036             CHECK(json(n) == j);
1037         }
1038 
1039         SECTION("int16_t")
1040         {
1041             int16_t n = j;
1042             CHECK(json(n) == j);
1043         }
1044 
1045         SECTION("int32_t")
1046         {
1047             int32_t n = j;
1048             CHECK(json(n) == j);
1049         }
1050 
1051         SECTION("int64_t")
1052         {
1053             int64_t n = j;
1054             CHECK(json(n) == j);
1055         }
1056 
1057         SECTION("int8_fast_t")
1058         {
1059             int_fast8_t n = j;
1060             CHECK(json(n) == j);
1061         }
1062 
1063         SECTION("int16_fast_t")
1064         {
1065             int_fast16_t n = j;
1066             CHECK(json(n) == j);
1067         }
1068 
1069         SECTION("int32_fast_t")
1070         {
1071             int_fast32_t n = j;
1072             CHECK(json(n) == j);
1073         }
1074 
1075         SECTION("int64_fast_t")
1076         {
1077             int_fast64_t n = j;
1078             CHECK(json(n) == j);
1079         }
1080 
1081         SECTION("int8_least_t")
1082         {
1083             int_least8_t n = j;
1084             CHECK(json(n) == j);
1085         }
1086 
1087         SECTION("int16_least_t")
1088         {
1089             int_least16_t n = j;
1090             CHECK(json(n) == j);
1091         }
1092 
1093         SECTION("int32_least_t")
1094         {
1095             int_least32_t n = j;
1096             CHECK(json(n) == j);
1097         }
1098 
1099         SECTION("int64_least_t")
1100         {
1101             int_least64_t n = j;
1102             CHECK(json(n) == j);
1103         }
1104 
1105         SECTION("uint8_t")
1106         {
1107             uint8_t n = j_unsigned;
1108             CHECK(json(n) == j_unsigned);
1109         }
1110 
1111         SECTION("uint16_t")
1112         {
1113             uint16_t n = j_unsigned;
1114             CHECK(json(n) == j_unsigned);
1115         }
1116 
1117         SECTION("uint32_t")
1118         {
1119             uint32_t n = j_unsigned;
1120             CHECK(json(n) == j_unsigned);
1121         }
1122 
1123         SECTION("uint64_t")
1124         {
1125             uint64_t n = j_unsigned;
1126             CHECK(json(n) == j_unsigned);
1127         }
1128 
1129         SECTION("uint8_fast_t")
1130         {
1131             uint_fast8_t n = j_unsigned;
1132             CHECK(json(n) == j_unsigned);
1133         }
1134 
1135         SECTION("uint16_fast_t")
1136         {
1137             uint_fast16_t n = j_unsigned;
1138             CHECK(json(n) == j_unsigned);
1139         }
1140 
1141         SECTION("uint32_fast_t")
1142         {
1143             uint_fast32_t n = j_unsigned;
1144             CHECK(json(n) == j_unsigned);
1145         }
1146 
1147         SECTION("uint64_fast_t")
1148         {
1149             uint_fast64_t n = j_unsigned;
1150             CHECK(json(n) == j_unsigned);
1151         }
1152 
1153         SECTION("uint8_least_t")
1154         {
1155             uint_least8_t n = j_unsigned;
1156             CHECK(json(n) == j_unsigned);
1157         }
1158 
1159         SECTION("uint16_least_t")
1160         {
1161             uint_least16_t n = j_unsigned;
1162             CHECK(json(n) == j_unsigned);
1163         }
1164 
1165         SECTION("uint32_least_t")
1166         {
1167             uint_least32_t n = j_unsigned;
1168             CHECK(json(n) == j_unsigned);
1169         }
1170 
1171         SECTION("uint64_least_t")
1172         {
1173             uint_least64_t n = j_unsigned;
1174             CHECK(json(n) == j_unsigned);
1175         }
1176     }
1177 
1178     SECTION("get a floating-point number (explicit)")
1179     {
1180         json::number_float_t n_reference{42.23};
1181         json j(n_reference);
1182 
1183         SECTION("number_float_t")
1184         {
1185             json::number_float_t n = j.get<json::number_float_t>();
1186             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1187         }
1188 
1189         SECTION("float")
1190         {
1191             float n = j.get<float>();
1192             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1193         }
1194 
1195         SECTION("double")
1196         {
1197             double n = j.get<double>();
1198             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1199         }
1200 
1201         SECTION("exception in case of a non-string type")
1202         {
1203             CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(),
1204                             json::type_error&);
1205             CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(),
1206                             json::type_error&);
1207             CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(),
1208                             json::type_error&);
1209             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(),
1210                             json::type_error&);
1211             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(),
1212                             json::type_error&);
1213 
1214             CHECK_THROWS_WITH(
1215                 json(json::value_t::null).get<json::number_float_t>(),
1216                 "[json.exception.type_error.302] type must be number, but is null");
1217             CHECK_THROWS_WITH(
1218                 json(json::value_t::object).get<json::number_float_t>(),
1219                 "[json.exception.type_error.302] type must be number, but is object");
1220             CHECK_THROWS_WITH(
1221                 json(json::value_t::array).get<json::number_float_t>(),
1222                 "[json.exception.type_error.302] type must be number, but is array");
1223             CHECK_THROWS_WITH(
1224                 json(json::value_t::string).get<json::number_float_t>(),
1225                 "[json.exception.type_error.302] type must be number, but is string");
1226             CHECK_THROWS_WITH(
1227                 json(json::value_t::boolean).get<json::number_float_t>(),
1228                 "[json.exception.type_error.302] type must be number, but is "
1229                 "boolean");
1230 
1231             CHECK_NOTHROW(
1232                 json(json::value_t::number_integer).get<json::number_float_t>());
1233             CHECK_NOTHROW(
1234                 json(json::value_t::number_unsigned).get<json::number_float_t>());
1235         }
1236     }
1237 
1238     SECTION("get a floating-point number (implicit)")
1239     {
1240         json::number_float_t n_reference{42.23};
1241         json j(n_reference);
1242 
1243         SECTION("number_float_t")
1244         {
1245             json::number_float_t n = j;
1246             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1247         }
1248 
1249         SECTION("float")
1250         {
1251             float n = j;
1252             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1253         }
1254 
1255         SECTION("double")
1256         {
1257             double n = j;
1258             CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
1259         }
1260     }
1261 
1262     SECTION("get an enum")
1263     {
1264         enum c_enum { value_1, value_2 };
1265         enum class cpp_enum { value_1, value_2 };
1266 
1267         CHECK(json(value_1).get<c_enum>() == value_1);
1268         CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
1269     }
1270 
1271     SECTION("more involved conversions")
1272     {
1273         SECTION("object-like STL containers")
1274         {
1275             json j1 = {{"one", 1}, {"two", 2}, {"three", 3}};
1276             json j2 = {{"one", 1u}, {"two", 2u}, {"three", 3u}};
1277             json j3 = {{"one", 1.1}, {"two", 2.2}, {"three", 3.3}};
1278             json j4 = {{"one", true}, {"two", false}, {"three", true}};
1279             json j5 = {{"one", "eins"}, {"two", "zwei"}, {"three", "drei"}};
1280 
1281             SECTION("std::map")
1282             {
1283                 j1.get<std::map<std::string, int>>();
1284                 j2.get<std::map<std::string, unsigned int>>();
1285                 j3.get<std::map<std::string, double>>();
1286                 j4.get<std::map<std::string, bool>>();
1287                 j5.get<std::map<std::string, std::string>>();
1288             }
1289 
1290             SECTION("std::unordered_map")
1291             {
1292                 j1.get<std::unordered_map<std::string, int>>();
1293                 j2.get<std::unordered_map<std::string, unsigned int>>();
1294                 j3.get<std::unordered_map<std::string, double>>();
1295                 j4.get<std::unordered_map<std::string, bool>>();
1296                 j5.get<std::unordered_map<std::string, std::string>>();
1297                 // CHECK(m5["one"] == "eins");
1298             }
1299 
1300             SECTION("std::multimap")
1301             {
1302                 j1.get<std::multimap<std::string, int>>();
1303                 j2.get<std::multimap<std::string, unsigned int>>();
1304                 j3.get<std::multimap<std::string, double>>();
1305                 j4.get<std::multimap<std::string, bool>>();
1306                 j5.get<std::multimap<std::string, std::string>>();
1307                 // CHECK(m5["one"] == "eins");
1308             }
1309 
1310             SECTION("std::unordered_multimap")
1311             {
1312                 j1.get<std::unordered_multimap<std::string, int>>();
1313                 j2.get<std::unordered_multimap<std::string, unsigned int>>();
1314                 j3.get<std::unordered_multimap<std::string, double>>();
1315                 j4.get<std::unordered_multimap<std::string, bool>>();
1316                 j5.get<std::unordered_multimap<std::string, std::string>>();
1317                 // CHECK(m5["one"] == "eins");
1318             }
1319 
1320             SECTION("exception in case of a non-object type")
1321             {
1322                 CHECK_THROWS_AS((json().get<std::map<std::string, int>>()),
1323                                 json::type_error&);
1324                 CHECK_THROWS_WITH(
1325                     (json().get<std::map<std::string, int>>()),
1326                     "[json.exception.type_error.302] type must be object, but is null");
1327             }
1328         }
1329 
1330         SECTION("array-like STL containers")
1331         {
1332             json j1 = {1, 2, 3, 4};
1333             json j2 = {1u, 2u, 3u, 4u};
1334             json j3 = {1.2, 2.3, 3.4, 4.5};
1335             json j4 = {true, false, true};
1336             json j5 = {"one", "two", "three"};
1337 
1338             SECTION("std::list")
1339             {
1340                 j1.get<std::list<int>>();
1341                 j2.get<std::list<unsigned int>>();
1342                 j3.get<std::list<double>>();
1343                 j4.get<std::list<bool>>();
1344                 j5.get<std::list<std::string>>();
1345             }
1346 
1347             SECTION("std::forward_list")
1348             {
1349                 j1.get<std::forward_list<int>>();
1350                 j2.get<std::forward_list<unsigned int>>();
1351                 j3.get<std::forward_list<double>>();
1352                 j4.get<std::forward_list<bool>>();
1353                 j5.get<std::forward_list<std::string>>();
1354             }
1355 
1356             SECTION("std::array")
1357             {
1358                 j1.get<std::array<int, 4>>();
1359                 j2.get<std::array<unsigned int, 3>>();
1360                 j3.get<std::array<double, 4>>();
1361                 j4.get<std::array<bool, 3>>();
1362                 j5.get<std::array<std::string, 3>>();
1363 
1364                 SECTION("std::array is larger than JSON")
1365                 {
1366                     std::array<int, 6> arr6 = {{1, 2, 3, 4, 5, 6}};
1367                     CHECK_THROWS_AS(arr6 = j1, json::out_of_range&);
1368                     CHECK_THROWS_WITH(arr6 = j1, "[json.exception.out_of_range.401] "
1369                                       "array index 4 is out of range");
1370                 }
1371 
1372                 SECTION("std::array is smaller than JSON")
1373                 {
1374                     std::array<int, 2> arr2 = {{8, 9}};
1375                     arr2 = j1;
1376                     CHECK(arr2[0] == 1);
1377                     CHECK(arr2[1] == 2);
1378                 }
1379             }
1380 
1381             SECTION("std::valarray")
1382             {
1383                 j1.get<std::valarray<int>>();
1384                 j2.get<std::valarray<unsigned int>>();
1385                 j3.get<std::valarray<double>>();
1386                 j4.get<std::valarray<bool>>();
1387                 j5.get<std::valarray<std::string>>();
1388             }
1389 
1390             SECTION("std::vector")
1391             {
1392                 j1.get<std::vector<int>>();
1393                 j2.get<std::vector<unsigned int>>();
1394                 j3.get<std::vector<double>>();
1395                 j4.get<std::vector<bool>>();
1396                 j5.get<std::vector<std::string>>();
1397             }
1398 
1399             SECTION("std::deque")
1400             {
1401                 j1.get<std::deque<int>>();
1402                 j2.get<std::deque<unsigned int>>();
1403                 j2.get<std::deque<double>>();
1404                 j4.get<std::deque<bool>>();
1405                 j5.get<std::deque<std::string>>();
1406             }
1407 
1408             SECTION("std::set")
1409             {
1410                 j1.get<std::set<int>>();
1411                 j2.get<std::set<unsigned int>>();
1412                 j3.get<std::set<double>>();
1413                 j4.get<std::set<bool>>();
1414                 j5.get<std::set<std::string>>();
1415             }
1416 
1417             SECTION("std::unordered_set")
1418             {
1419                 j1.get<std::unordered_set<int>>();
1420                 j2.get<std::unordered_set<unsigned int>>();
1421                 j3.get<std::unordered_set<double>>();
1422                 j4.get<std::unordered_set<bool>>();
1423                 j5.get<std::unordered_set<std::string>>();
1424             }
1425 
1426             SECTION("std::map (array of pairs)")
1427             {
1428                 std::map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
1429                 json j6 = m;
1430 
1431                 auto m2 = j6.get<std::map<int, int>>();
1432                 CHECK(m == m2);
1433 
1434                 json j7 = {0, 1, 2, 3};
1435                 json j8 = 2;
1436                 CHECK_THROWS_AS((j7.get<std::map<int, int>>()), json::type_error&);
1437                 CHECK_THROWS_AS((j8.get<std::map<int, int>>()), json::type_error&);
1438                 CHECK_THROWS_WITH((j7.get<std::map<int, int>>()),
1439                                   "[json.exception.type_error.302] type must be array, "
1440                                   "but is number");
1441                 CHECK_THROWS_WITH((j8.get<std::map<int, int>>()),
1442                                   "[json.exception.type_error.302] type must be array, "
1443                                   "but is number");
1444 
1445                 SECTION("superfluous entries")
1446                 {
1447                     json j9 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
1448                     m2 = j9.get<std::map<int, int>>();
1449                     CHECK(m == m2);
1450                 }
1451             }
1452 
1453             SECTION("std::unordered_map (array of pairs)")
1454             {
1455                 std::unordered_map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
1456                 json j6 = m;
1457 
1458                 auto m2 = j6.get<std::unordered_map<int, int>>();
1459                 CHECK(m == m2);
1460 
1461                 json j7 = {0, 1, 2, 3};
1462                 json j8 = 2;
1463                 CHECK_THROWS_AS((j7.get<std::unordered_map<int, int>>()), json::type_error&);
1464                 CHECK_THROWS_AS((j8.get<std::unordered_map<int, int>>()), json::type_error&);
1465                 CHECK_THROWS_WITH((j7.get<std::unordered_map<int, int>>()),
1466                                   "[json.exception.type_error.302] type must be array, "
1467                                   "but is number");
1468                 CHECK_THROWS_WITH((j8.get<std::unordered_map<int, int>>()),
1469                                   "[json.exception.type_error.302] type must be array, "
1470                                   "but is number");
1471 
1472                 SECTION("superfluous entries")
1473                 {
1474                     json j9{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
1475                     m2 = j9.get<std::unordered_map<int, int>>();
1476                     CHECK(m == m2);
1477                 }
1478             }
1479 
1480             SECTION("exception in case of a non-object type")
1481             {
1482                 CHECK_THROWS_AS((json().get<std::list<int>>()), json::type_error&);
1483                 CHECK_THROWS_AS((json().get<std::vector<int>>()), json::type_error&);
1484                 CHECK_THROWS_AS((json().get<std::vector<json>>()), json::type_error&);
1485                 CHECK_THROWS_AS((json().get<std::list<json>>()), json::type_error&);
1486                 CHECK_THROWS_AS((json().get<std::valarray<int>>()), json::type_error&);
1487 
1488                 // does type really must be an array? or it rather must not be null?
1489                 // that's what I thought when other test like this one broke
1490                 CHECK_THROWS_WITH(
1491                     (json().get<std::list<int>>()),
1492                     "[json.exception.type_error.302] type must be array, but is null");
1493                 CHECK_THROWS_WITH(
1494                     (json().get<std::vector<int>>()),
1495                     "[json.exception.type_error.302] type must be array, but is null");
1496                 CHECK_THROWS_WITH(
1497                     (json().get<std::vector<json>>()),
1498                     "[json.exception.type_error.302] type must be array, but is null");
1499                 CHECK_THROWS_WITH(
1500                     (json().get<std::list<json>>()),
1501                     "[json.exception.type_error.302] type must be array, but is null");
1502                 CHECK_THROWS_WITH(
1503                     (json().get<std::valarray<int>>()),
1504                     "[json.exception.type_error.302] type must be array, but is null");
1505                 CHECK_THROWS_WITH(
1506                     (json().get<std::map<int, int>>()),
1507                     "[json.exception.type_error.302] type must be array, but is null");
1508             }
1509         }
1510     }
1511 }
1512 
1513 enum class cards {kreuz, pik, herz, karo};
1514 
1515 NLOHMANN_JSON_SERIALIZE_ENUM(cards,
1516 {
1517     {cards::kreuz, "kreuz"},
1518     {cards::pik, "pik"},
1519     {cards::pik, "puk"},  // second entry for cards::puk; will not be used
1520     {cards::herz, "herz"},
1521     {cards::karo, "karo"}
1522 })
1523 
1524 enum TaskState
1525 {
1526     TS_STOPPED,
1527     TS_RUNNING,
1528     TS_COMPLETED,
1529     TS_INVALID = -1,
1530 };
1531 
1532 NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
1533 {
1534     {TS_INVALID, nullptr},
1535     {TS_STOPPED, "stopped"},
1536     {TS_RUNNING, "running"},
1537     {TS_COMPLETED, "completed"},
1538 })
1539 
1540 TEST_CASE("JSON to enum mapping")
1541 {
1542     SECTION("enum class")
1543     {
1544         // enum -> json
1545         CHECK(json(cards::kreuz) == "kreuz");
1546         CHECK(json(cards::pik) == "pik");
1547         CHECK(json(cards::herz) == "herz");
1548         CHECK(json(cards::karo) == "karo");
1549 
1550         // json -> enum
1551         CHECK(cards::kreuz == json("kreuz"));
1552         CHECK(cards::pik == json("pik"));
1553         CHECK(cards::herz == json("herz"));
1554         CHECK(cards::karo == json("karo"));
1555 
1556         // invalid json -> first enum
1557         CHECK(cards::kreuz == json("what?").get<cards>());
1558     }
1559 
1560     SECTION("traditional enum")
1561     {
1562         // enum -> json
1563         CHECK(json(TS_STOPPED) == "stopped");
1564         CHECK(json(TS_RUNNING) == "running");
1565         CHECK(json(TS_COMPLETED) == "completed");
1566         CHECK(json(TS_INVALID) == json());
1567 
1568         // json -> enum
1569         CHECK(TS_STOPPED == json("stopped"));
1570         CHECK(TS_RUNNING == json("running"));
1571         CHECK(TS_COMPLETED == json("completed"));
1572         CHECK(TS_INVALID == json());
1573 
1574         // invalid json -> first enum
1575         CHECK(TS_INVALID == json("what?").get<TaskState>());
1576     }
1577 }
1578