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