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