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>
13using nlohmann::json;
14
15TEST_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