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