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