• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //     __ _____ _____ _____
2 //  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3 // |  |  |__   |  |  | | | |  version 3.11.3
4 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 #include "doctest_compatibility.h"
10 
11 #define JSON_TESTS_PRIVATE
12 #include <nlohmann/json.hpp>
13 using nlohmann::json;
14 
15 #include <deque>
16 #include <forward_list>
17 #include <fstream>
18 #include <list>
19 #include <set>
20 #include <unordered_map>
21 #include <unordered_set>
22 #include <valarray>
23 
24 TEST_CASE("constructors")
25 {
26     SECTION("create an empty value with a given type")
27     {
28         SECTION("null")
29         {
30             auto const t = json::value_t::null;
31             json const j(t);
32             CHECK(j.type() == t);
33         }
34 
35         SECTION("discarded")
36         {
37             auto const t = json::value_t::discarded;
38             json const j(t);
39             CHECK(j.type() == t);
40         }
41 
42         SECTION("object")
43         {
44             auto const t = json::value_t::object;
45             json const j(t);
46             CHECK(j.type() == t);
47         }
48 
49         SECTION("array")
50         {
51             auto const t = json::value_t::array;
52             json const j(t);
53             CHECK(j.type() == t);
54         }
55 
56         SECTION("boolean")
57         {
58             auto const t = json::value_t::boolean;
59             json const j(t);
60             CHECK(j.type() == t);
61             CHECK(j == false);
62         }
63 
64         SECTION("string")
65         {
66             auto const t = json::value_t::string;
67             json const j(t);
68             CHECK(j.type() == t);
69             CHECK(j == "");
70         }
71 
72         SECTION("number_integer")
73         {
74             auto const t = json::value_t::number_integer;
75             json const j(t);
76             CHECK(j.type() == t);
77             CHECK(j == 0);
78         }
79 
80         SECTION("number_unsigned")
81         {
82             auto const t = json::value_t::number_unsigned;
83             json const j(t);
84             CHECK(j.type() == t);
85             CHECK(j == 0);
86         }
87 
88         SECTION("number_float")
89         {
90             auto const t = json::value_t::number_float;
91             json const j(t);
92             CHECK(j.type() == t);
93             CHECK(j == 0.0);
94         }
95 
96         SECTION("binary")
97         {
98             auto const t = json::value_t::binary;
99             json const j(t);
100             CHECK(j.type() == t);
101             CHECK(j == json::binary({}));
102         }
103     }
104 
105     SECTION("create a null object (implicitly)")
106     {
107         SECTION("no parameter")
108         {
109             json const j{};
110             CHECK(j.type() == json::value_t::null);
111         }
112     }
113 
114     SECTION("create a null object (explicitly)")
115     {
116         SECTION("parameter")
117         {
118             json const j(nullptr);
119             CHECK(j.type() == json::value_t::null);
120         }
121     }
122 
123     SECTION("create an object (explicit)")
124     {
125         SECTION("empty object")
126         {
127             json::object_t const o{};
128             json const j(o);
129             CHECK(j.type() == json::value_t::object);
130         }
131 
132         SECTION("filled object")
133         {
134             json::object_t const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
135             json const j(o);
136             CHECK(j.type() == json::value_t::object);
137         }
138     }
139 
140     SECTION("create an object (implicit)")
141     {
142         // reference object
143         json::object_t const o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
144         json const j_reference(o_reference);
145 
146         SECTION("std::map<json::string_t, json>")
147         {
148             std::map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
149             json const j(o);
150             CHECK(j.type() == json::value_t::object);
151             CHECK(j == j_reference);
152         }
153 
154         SECTION("std::map<std::string, std::string> #600")
155         {
156             const std::map<std::string, std::string> m
157             {
158                 {"a", "b"},
159                 {"c", "d"},
160                 {"e", "f"},
161             };
162 
163             json const j(m);
164             CHECK((j.get<decltype(m)>() == m));
165         }
166 
167         SECTION("std::map<const char*, json>")
168         {
169             std::map<const char*, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
170             json const j(o);
171             CHECK(j.type() == json::value_t::object);
172             CHECK(j == j_reference);
173         }
174 
175         SECTION("std::multimap<json::string_t, json>")
176         {
177             std::multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
178             json const j(o);
179             CHECK(j.type() == json::value_t::object);
180             CHECK(j == j_reference);
181         }
182 
183         SECTION("std::unordered_map<json::string_t, json>")
184         {
185             std::unordered_map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
186             json const j(o);
187             CHECK(j.type() == json::value_t::object);
188             CHECK(j == j_reference);
189         }
190 
191         SECTION("std::unordered_multimap<json::string_t, json>")
192         {
193             std::unordered_multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
194             json const j(o);
195             CHECK(j.type() == json::value_t::object);
196             CHECK(j == j_reference);
197         }
198 
199         SECTION("associative container literal")
200         {
201             json const j({{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}});
202             CHECK(j.type() == json::value_t::object);
203             CHECK(j == j_reference);
204         }
205     }
206 
207     SECTION("create an array (explicit)")
208     {
209         SECTION("empty array")
210         {
211             json::array_t const a{};
212             json const j(a);
213             CHECK(j.type() == json::value_t::array);
214         }
215 
216         SECTION("filled array")
217         {
218             json::array_t const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
219             json const j(a);
220             CHECK(j.type() == json::value_t::array);
221         }
222     }
223 
224     SECTION("create an array (implicit)")
225     {
226         // reference array
227         json::array_t const a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
228         json const j_reference(a_reference);
229 
230         SECTION("std::list<json>")
231         {
232             std::list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
233             json const j(a);
234             CHECK(j.type() == json::value_t::array);
235             CHECK(j == j_reference);
236         }
237 
238         SECTION("std::pair")
239         {
240             std::pair<float, std::string> const p{1.0f, "string"};
241             json const j(p);
242 
243             CHECK(j.type() == json::value_t::array);
244             CHECK(j.get<decltype(p)>() == p);
245             REQUIRE(j.size() == 2);
246             CHECK(j[0] == std::get<0>(p));
247             CHECK(j[1] == std::get<1>(p));
248         }
249 
250         SECTION("std::pair with discarded values")
251         {
252             json const j{1, 2.0, "string"};
253 
254             const auto p = j.get<std::pair<int, float>>();
255             CHECK(p.first == j[0]);
256             CHECK(p.second == j[1]);
257         }
258 
259         SECTION("std::tuple")
260         {
261             const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector<int> {0, 1});
262             json const j(t);
263 
264             CHECK(j.type() == json::value_t::array);
265             REQUIRE(j.size() == 4);
266             CHECK(j.get<decltype(t)>() == t);
267             CHECK(j[0] == std::get<0>(t));
268             CHECK(j[1] == std::get<1>(t));
269             CHECK(j[2] == std::get<2>(t));
270             CHECK(j[3][0] == 0);
271             CHECK(j[3][1] == 1);
272         }
273 
274         SECTION("std::tuple with discarded values")
275         {
276             json const j{1, 2.0, "string", 42};
277 
278             const auto t = j.get<std::tuple<int, float, std::string>>();
279             CHECK(std::get<0>(t) == j[0]);
280             CHECK(std::get<1>(t) == j[1]);
281             // CHECK(std::get<2>(t) == j[2]); // commented out due to CI issue, see https://github.com/nlohmann/json/pull/3985 and https://github.com/nlohmann/json/issues/4025
282         }
283 
284         SECTION("std::pair/tuple/array failures")
285         {
286             json const j{1};
287 
288             CHECK_THROWS_WITH_AS((j.get<std::pair<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
289             CHECK_THROWS_WITH_AS((j.get<std::tuple<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
290             CHECK_THROWS_WITH_AS((j.get<std::array<int, 3>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
291         }
292 
293         SECTION("std::forward_list<json>")
294         {
295             std::forward_list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
296             json const j(a);
297             CHECK(j.type() == json::value_t::array);
298             CHECK(j == j_reference);
299         }
300 
301         SECTION("std::array<json, 6>")
302         {
303             std::array<json, 6> const a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}};
304             json const j(a);
305             CHECK(j.type() == json::value_t::array);
306             CHECK(j == j_reference);
307 
308             const auto a2 = j.get<std::array<json, 6>>();
309             CHECK(a2 == a);
310         }
311 
312         SECTION("std::valarray<int>")
313         {
314             std::valarray<int> const va = {1, 2, 3, 4, 5};
315             json const j(va);
316             CHECK(j.type() == json::value_t::array);
317             CHECK(j == json({1, 2, 3, 4, 5}));
318 
319             auto jva = j.get<std::valarray<int>>();
320             CHECK(jva.size() == va.size());
321             for (size_t i = 0; i < jva.size(); ++i)
322             {
323                 CHECK(va[i] == jva[i]);
324             }
325         }
326 
327         SECTION("std::valarray<double>")
328         {
329             std::valarray<double> const va = {1.2, 2.3, 3.4, 4.5, 5.6};
330             json const j(va);
331             CHECK(j.type() == json::value_t::array);
332             CHECK(j == json({1.2, 2.3, 3.4, 4.5, 5.6}));
333 
334             auto jva = j.get<std::valarray<double>>();
335             CHECK(jva.size() == va.size());
336             for (size_t i = 0; i < jva.size(); ++i)
337             {
338                 CHECK(va[i] == jva[i]);
339             }
340         }
341 
342         SECTION("std::vector<json>")
343         {
344             std::vector<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
345             json const j(a);
346             CHECK(j.type() == json::value_t::array);
347             CHECK(j == j_reference);
348         }
349 
350         SECTION("std::deque<json>")
351         {
352             std::deque<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
353             json const j(a);
354             CHECK(j.type() == json::value_t::array);
355             CHECK(j == j_reference);
356         }
357 
358         SECTION("std::set<json>")
359         {
360             std::set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
361             json const j(a);
362             CHECK(j.type() == json::value_t::array);
363             // we cannot really check for equality here
364         }
365 
366         SECTION("std::unordered_set<json>")
367         {
368             std::unordered_set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
369             json const j(a);
370             CHECK(j.type() == json::value_t::array);
371             // we cannot really check for equality here
372         }
373 
374         SECTION("sequence container literal")
375         {
376             json const j({json(1), json(1u), json(2.2), json(false), json("string"), json()});
377             CHECK(j.type() == json::value_t::array);
378             CHECK(j == j_reference);
379         }
380     }
381 
382     SECTION("create a string (explicit)")
383     {
384         SECTION("empty string")
385         {
386             json::string_t const s{};
387             json const j(s);
388             CHECK(j.type() == json::value_t::string);
389         }
390 
391         SECTION("filled string")
392         {
393             json::string_t const s {"Hello world"};
394             json const j(s);
395             CHECK(j.type() == json::value_t::string);
396         }
397     }
398 
399     SECTION("create a string (implicit)")
400     {
401         // reference string
402         json::string_t const s_reference {"Hello world"};
403         json const j_reference(s_reference);
404 
405         SECTION("std::string")
406         {
407             std::string const s {"Hello world"};
408             json const j(s);
409             CHECK(j.type() == json::value_t::string);
410             CHECK(j == j_reference);
411         }
412 
413         SECTION("char[]")
414         {
415             char const s[] {"Hello world"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
416             json const j(s);
417             CHECK(j.type() == json::value_t::string);
418             CHECK(j == j_reference);
419         }
420 
421         SECTION("const char*")
422         {
423             const char* s {"Hello world"};
424             json const j(s);
425             CHECK(j.type() == json::value_t::string);
426             CHECK(j == j_reference);
427         }
428 
429         SECTION("string literal")
430         {
431             json const j("Hello world");
432             CHECK(j.type() == json::value_t::string);
433             CHECK(j == j_reference);
434         }
435     }
436 
437     SECTION("create a boolean (explicit)")
438     {
439         SECTION("empty boolean")
440         {
441             json::boolean_t const b{};
442             json const j(b);
443             CHECK(j.type() == json::value_t::boolean);
444         }
445 
446         SECTION("filled boolean (true)")
447         {
448             json const j(true);
449             CHECK(j.type() == json::value_t::boolean);
450         }
451 
452         SECTION("filled boolean (false)")
453         {
454             json const j(false);
455             CHECK(j.type() == json::value_t::boolean);
456         }
457 
458         SECTION("from std::vector<bool>::reference")
459         {
460             std::vector<bool> v{true};
461             json const j(v[0]);
462             CHECK(std::is_same<decltype(v[0]), std::vector<bool>::reference>::value);
463             CHECK(j.type() == json::value_t::boolean);
464         }
465 
466         SECTION("from std::vector<bool>::const_reference")
467         {
468             const std::vector<bool> v{true};
469             json const j(v[0]);
470             CHECK(std::is_same<decltype(v[0]), std::vector<bool>::const_reference>::value);
471             CHECK(j.type() == json::value_t::boolean);
472         }
473     }
474 
475     SECTION("create a binary (explicit)")
476     {
477         SECTION("empty binary")
478         {
479             json::binary_t const b{};
480             json const j(b);
481             CHECK(j.type() == json::value_t::binary);
482         }
483 
484         SECTION("filled binary")
485         {
486             json::binary_t const b({1, 2, 3});
487             json const j(b);
488             CHECK(j.type() == json::value_t::binary);
489         }
490     }
491 
492     SECTION("create an integer number (explicit)")
493     {
494         SECTION("uninitialized value")
495         {
496             json::number_integer_t const n{};
497             json const j(n);
498             CHECK(j.type() == json::value_t::number_integer);
499         }
500 
501         SECTION("initialized value")
502         {
503             json::number_integer_t const n(42);
504             json const j(n);
505             CHECK(j.type() == json::value_t::number_integer);
506         }
507     }
508 
509     SECTION("create an integer number (implicit)")
510     {
511         // reference objects
512         json::number_integer_t const n_reference = 42;
513         json const j_reference(n_reference);
514         json::number_unsigned_t const n_unsigned_reference = 42;
515         json const j_unsigned_reference(n_unsigned_reference);
516 
517         SECTION("short")
518         {
519             short const n = 42;
520             json const j(n);
521             CHECK(j.type() == json::value_t::number_integer);
522             CHECK(j == j_reference);
523         }
524 
525         SECTION("unsigned short")
526         {
527             unsigned short const n = 42;
528             json const j(n);
529             CHECK(j.type() == json::value_t::number_unsigned);
530             CHECK(j == j_unsigned_reference);
531         }
532 
533         SECTION("int")
534         {
535             int const n = 42;
536             json const j(n);
537             CHECK(j.type() == json::value_t::number_integer);
538             CHECK(j == j_reference);
539         }
540 
541         SECTION("unsigned int")
542         {
543             unsigned int const n = 42;
544             json const j(n);
545             CHECK(j.type() == json::value_t::number_unsigned);
546             CHECK(j == j_unsigned_reference);
547         }
548 
549         SECTION("long")
550         {
551             long const n = 42;
552             json const j(n);
553             CHECK(j.type() == json::value_t::number_integer);
554             CHECK(j == j_reference);
555         }
556 
557         SECTION("unsigned long")
558         {
559             unsigned long const n = 42;
560             json const j(n);
561             CHECK(j.type() == json::value_t::number_unsigned);
562             CHECK(j == j_unsigned_reference);
563         }
564 
565         SECTION("long long")
566         {
567             long long const n = 42;
568             json const j(n);
569             CHECK(j.type() == json::value_t::number_integer);
570             CHECK(j == j_reference);
571         }
572 
573         SECTION("unsigned long long")
574         {
575             unsigned long long const n = 42;
576             json const j(n);
577             CHECK(j.type() == json::value_t::number_unsigned);
578             CHECK(j == j_unsigned_reference);
579         }
580 
581         SECTION("int8_t")
582         {
583             int8_t const n = 42;
584             json const j(n);
585             CHECK(j.type() == json::value_t::number_integer);
586             CHECK(j == j_reference);
587         }
588 
589         SECTION("int16_t")
590         {
591             int16_t const n = 42;
592             json const j(n);
593             CHECK(j.type() == json::value_t::number_integer);
594             CHECK(j == j_reference);
595         }
596 
597         SECTION("int32_t")
598         {
599             int32_t const n = 42;
600             json const j(n);
601             CHECK(j.type() == json::value_t::number_integer);
602             CHECK(j == j_reference);
603         }
604 
605         SECTION("int64_t")
606         {
607             int64_t const n = 42;
608             json const j(n);
609             CHECK(j.type() == json::value_t::number_integer);
610             CHECK(j == j_reference);
611         }
612 
613         SECTION("int_fast8_t")
614         {
615             int_fast8_t const n = 42;
616             json const j(n);
617             CHECK(j.type() == json::value_t::number_integer);
618             CHECK(j == j_reference);
619         }
620 
621         SECTION("int_fast16_t")
622         {
623             int_fast16_t const n = 42;
624             json const j(n);
625             CHECK(j.type() == json::value_t::number_integer);
626             CHECK(j == j_reference);
627         }
628 
629         SECTION("int_fast32_t")
630         {
631             int_fast32_t const n = 42;
632             json const j(n);
633             CHECK(j.type() == json::value_t::number_integer);
634             CHECK(j == j_reference);
635         }
636 
637         SECTION("int_fast64_t")
638         {
639             int_fast64_t const n = 42;
640             json const j(n);
641             CHECK(j.type() == json::value_t::number_integer);
642             CHECK(j == j_reference);
643         }
644 
645         SECTION("int_least8_t")
646         {
647             int_least8_t const n = 42;
648             json const j(n);
649             CHECK(j.type() == json::value_t::number_integer);
650             CHECK(j == j_reference);
651         }
652 
653         SECTION("int_least16_t")
654         {
655             int_least16_t const n = 42;
656             json const j(n);
657             CHECK(j.type() == json::value_t::number_integer);
658             CHECK(j == j_reference);
659         }
660 
661         SECTION("int_least32_t")
662         {
663             int_least32_t const n = 42;
664             json const j(n);
665             CHECK(j.type() == json::value_t::number_integer);
666             CHECK(j == j_reference);
667         }
668 
669         SECTION("int_least64_t")
670         {
671             int_least64_t const n = 42;
672             json const j(n);
673             CHECK(j.type() == json::value_t::number_integer);
674             CHECK(j == j_reference);
675         }
676 
677         SECTION("uint8_t")
678         {
679             uint8_t const n = 42;
680             json const j(n);
681             CHECK(j.type() == json::value_t::number_unsigned);
682             CHECK(j == j_unsigned_reference);
683         }
684 
685         SECTION("uint16_t")
686         {
687             uint16_t const n = 42;
688             json const j(n);
689             CHECK(j.type() == json::value_t::number_unsigned);
690             CHECK(j == j_unsigned_reference);
691         }
692 
693         SECTION("uint32_t")
694         {
695             uint32_t const n = 42;
696             json const j(n);
697             CHECK(j.type() == json::value_t::number_unsigned);
698             CHECK(j == j_unsigned_reference);
699         }
700 
701         SECTION("uint64_t")
702         {
703             uint64_t const n = 42;
704             json const j(n);
705             CHECK(j.type() == json::value_t::number_unsigned);
706             CHECK(j == j_unsigned_reference);
707         }
708 
709         SECTION("uint_fast8_t")
710         {
711             uint_fast8_t const n = 42;
712             json const j(n);
713             CHECK(j.type() == json::value_t::number_unsigned);
714             CHECK(j == j_unsigned_reference);
715         }
716 
717         SECTION("uint_fast16_t")
718         {
719             uint_fast16_t const n = 42;
720             json const j(n);
721             CHECK(j.type() == json::value_t::number_unsigned);
722             CHECK(j == j_unsigned_reference);
723         }
724 
725         SECTION("uint_fast32_t")
726         {
727             uint_fast32_t const n = 42;
728             json const j(n);
729             CHECK(j.type() == json::value_t::number_unsigned);
730             CHECK(j == j_unsigned_reference);
731         }
732 
733         SECTION("uint_fast64_t")
734         {
735             uint_fast64_t const n = 42;
736             json const j(n);
737             CHECK(j.type() == json::value_t::number_unsigned);
738             CHECK(j == j_unsigned_reference);
739         }
740 
741         SECTION("uint_least8_t")
742         {
743             uint_least8_t const n = 42;
744             json const j(n);
745             CHECK(j.type() == json::value_t::number_unsigned);
746             CHECK(j == j_unsigned_reference);
747         }
748 
749         SECTION("uint_least16_t")
750         {
751             uint_least16_t const n = 42;
752             json const j(n);
753             CHECK(j.type() == json::value_t::number_unsigned);
754             CHECK(j == j_unsigned_reference);
755         }
756 
757         SECTION("uint_least32_t")
758         {
759             uint_least32_t const n = 42;
760             json const j(n);
761             CHECK(j.type() == json::value_t::number_unsigned);
762             CHECK(j == j_unsigned_reference);
763         }
764 
765         SECTION("uint_least64_t")
766         {
767             uint_least64_t const n = 42;
768             json const j(n);
769             CHECK(j.type() == json::value_t::number_unsigned);
770             CHECK(j == j_unsigned_reference);
771         }
772 
773         SECTION("integer literal without suffix")
774         {
775             json const j(42);
776             CHECK(j.type() == json::value_t::number_integer);
777             CHECK(j == j_reference);
778         }
779 
780         SECTION("integer literal with u suffix")
781         {
782             json j(42u);
783             CHECK(j.type() == json::value_t::number_unsigned);
784             CHECK(j == j_unsigned_reference);
785         }
786 
787         SECTION("integer literal with l suffix")
788         {
789             json const j(42L);
790             CHECK(j.type() == json::value_t::number_integer);
791             CHECK(j == j_reference);
792         }
793 
794         SECTION("integer literal with ul suffix")
795         {
796             json j(42ul);
797             CHECK(j.type() == json::value_t::number_unsigned);
798             CHECK(j == j_unsigned_reference);
799         }
800 
801         SECTION("integer literal with ll suffix")
802         {
803             json const j(42LL);
804             CHECK(j.type() == json::value_t::number_integer);
805             CHECK(j == j_reference);
806         }
807 
808         SECTION("integer literal with ull suffix")
809         {
810             json j(42ull);
811             CHECK(j.type() == json::value_t::number_unsigned);
812             CHECK(j == j_unsigned_reference);
813         }
814     }
815 
816     SECTION("create a floating-point number (explicit)")
817     {
818         SECTION("uninitialized value")
819         {
820             json::number_float_t const n{};
821             json const j(n);
822             CHECK(j.type() == json::value_t::number_float);
823         }
824 
825         SECTION("initialized value")
826         {
827             json::number_float_t const n(42.23);
828             json const j(n);
829             CHECK(j.type() == json::value_t::number_float);
830         }
831 
832         SECTION("NaN")
833         {
834             // NaN is stored properly, but serialized to null
835             json::number_float_t const n(std::numeric_limits<json::number_float_t>::quiet_NaN());
836             json const j(n);
837             CHECK(j.type() == json::value_t::number_float);
838 
839             // check round trip of NaN
840             json::number_float_t const d{j};
841             CHECK((std::isnan(d) && std::isnan(n)) == true);
842 
843             // check that NaN is serialized to null
844             CHECK(j.dump() == "null");
845         }
846 
847         SECTION("infinity")
848         {
849             // infinity is stored properly, but serialized to null
850             json::number_float_t const n(std::numeric_limits<json::number_float_t>::infinity());
851             json const j(n);
852             CHECK(j.type() == json::value_t::number_float);
853 
854             // check round trip of infinity
855             json::number_float_t const d{j};
856             CHECK(d == n);
857 
858             // check that inf is serialized to null
859             CHECK(j.dump() == "null");
860         }
861     }
862 
863     SECTION("create a floating-point number (implicit)")
864     {
865         // reference object
866         json::number_float_t const n_reference = 42.23;
867         json const j_reference(n_reference);
868 
869         SECTION("float")
870         {
871             float const n = 42.23f;
872             json const j(n);
873             CHECK(j.type() == json::value_t::number_float);
874             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
875         }
876 
877         SECTION("double")
878         {
879             double const n = 42.23;
880             json const j(n);
881             CHECK(j.type() == json::value_t::number_float);
882             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
883         }
884 
885         SECTION("long double")
886         {
887             long double const n = 42.23L;
888             json const j(n);
889             CHECK(j.type() == json::value_t::number_float);
890             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
891         }
892 
893         SECTION("floating-point literal without suffix")
894         {
895             json const j(42.23);
896             CHECK(j.type() == json::value_t::number_float);
897             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
898         }
899 
900         SECTION("integer literal with f suffix")
901         {
902             json const j(42.23f);
903             CHECK(j.type() == json::value_t::number_float);
904             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
905         }
906 
907         SECTION("integer literal with l suffix")
908         {
909             json const j(42.23L);
910             CHECK(j.type() == json::value_t::number_float);
911             CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
912         }
913     }
914 
915     SECTION("create a container (array or object) from an initializer list")
916     {
917         SECTION("empty initializer list")
918         {
919             SECTION("explicit")
920             {
921                 json const j(json::initializer_list_t {});
922                 CHECK(j.type() == json::value_t::object);
923             }
924 
925             SECTION("implicit")
926             {
927                 json const j {};
928                 CHECK(j.type() == json::value_t::null);
929             }
930         }
931 
932         SECTION("one element")
933         {
934             SECTION("array")
935             {
936                 SECTION("explicit")
937                 {
938                     json const j(json::initializer_list_t {json(json::array_t())});
939                     CHECK(j.type() == json::value_t::array);
940                 }
941 
942                 SECTION("implicit")
943                 {
944                     json const j {json::array_t()};
945                     CHECK(j.type() == json::value_t::array);
946                 }
947             }
948 
949             SECTION("object")
950             {
951                 SECTION("explicit")
952                 {
953                     json const j(json::initializer_list_t {json(json::object_t())});
954                     CHECK(j.type() == json::value_t::array);
955                 }
956 
957                 SECTION("implicit")
958                 {
959                     json const j {json::object_t()};
960                     CHECK(j.type() == json::value_t::array);
961                 }
962             }
963 
964             SECTION("string")
965             {
966                 SECTION("explicit")
967                 {
968                     json const j(json::initializer_list_t {json("Hello world")});
969                     CHECK(j.type() == json::value_t::array);
970                 }
971 
972                 SECTION("implicit")
973                 {
974                     json const j {"Hello world"};
975                     CHECK(j.type() == json::value_t::array);
976                 }
977             }
978 
979             SECTION("boolean")
980             {
981                 SECTION("explicit")
982                 {
983                     json const j(json::initializer_list_t {json(true)});
984                     CHECK(j.type() == json::value_t::array);
985                 }
986 
987                 SECTION("implicit")
988                 {
989                     json const j {true};
990                     CHECK(j.type() == json::value_t::array);
991                 }
992             }
993 
994             SECTION("number (integer)")
995             {
996                 SECTION("explicit")
997                 {
998                     json const j(json::initializer_list_t {json(1)});
999                     CHECK(j.type() == json::value_t::array);
1000                 }
1001 
1002                 SECTION("implicit")
1003                 {
1004                     json const j {1};
1005                     CHECK(j.type() == json::value_t::array);
1006                 }
1007             }
1008 
1009             SECTION("number (unsigned)")
1010             {
1011                 SECTION("explicit")
1012                 {
1013                     json const j(json::initializer_list_t {json(1u)});
1014                     CHECK(j.type() == json::value_t::array);
1015                 }
1016 
1017                 SECTION("implicit")
1018                 {
1019                     json const j {1u};
1020                     CHECK(j.type() == json::value_t::array);
1021                 }
1022             }
1023 
1024             SECTION("number (floating-point)")
1025             {
1026                 SECTION("explicit")
1027                 {
1028                     json const j(json::initializer_list_t {json(42.23)});
1029                     CHECK(j.type() == json::value_t::array);
1030                 }
1031 
1032                 SECTION("implicit")
1033                 {
1034                     json const j {42.23};
1035                     CHECK(j.type() == json::value_t::array);
1036                 }
1037             }
1038         }
1039 
1040         SECTION("more elements")
1041         {
1042             SECTION("explicit")
1043             {
1044                 json const j(json::initializer_list_t {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()});
1045                 CHECK(j.type() == json::value_t::array);
1046             }
1047 
1048             SECTION("implicit")
1049             {
1050                 json const j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};
1051                 CHECK(j.type() == json::value_t::array);
1052             }
1053         }
1054 
1055         SECTION("implicit type deduction")
1056         {
1057             SECTION("object")
1058             {
1059                 json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} };
1060                 CHECK(j.type() == json::value_t::object);
1061             }
1062 
1063             SECTION("array")
1064             {
1065                 json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 };
1066                 CHECK(j.type() == json::value_t::array);
1067             }
1068         }
1069 
1070         SECTION("explicit type deduction")
1071         {
1072             SECTION("empty object")
1073             {
1074                 json const j = json::object();
1075                 CHECK(j.type() == json::value_t::object);
1076             }
1077 
1078             SECTION("object")
1079             {
1080                 json const j = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
1081                 CHECK(j.type() == json::value_t::object);
1082             }
1083 
1084             SECTION("object with error")
1085             {
1086                 json _;
1087                 CHECK_THROWS_WITH_AS(_ = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), "[json.exception.type_error.301] cannot create object from initializer list", json::type_error&);
1088             }
1089 
1090             SECTION("empty array")
1091             {
1092                 json const j = json::array();
1093                 CHECK(j.type() == json::value_t::array);
1094             }
1095 
1096             SECTION("array")
1097             {
1098                 json const j = json::array({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
1099                 CHECK(j.type() == json::value_t::array);
1100             }
1101         }
1102 
1103         SECTION("move from initializer_list")
1104         {
1105             SECTION("string")
1106             {
1107                 SECTION("constructor with implicit types (array)")
1108                 {
1109                     // This should break through any short string optimization in std::string
1110                     std::string source(1024, '!');
1111                     const auto* source_addr = source.data();
1112                     json j = {std::move(source)};
1113                     const auto* target_addr = j[0].get_ref<std::string const&>().data();
1114                     const bool success = (target_addr == source_addr);
1115                     CHECK(success);
1116                 }
1117 
1118                 SECTION("constructor with implicit types (object)")
1119                 {
1120                     // This should break through any short string optimization in std::string
1121                     std::string source(1024, '!');
1122                     const auto* source_addr = source.data();
1123                     json j = {{"key", std::move(source)}};
1124                     const auto* target_addr = j["key"].get_ref<std::string const&>().data();
1125                     const bool success = (target_addr == source_addr);
1126                     CHECK(success);
1127                 }
1128 
1129                 SECTION("constructor with implicit types (object key)")
1130                 {
1131                     // This should break through any short string optimization in std::string
1132                     std::string source(1024, '!');
1133                     const auto* source_addr = source.data();
1134                     json j = {{std::move(source), 42}};
1135                     const auto* target_addr = j.get_ref<json::object_t&>().begin()->first.data();
1136                     const bool success = (target_addr == source_addr);
1137                     CHECK(success);
1138                 }
1139             }
1140 
1141             SECTION("array")
1142             {
1143                 SECTION("constructor with implicit types (array)")
1144                 {
1145                     json::array_t source = {1, 2, 3};
1146                     const auto* source_addr = source.data();
1147                     json j {std::move(source)};
1148                     const auto* target_addr = j[0].get_ref<json::array_t const&>().data();
1149                     const bool success = (target_addr == source_addr);
1150                     CHECK(success);
1151                 }
1152 
1153                 SECTION("constructor with implicit types (object)")
1154                 {
1155                     json::array_t source = {1, 2, 3};
1156                     const auto* source_addr = source.data();
1157                     json const j {{"key", std::move(source)}};
1158                     const auto* target_addr = j["key"].get_ref<json::array_t const&>().data();
1159                     const bool success = (target_addr == source_addr);
1160                     CHECK(success);
1161                 }
1162 
1163                 SECTION("assignment with implicit types (array)")
1164                 {
1165                     json::array_t source = {1, 2, 3};
1166                     const auto* source_addr = source.data();
1167                     json j = {std::move(source)};
1168                     const auto* target_addr = j[0].get_ref<json::array_t const&>().data();
1169                     const bool success = (target_addr == source_addr);
1170                     CHECK(success);
1171                 }
1172 
1173                 SECTION("assignment with implicit types (object)")
1174                 {
1175                     json::array_t source = {1, 2, 3};
1176                     const auto* source_addr = source.data();
1177                     json j = {{"key", std::move(source)}};
1178                     const auto* target_addr = j["key"].get_ref<json::array_t const&>().data();
1179                     const bool success = (target_addr == source_addr);
1180                     CHECK(success);
1181                 }
1182             }
1183 
1184             SECTION("object")
1185             {
1186                 SECTION("constructor with implicit types (array)")
1187                 {
1188                     json::object_t source = {{"hello", "world"}};
1189                     const json* source_addr = &source.at("hello");
1190                     json j {std::move(source)};
1191                     CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr);
1192                 }
1193 
1194                 SECTION("constructor with implicit types (object)")
1195                 {
1196                     json::object_t source = {{"hello", "world"}};
1197                     const json* source_addr = &source.at("hello");
1198                     json j {{"key", std::move(source)}};
1199                     CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr);
1200                 }
1201 
1202                 SECTION("assignment with implicit types (array)")
1203                 {
1204                     json::object_t source = {{"hello", "world"}};
1205                     const json* source_addr = &source.at("hello");
1206                     json j = {std::move(source)};
1207                     CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr);
1208                 }
1209 
1210                 SECTION("assignment with implicit types (object)")
1211                 {
1212                     json::object_t source = {{"hello", "world"}};
1213                     const json* source_addr = &source.at("hello");
1214                     json j = {{"key", std::move(source)}};
1215                     CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr);
1216                 }
1217             }
1218 
1219             SECTION("json")
1220             {
1221                 SECTION("constructor with implicit types (array)")
1222                 {
1223                     json source {1, 2, 3};
1224                     const json* source_addr = &source[0];
1225                     json j {std::move(source), {}};
1226                     CHECK(&j[0][0] == source_addr);
1227                 }
1228 
1229                 SECTION("constructor with implicit types (object)")
1230                 {
1231                     json source {1, 2, 3};
1232                     const json* source_addr = &source[0];
1233                     json j {{"key", std::move(source)}};
1234                     CHECK(&j["key"][0] == source_addr);
1235                 }
1236 
1237                 SECTION("assignment with implicit types (array)")
1238                 {
1239                     json source {1, 2, 3};
1240                     const json* source_addr = &source[0];
1241                     json j = {std::move(source), {}};
1242                     CHECK(&j[0][0] == source_addr);
1243                 }
1244 
1245                 SECTION("assignment with implicit types (object)")
1246                 {
1247                     json source {1, 2, 3};
1248                     const json* source_addr = &source[0];
1249                     json j = {{"key", std::move(source)}};
1250                     CHECK(&j["key"][0] == source_addr);
1251                 }
1252             }
1253 
1254         }
1255     }
1256 
1257     SECTION("create an array of n copies of a given value")
1258     {
1259         SECTION("cnt = 0")
1260         {
1261             json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
1262             json const arr(0, v);
1263             CHECK(arr.size() == 0);
1264         }
1265 
1266         SECTION("cnt = 1")
1267         {
1268             json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
1269             json const arr(1, v);
1270             CHECK(arr.size() == 1);
1271             for (const auto& x : arr)
1272             {
1273                 CHECK(x == v);
1274             }
1275         }
1276 
1277         SECTION("cnt = 3")
1278         {
1279             json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
1280             json const arr(3, v);
1281             CHECK(arr.size() == 3);
1282             for (const auto& x : arr)
1283             {
1284                 CHECK(x == v);
1285             }
1286         }
1287     }
1288 
1289     SECTION("create a JSON container from an iterator range")
1290     {
1291         SECTION("object")
1292         {
1293             SECTION("json(begin(), end())")
1294             {
1295                 {
1296                     json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1297                     json const j_new(jobject.begin(), jobject.end());
1298                     CHECK(j_new == jobject);
1299                 }
1300                 {
1301                     json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1302                     json const j_new(jobject.cbegin(), jobject.cend());
1303                     CHECK(j_new == jobject);
1304                 }
1305             }
1306 
1307             SECTION("json(begin(), begin())")
1308             {
1309                 {
1310                     json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1311                     json const j_new(jobject.begin(), jobject.begin());
1312                     CHECK(j_new == json::object());
1313                 }
1314                 {
1315                     json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1316                     json const j_new(jobject.cbegin(), jobject.cbegin());
1317                     CHECK(j_new == json::object());
1318                 }
1319             }
1320 
1321             SECTION("construct from subrange")
1322             {
1323                 json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
1324                 json const j_new(jobject.find("b"), jobject.find("e"));
1325                 CHECK(j_new == json({{"b", 1}, {"c", 17u}, {"d", false}}));
1326             }
1327 
1328             SECTION("incompatible iterators")
1329             {
1330                 {
1331                     json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
1332                     json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1333                     CHECK_THROWS_WITH_AS(json(jobject.begin(), jobject2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1334                     CHECK_THROWS_WITH_AS(json(jobject2.begin(), jobject.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1335                 }
1336                 {
1337                     json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
1338                     json const jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
1339                     CHECK_THROWS_WITH_AS(json(jobject.cbegin(), jobject2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1340                     CHECK_THROWS_WITH_AS(json(jobject2.cbegin(), jobject.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1341                 }
1342             }
1343         }
1344 
1345         SECTION("array")
1346         {
1347             SECTION("json(begin(), end())")
1348             {
1349                 {
1350                     json jarray = {1, 2, 3, 4, 5};
1351                     json const j_new(jarray.begin(), jarray.end());
1352                     CHECK(j_new == jarray);
1353                 }
1354                 {
1355                     json const jarray = {1, 2, 3, 4, 5};
1356                     json const j_new(jarray.cbegin(), jarray.cend());
1357                     CHECK(j_new == jarray);
1358                 }
1359             }
1360 
1361             SECTION("json(begin(), begin())")
1362             {
1363                 {
1364                     json jarray = {1, 2, 3, 4, 5};
1365                     json j_new(jarray.begin(), jarray.begin());
1366                     CHECK(j_new == json::array());
1367                 }
1368                 {
1369                     json const jarray = {1, 2, 3, 4, 5};
1370                     json const j_new(jarray.cbegin(), jarray.cbegin());
1371                     CHECK(j_new == json::array());
1372                 }
1373             }
1374 
1375             SECTION("construct from subrange")
1376             {
1377                 {
1378                     json jarray = {1, 2, 3, 4, 5};
1379                     json const j_new(jarray.begin() + 1, jarray.begin() + 3);
1380                     CHECK(j_new == json({2, 3}));
1381                 }
1382                 {
1383                     json const jarray = {1, 2, 3, 4, 5};
1384                     json const j_new(jarray.cbegin() + 1, jarray.cbegin() + 3);
1385                     CHECK(j_new == json({2, 3}));
1386                 }
1387             }
1388 
1389             SECTION("incompatible iterators")
1390             {
1391                 {
1392                     json jarray = {1, 2, 3, 4};
1393                     json jarray2 = {2, 3, 4, 5};
1394                     CHECK_THROWS_WITH_AS(json(jarray.begin(), jarray2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1395                     CHECK_THROWS_WITH_AS(json(jarray2.begin(), jarray.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1396                 }
1397                 {
1398                     json const jarray = {1, 2, 3, 4};
1399                     json const jarray2 = {2, 3, 4, 5};
1400                     CHECK_THROWS_WITH_AS(json(jarray.cbegin(), jarray2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1401                     CHECK_THROWS_WITH_AS(json(jarray2.cbegin(), jarray.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
1402                 }
1403             }
1404         }
1405 
1406         SECTION("other values")
1407         {
1408             SECTION("construct with two valid iterators")
1409             {
1410                 SECTION("null")
1411                 {
1412                     {
1413                         json j;
1414                         CHECK_THROWS_WITH_AS(json(j.begin(), j.end()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&);
1415                     }
1416                     {
1417                         json const j;
1418                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cend()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&);
1419                     }
1420                 }
1421 
1422                 SECTION("string")
1423                 {
1424                     {
1425                         json j = "foo";
1426                         json const j_new(j.begin(), j.end());
1427                         CHECK(j == j_new);
1428                     }
1429                     {
1430                         json const j = "bar";
1431                         json const j_new(j.cbegin(), j.cend());
1432                         CHECK(j == j_new);
1433                     }
1434                 }
1435 
1436                 SECTION("number (boolean)")
1437                 {
1438                     {
1439                         json j = false;
1440                         json const j_new(j.begin(), j.end());
1441                         CHECK(j == j_new);
1442                     }
1443                     {
1444                         json const j = true;
1445                         json const j_new(j.cbegin(), j.cend());
1446                         CHECK(j == j_new);
1447                     }
1448                 }
1449 
1450                 SECTION("number (integer)")
1451                 {
1452                     {
1453                         json j = 17;
1454                         json const j_new(j.begin(), j.end());
1455                         CHECK(j == j_new);
1456                     }
1457                     {
1458                         json const j = 17;
1459                         json const j_new(j.cbegin(), j.cend());
1460                         CHECK(j == j_new);
1461                     }
1462                 }
1463 
1464                 SECTION("number (unsigned)")
1465                 {
1466                     {
1467                         json j = 17u;
1468                         json const j_new(j.begin(), j.end());
1469                         CHECK(j == j_new);
1470                     }
1471                     {
1472                         json const j = 17u;
1473                         json const j_new(j.cbegin(), j.cend());
1474                         CHECK(j == j_new);
1475                     }
1476                 }
1477 
1478                 SECTION("number (floating point)")
1479                 {
1480                     {
1481                         json j = 23.42;
1482                         json const j_new(j.begin(), j.end());
1483                         CHECK(j == j_new);
1484                     }
1485                     {
1486                         json const j = 23.42;
1487                         json const j_new(j.cbegin(), j.cend());
1488                         CHECK(j == j_new);
1489                     }
1490                 }
1491 
1492                 SECTION("binary")
1493                 {
1494                     {
1495                         json j = json::binary({1, 2, 3});
1496                         json const j_new(j.begin(), j.end());
1497                         CHECK((j == j_new));
1498                     }
1499                     {
1500                         json const j = json::binary({1, 2, 3});
1501                         json const j_new(j.cbegin(), j.cend());
1502                         CHECK((j == j_new));
1503                     }
1504                 }
1505             }
1506 
1507             SECTION("construct with two invalid iterators")
1508             {
1509                 SECTION("string")
1510                 {
1511                     {
1512                         json j = "foo";
1513                         CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1514                         CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1515                     }
1516                     {
1517                         json const j = "bar";
1518                         CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1519                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1520                     }
1521                 }
1522 
1523                 SECTION("number (boolean)")
1524                 {
1525                     {
1526                         json j = false;
1527                         CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1528                         CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1529                     }
1530                     {
1531                         json const j = true;
1532                         CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1533                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1534                     }
1535                 }
1536 
1537                 SECTION("number (integer)")
1538                 {
1539                     {
1540                         json j = 17;
1541                         CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1542                         CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1543                     }
1544                     {
1545                         json const j = 17;
1546                         CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1547                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1548                     }
1549                 }
1550 
1551                 SECTION("number (integer)")
1552                 {
1553                     {
1554                         json j = 17u;
1555                         CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1556                         CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1557                     }
1558                     {
1559                         json const j = 17u;
1560                         CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1561                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1562                     }
1563                 }
1564 
1565                 SECTION("number (floating point)")
1566                 {
1567                     {
1568                         json j = 23.42;
1569                         CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1570                         CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1571                     }
1572                     {
1573                         json const j = 23.42;
1574                         CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1575                         CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
1576                     }
1577                 }
1578             }
1579         }
1580     }
1581 }
1582