• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
12 using 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.
15 DOCTEST_GCC_SUPPRESS_WARNING_PUSH
16 #if DOCTEST_GCC >= DOCTEST_COMPILER(11, 0, 0)
17     DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct")
18 #endif
19 DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
20 DOCTEST_CLANG_SUPPRESS_WARNING("-Wrange-loop-construct")
21 
22 TEST_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 
719 TEST_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 
1432 DOCTEST_GCC_SUPPRESS_WARNING_POP
1433 DOCTEST_CLANG_SUPPRESS_WARNING_POP
1434