1 //     __ _____ _____ _____
2 //  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3 // |  |  |__   |  |  | | | |  version 3.11.2
4 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5 //
6 // Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
7 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8 // SPDX-License-Identifier: MIT
9 
10 #include "doctest_compatibility.h"
11 
12 #include <nlohmann/json.hpp>
13 using nlohmann::json;
14 
15 TEST_CASE("element access 1")
16 {
17     SECTION("array")
18     {
19         json j = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
20         const json j_const = j;
21 
22         SECTION("access specified element with bounds checking")
23         {
24             SECTION("access within bounds")
25             {
26                 CHECK(j.at(0) == json(1));
27                 CHECK(j.at(1) == json(1u));
28                 CHECK(j.at(2) == json(true));
29                 CHECK(j.at(3) == json(nullptr));
30                 CHECK(j.at(4) == json("string"));
31                 CHECK(j.at(5) == json(42.23));
32                 CHECK(j.at(6) == json::object());
33                 CHECK(j.at(7) == json({1, 2, 3}));
34 
35                 CHECK(j_const.at(0) == json(1));
36                 CHECK(j_const.at(1) == json(1u));
37                 CHECK(j_const.at(2) == json(true));
38                 CHECK(j_const.at(3) == json(nullptr));
39                 CHECK(j_const.at(4) == json("string"));
40                 CHECK(j_const.at(5) == json(42.23));
41                 CHECK(j_const.at(6) == json::object());
42                 CHECK(j_const.at(7) == json({1, 2, 3}));
43             }
44 
45             SECTION("access outside bounds")
46             {
47                 CHECK_THROWS_WITH_AS(j.at(8),
48                                      "[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
49                 CHECK_THROWS_WITH_AS(j_const.at(8),
50                                      "[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
51             }
52 
53             SECTION("access on non-array type")
54             {
55                 SECTION("null")
56                 {
57                     json j_nonarray(json::value_t::null);
58                     const json j_nonarray_const(j_nonarray);
59 
60                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with null", json::type_error&);
61                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with null", json::type_error&);
62                 }
63 
64                 SECTION("boolean")
65                 {
66                     json j_nonarray(json::value_t::boolean);
67                     const json j_nonarray_const(j_nonarray);
68 
69                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&);
70                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&);
71                 }
72 
73                 SECTION("string")
74                 {
75                     json j_nonarray(json::value_t::string);
76                     const json j_nonarray_const(j_nonarray);
77 
78                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with string", json::type_error&);
79                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with string", json::type_error&);
80                 }
81 
82                 SECTION("object")
83                 {
84                     json j_nonarray(json::value_t::object);
85                     const json j_nonarray_const(j_nonarray);
86 
87                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with object", json::type_error&);
88                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with object", json::type_error&);
89                 }
90 
91                 SECTION("number (integer)")
92                 {
93                     json j_nonarray(json::value_t::number_integer);
94                     const json j_nonarray_const(j_nonarray);
95 
96                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
97                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
98                 }
99 
100                 SECTION("number (unsigned)")
101                 {
102                     json j_nonarray(json::value_t::number_unsigned);
103                     const json j_nonarray_const(j_nonarray);
104 
105                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
106                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
107                 }
108 
109                 SECTION("number (floating-point)")
110                 {
111                     json j_nonarray(json::value_t::number_float);
112                     const json j_nonarray_const(j_nonarray);
113 
114                     CHECK_THROWS_WITH_AS(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
115                     CHECK_THROWS_WITH_AS(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number", json::type_error&);
116                 }
117             }
118         }
119 
120         SECTION("front and back")
121         {
122             CHECK(j.front() == json(1));
123             CHECK(j_const.front() == json(1));
124             CHECK(j.back() == json({1, 2, 3}));
125             CHECK(j_const.back() == json({1, 2, 3}));
126         }
127 
128         SECTION("access specified element")
129         {
130             SECTION("access within bounds")
131             {
132                 CHECK(j[0] == json(1));
133                 CHECK(j[1] == json(1u));
134                 CHECK(j[2] == json(true));
135                 CHECK(j[3] == json(nullptr));
136                 CHECK(j[4] == json("string"));
137                 CHECK(j[5] == json(42.23));
138                 CHECK(j[6] == json::object());
139                 CHECK(j[7] == json({1, 2, 3}));
140 
141                 CHECK(j_const[0] == json(1));
142                 CHECK(j_const[1] == json(1u));
143                 CHECK(j_const[2] == json(true));
144                 CHECK(j_const[3] == json(nullptr));
145                 CHECK(j_const[4] == json("string"));
146                 CHECK(j_const[5] == json(42.23));
147                 CHECK(j_const[6] == json::object());
148                 CHECK(j_const[7] == json({1, 2, 3}));
149             }
150 
151             SECTION("access on non-array type")
152             {
153                 SECTION("null")
154                 {
155                     SECTION("standard tests")
156                     {
157                         json j_nonarray(json::value_t::null);
158                         const json j_nonarray_const(j_nonarray);
159                         CHECK_NOTHROW(j_nonarray[0]);
160                         CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with null", json::type_error&);
161                     }
162 
163                     SECTION("implicit transformation to properly filled array")
164                     {
165                         json j_nonarray;
166                         j_nonarray[3] = 42;
167                         CHECK(j_nonarray == json({nullptr, nullptr, nullptr, 42}));
168                     }
169                 }
170 
171                 SECTION("boolean")
172                 {
173                     json j_nonarray(json::value_t::boolean);
174                     const json j_nonarray_const(j_nonarray);
175                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean", json::type_error&);
176                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean", json::type_error&);
177                 }
178 
179                 SECTION("string")
180                 {
181                     json j_nonarray(json::value_t::string);
182                     const json j_nonarray_const(j_nonarray);
183                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string", json::type_error&);
184                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string", json::type_error&);
185                 }
186 
187                 SECTION("object")
188                 {
189                     json j_nonarray(json::value_t::object);
190                     const json j_nonarray_const(j_nonarray);
191                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object", json::type_error&);
192                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object", json::type_error&);
193                 }
194 
195                 SECTION("number (integer)")
196                 {
197                     json j_nonarray(json::value_t::number_integer);
198                     const json j_nonarray_const(j_nonarray);
199                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
200                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
201                 }
202 
203                 SECTION("number (unsigned)")
204                 {
205                     json j_nonarray(json::value_t::number_unsigned);
206                     const json j_nonarray_const(j_nonarray);
207                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
208                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
209                 }
210 
211                 SECTION("number (floating-point)")
212                 {
213                     json j_nonarray(json::value_t::number_float);
214                     const json j_nonarray_const(j_nonarray);
215                     CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
216                     CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
217                 }
218             }
219         }
220 
221         SECTION("remove specified element")
222         {
223             SECTION("remove element by index")
224             {
225                 {
226                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
227                     jarray.erase(0);
228                     CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
229                 }
230                 {
231                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
232                     jarray.erase(1);
233                     CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
234                 }
235                 {
236                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
237                     jarray.erase(2);
238                     CHECK(jarray == json({1, 1u, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
239                 }
240                 {
241                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
242                     jarray.erase(3);
243                     CHECK(jarray == json({1, 1u, true, "string", 42.23, json::object(), {1, 2, 3}}));
244                 }
245                 {
246                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
247                     jarray.erase(4);
248                     CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
249                 }
250                 {
251                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
252                     jarray.erase(5);
253                     CHECK(jarray == json({1, 1u, true, nullptr, "string", json::object(), {1, 2, 3}}));
254                 }
255                 {
256                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
257                     jarray.erase(6);
258                     CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, {1, 2, 3}}));
259                 }
260                 {
261                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
262                     jarray.erase(7);
263                     CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object()}));
264                 }
265                 {
266                     json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
267                     CHECK_THROWS_WITH_AS(jarray.erase(8), "[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
268                 }
269             }
270 
271             SECTION("remove element by iterator")
272             {
273                 SECTION("erase(begin())")
274                 {
275                     {
276                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
277                         json::iterator it2 = jarray.erase(jarray.begin());
278                         CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
279                         CHECK(*it2 == json(1u));
280                     }
281                     {
282                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
283                         json::const_iterator it2 = jarray.erase(jarray.cbegin());
284                         CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
285                         CHECK(*it2 == json(1u));
286                     }
287                 }
288 
289                 SECTION("erase(begin(), end())")
290                 {
291                     {
292                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
293                         json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());
294                         CHECK(jarray == json::array());
295                         CHECK(it2 == jarray.end());
296                     }
297                     {
298                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
299                         json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());
300                         CHECK(jarray == json::array());
301                         CHECK(it2 == jarray.cend());
302                     }
303                 }
304 
305                 SECTION("erase(begin(), begin())")
306                 {
307                     {
308                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
309                         json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());
310                         CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
311                         CHECK(*it2 == json(1));
312                     }
313                     {
314                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
315                         json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());
316                         CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
317                         CHECK(*it2 == json(1));
318                     }
319                 }
320 
321                 SECTION("erase at offset")
322                 {
323                     {
324                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
325                         json::iterator it = jarray.begin() + 4;
326                         json::iterator it2 = jarray.erase(it);
327                         CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
328                         CHECK(*it2 == json(42.23));
329                     }
330                     {
331                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
332                         json::const_iterator it = jarray.cbegin() + 4;
333                         json::const_iterator it2 = jarray.erase(it);
334                         CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
335                         CHECK(*it2 == json(42.23));
336                     }
337                 }
338 
339                 SECTION("erase subrange")
340                 {
341                     {
342                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
343                         json::iterator it2 = jarray.erase(jarray.begin() + 3, jarray.begin() + 6);
344                         CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
345                         CHECK(*it2 == json::object());
346                     }
347                     {
348                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
349                         json::const_iterator it2 = jarray.erase(jarray.cbegin() + 3, jarray.cbegin() + 6);
350                         CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
351                         CHECK(*it2 == json::object());
352                     }
353                 }
354 
355                 SECTION("different arrays")
356                 {
357                     {
358                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
359                         json jarray2 = {"foo", "bar"};
360 
361                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin()),
362                                              "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
363                         CHECK_THROWS_WITH_AS(jarray.erase(jarray.begin(), jarray2.end()),
364                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
365                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray.end()),
366                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
367                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray2.end()),
368                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
369                     }
370                     {
371                         json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
372                         json jarray2 = {"foo", "bar"};
373 
374                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin()),
375                                              "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
376                         CHECK_THROWS_WITH_AS(jarray.erase(jarray.cbegin(), jarray2.cend()),
377                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
378                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray.cend()),
379                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
380                         CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()),
381                                              "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
382                     }
383                 }
384             }
385 
386             SECTION("remove element by index in non-array type")
387             {
388                 SECTION("null")
389                 {
390                     json j_nonobject(json::value_t::null);
391                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
392                 }
393 
394                 SECTION("boolean")
395                 {
396                     json j_nonobject(json::value_t::boolean);
397                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with boolean", json::type_error&);
398                 }
399 
400                 SECTION("string")
401                 {
402                     json j_nonobject(json::value_t::string);
403                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with string", json::type_error&);
404                 }
405 
406                 SECTION("object")
407                 {
408                     json j_nonobject(json::value_t::object);
409                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with object", json::type_error&);
410                 }
411 
412                 SECTION("number (integer)")
413                 {
414                     json j_nonobject(json::value_t::number_integer);
415                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&);
416                 }
417 
418                 SECTION("number (unsigned)")
419                 {
420                     json j_nonobject(json::value_t::number_unsigned);
421                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&);
422                 }
423 
424                 SECTION("number (floating-point)")
425                 {
426                     json j_nonobject(json::value_t::number_float);
427                     CHECK_THROWS_WITH_AS(j_nonobject.erase(0), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&);
428                 }
429             }
430         }
431     }
432 
433     SECTION("other values")
434     {
435         SECTION("front and back")
436         {
437             SECTION("null")
438             {
439                 {
440                     json j;
441                     CHECK_THROWS_WITH_AS(j.front(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
442                     CHECK_THROWS_WITH_AS(j.back(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
443                 }
444                 {
445                     const json j{};
446                     CHECK_THROWS_WITH_AS(j.front(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
447                     CHECK_THROWS_WITH_AS(j.back(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
448                 }
449             }
450 
451             SECTION("string")
452             {
453                 {
454                     json j = "foo";
455                     CHECK(j.front() == j);
456                     CHECK(j.back() == j);
457                 }
458                 {
459                     const json j = "bar";
460                     CHECK(j.front() == j);
461                     CHECK(j.back() == j);
462                 }
463             }
464 
465             SECTION("number (boolean)")
466             {
467                 {
468                     json j = false;
469                     CHECK(j.front() == j);
470                     CHECK(j.back() == j);
471                 }
472                 {
473                     const json j = true;
474                     CHECK(j.front() == j);
475                     CHECK(j.back() == j);
476                 }
477             }
478 
479             SECTION("number (integer)")
480             {
481                 {
482                     json j = 17;
483                     CHECK(j.front() == j);
484                     CHECK(j.back() == j);
485                 }
486                 {
487                     const json j = 17;
488                     CHECK(j.front() == j);
489                     CHECK(j.back() == j);
490                 }
491             }
492 
493             SECTION("number (unsigned)")
494             {
495                 {
496                     json j = 17u;
497                     CHECK(j.front() == j);
498                     CHECK(j.back() == j);
499                 }
500                 {
501                     const json j = 17u;
502                     CHECK(j.front() == j);
503                     CHECK(j.back() == j);
504                 }
505             }
506 
507             SECTION("number (floating point)")
508             {
509                 {
510                     json j = 23.42;
511                     CHECK(j.front() == j);
512                     CHECK(j.back() == j);
513                 }
514                 {
515                     const json j = 23.42;
516                     CHECK(j.front() == j);
517                     CHECK(j.back() == j);
518                 }
519             }
520         }
521 
522         SECTION("erase with one valid iterator")
523         {
524             SECTION("null")
525             {
526                 {
527                     json j;
528                     CHECK_THROWS_WITH_AS(j.erase(j.begin()), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
529                 }
530                 {
531                     json j;
532                     CHECK_THROWS_WITH_AS(j.erase(j.begin()),
533                                          "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
534                 }
535             }
536 
537             SECTION("string")
538             {
539                 {
540                     json j = "foo";
541                     json::iterator it = j.erase(j.begin());
542                     CHECK(j.type() == json::value_t::null);
543                     CHECK(it == j.end());
544                 }
545                 {
546                     json j = "bar";
547                     json::const_iterator it = j.erase(j.cbegin());
548                     CHECK(j.type() == json::value_t::null);
549                     CHECK(it == j.end());
550                 }
551             }
552 
553             SECTION("number (boolean)")
554             {
555                 {
556                     json j = false;
557                     json::iterator it = j.erase(j.begin());
558                     CHECK(j.type() == json::value_t::null);
559                     CHECK(it == j.end());
560                 }
561                 {
562                     json j = true;
563                     json::const_iterator it = j.erase(j.cbegin());
564                     CHECK(j.type() == json::value_t::null);
565                     CHECK(it == j.end());
566                 }
567             }
568 
569             SECTION("number (integer)")
570             {
571                 {
572                     json j = 17;
573                     json::iterator it = j.erase(j.begin());
574                     CHECK(j.type() == json::value_t::null);
575                     CHECK(it == j.end());
576                 }
577                 {
578                     json j = 17;
579                     json::const_iterator it = j.erase(j.cbegin());
580                     CHECK(j.type() == json::value_t::null);
581                     CHECK(it == j.end());
582                 }
583             }
584 
585             SECTION("number (unsigned)")
586             {
587                 {
588                     json j = 17u;
589                     json::iterator it = j.erase(j.begin());
590                     CHECK(j.type() == json::value_t::null);
591                     CHECK(it == j.end());
592                 }
593                 {
594                     json j = 17u;
595                     json::const_iterator it = j.erase(j.cbegin());
596                     CHECK(j.type() == json::value_t::null);
597                     CHECK(it == j.end());
598                 }
599             }
600 
601             SECTION("number (floating point)")
602             {
603                 {
604                     json j = 23.42;
605                     json::iterator it = j.erase(j.begin());
606                     CHECK(j.type() == json::value_t::null);
607                     CHECK(it == j.end());
608                 }
609                 {
610                     json j = 23.42;
611                     json::const_iterator it = j.erase(j.cbegin());
612                     CHECK(j.type() == json::value_t::null);
613                     CHECK(it == j.end());
614                 }
615             }
616 
617             SECTION("binary")
618             {
619                 {
620                     json j = json::binary({1, 2, 3});
621                     json::iterator it = j.erase(j.begin());
622                     CHECK(j.type() == json::value_t::null);
623                     CHECK(it == j.end());
624                 }
625                 {
626                     json j = json::binary({1, 2, 3});
627                     json::const_iterator it = j.erase(j.cbegin());
628                     CHECK(j.type() == json::value_t::null);
629                     CHECK(it == j.end());
630                 }
631             }
632         }
633 
634         SECTION("erase with one invalid iterator")
635         {
636             SECTION("string")
637             {
638                 {
639                     json j = "foo";
640                     CHECK_THROWS_WITH_AS(j.erase(j.end()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
641                 }
642                 {
643                     json j = "bar";
644                     CHECK_THROWS_WITH_AS(j.erase(j.cend()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
645                 }
646             }
647 
648             SECTION("number (boolean)")
649             {
650                 {
651                     json j = false;
652                     CHECK_THROWS_WITH_AS(j.erase(j.end()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
653                 }
654                 {
655                     json j = true;
656                     CHECK_THROWS_WITH_AS(j.erase(j.cend()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
657                 }
658             }
659 
660             SECTION("number (integer)")
661             {
662                 {
663                     json j = 17;
664                     CHECK_THROWS_WITH_AS(j.erase(j.end()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
665                 }
666                 {
667                     json j = 17;
668                     CHECK_THROWS_WITH_AS(j.erase(j.cend()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
669                 }
670             }
671 
672             SECTION("number (unsigned)")
673             {
674                 {
675                     json j = 17u;
676                     CHECK_THROWS_WITH_AS(j.erase(j.end()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
677                 }
678                 {
679                     json j = 17u;
680                     CHECK_THROWS_WITH_AS(j.erase(j.cend()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
681                 }
682             }
683 
684             SECTION("number (floating point)")
685             {
686                 {
687                     json j = 23.42;
688                     CHECK_THROWS_WITH_AS(j.erase(j.end()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
689                 }
690                 {
691                     json j = 23.42;
692                     CHECK_THROWS_WITH_AS(j.erase(j.cend()), "[json.exception.invalid_iterator.205] iterator out of range", json::invalid_iterator&);
693                 }
694             }
695         }
696 
697         SECTION("erase with two valid iterators")
698         {
699             SECTION("null")
700             {
701                 {
702                     json j;
703                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.end()), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
704                 }
705                 {
706                     json j;
707                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cend()), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
708                 }
709             }
710 
711             SECTION("string")
712             {
713                 {
714                     json j = "foo";
715                     json::iterator it = j.erase(j.begin(), j.end());
716                     CHECK(j.type() == json::value_t::null);
717                     CHECK(it == j.end());
718                 }
719                 {
720                     json j = "bar";
721                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
722                     CHECK(j.type() == json::value_t::null);
723                     CHECK(it == j.end());
724                 }
725             }
726 
727             SECTION("number (boolean)")
728             {
729                 {
730                     json j = false;
731                     json::iterator it = j.erase(j.begin(), j.end());
732                     CHECK(j.type() == json::value_t::null);
733                     CHECK(it == j.end());
734                 }
735                 {
736                     json j = true;
737                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
738                     CHECK(j.type() == json::value_t::null);
739                     CHECK(it == j.end());
740                 }
741             }
742 
743             SECTION("number (integer)")
744             {
745                 {
746                     json j = 17;
747                     json::iterator it = j.erase(j.begin(), j.end());
748                     CHECK(j.type() == json::value_t::null);
749                     CHECK(it == j.end());
750                 }
751                 {
752                     json j = 17;
753                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
754                     CHECK(j.type() == json::value_t::null);
755                     CHECK(it == j.end());
756                 }
757             }
758 
759             SECTION("number (unsigned)")
760             {
761                 {
762                     json j = 17u;
763                     json::iterator it = j.erase(j.begin(), j.end());
764                     CHECK(j.type() == json::value_t::null);
765                     CHECK(it == j.end());
766                 }
767                 {
768                     json j = 17u;
769                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
770                     CHECK(j.type() == json::value_t::null);
771                     CHECK(it == j.end());
772                 }
773             }
774 
775             SECTION("number (floating point)")
776             {
777                 {
778                     json j = 23.42;
779                     json::iterator it = j.erase(j.begin(), j.end());
780                     CHECK(j.type() == json::value_t::null);
781                     CHECK(it == j.end());
782                 }
783                 {
784                     json j = 23.42;
785                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
786                     CHECK(j.type() == json::value_t::null);
787                     CHECK(it == j.end());
788                 }
789             }
790 
791             SECTION("binary")
792             {
793                 {
794                     json j = json::binary({1, 2, 3});
795                     json::iterator it = j.erase(j.begin(), j.end());
796                     CHECK(j.type() == json::value_t::null);
797                     CHECK(it == j.end());
798                 }
799                 {
800                     json j = json::binary({1, 2, 3});
801                     json::const_iterator it = j.erase(j.cbegin(), j.cend());
802                     CHECK(j.type() == json::value_t::null);
803                     CHECK(it == j.end());
804                 }
805             }
806         }
807 
808         SECTION("erase with two invalid iterators")
809         {
810             SECTION("string")
811             {
812                 {
813                     json j = "foo";
814                     CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
815                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
816                 }
817                 {
818                     json j = "bar";
819                     CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
820                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
821                 }
822             }
823 
824             SECTION("number (boolean)")
825             {
826                 {
827                     json j = false;
828                     CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
829                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
830                 }
831                 {
832                     json j = true;
833                     CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
834                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
835                 }
836             }
837 
838             SECTION("number (integer)")
839             {
840                 {
841                     json j = 17;
842                     CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
843                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
844                 }
845                 {
846                     json j = 17;
847                     CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
848                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
849                 }
850             }
851 
852             SECTION("number (unsigned)")
853             {
854                 {
855                     json j = 17u;
856                     CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
857                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
858                 }
859                 {
860                     json j = 17u;
861                     CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
862                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
863                 }
864             }
865 
866             SECTION("number (floating point)")
867             {
868                 {
869                     json j = 23.42;
870                     CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
871                     CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
872                 }
873                 {
874                     json j = 23.42;
875                     CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
876                     CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
877                 }
878             }
879         }
880     }
881 }
882