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