• 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 TEST_CASE("iterators 2")
36 {
37     SECTION("iterator comparisons")
38     {
39         json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
40 
41         for (json& j : j_values)
42         {
43             auto it1 = j.begin();
44             auto it2 = j.begin();
45             auto it3 = j.begin();
46             ++it2;
47             ++it3;
48             ++it3;
49             auto it1_c = j.cbegin();
50             auto it2_c = j.cbegin();
51             auto it3_c = j.cbegin();
52             ++it2_c;
53             ++it3_c;
54             ++it3_c;
55 
56             // comparison: equal
57             {
58                 CHECK(it1 == it1);
59                 CHECK(!(it1 == it2));
60                 CHECK(!(it1 == it3));
61                 CHECK(!(it2 == it3));
62                 CHECK(it1_c == it1_c);
63                 CHECK(!(it1_c == it2_c));
64                 CHECK(!(it1_c == it3_c));
65                 CHECK(!(it2_c == it3_c));
66             }
67 
68             // comparison: not equal
69             {
70                 // check definition
71                 CHECK( (it1 != it1) == !(it1 == it1) );
72                 CHECK( (it1 != it2) == !(it1 == it2) );
73                 CHECK( (it1 != it3) == !(it1 == it3) );
74                 CHECK( (it2 != it3) == !(it2 == it3) );
75                 CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );
76                 CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );
77                 CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );
78                 CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );
79             }
80 
81             // comparison: smaller
82             {
83                 if (j.type() == json::value_t::object)
84                 {
85                     CHECK_THROWS_AS(it1 < it1, json::invalid_iterator&);
86                     CHECK_THROWS_AS(it1 < it2, json::invalid_iterator&);
87                     CHECK_THROWS_AS(it2 < it3, json::invalid_iterator&);
88                     CHECK_THROWS_AS(it1 < it3, json::invalid_iterator&);
89                     CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator&);
90                     CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);
91                     CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);
92                     CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);
93 #if JSON_DIAGNOSTICS
94                     CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
95                     CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
96                     CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
97                     CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
98                     CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
99                     CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
100                     CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
101                     CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
102 #else
103                     CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
104                     CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
105                     CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
106                     CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
107                     CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
108                     CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
109                     CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
110                     CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
111 #endif
112                 }
113                 else
114                 {
115                     CHECK(!(it1 < it1));
116                     CHECK(it1 < it2);
117                     CHECK(it1 < it3);
118                     CHECK(it2 < it3);
119                     CHECK(!(it1_c < it1_c));
120                     CHECK(it1_c < it2_c);
121                     CHECK(it1_c < it3_c);
122                     CHECK(it2_c < it3_c);
123                 }
124             }
125 
126             // comparison: less than or equal
127             {
128                 if (j.type() == json::value_t::object)
129                 {
130                     CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator&);
131                     CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator&);
132                     CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator&);
133                     CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator&);
134                     CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator&);
135                     CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);
136                     CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);
137                     CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);
138 #if JSON_DIAGNOSTICS
139                     CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
140                     CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
141                     CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
142                     CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
143                     CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
144                     CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
145                     CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
146                     CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
147 #else
148                     CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
149                     CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
150                     CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
151                     CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
152                     CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
153                     CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
154                     CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
155                     CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
156 #endif
157                 }
158                 else
159                 {
160                     // check definition
161                     CHECK( (it1 <= it1) == !(it1 < it1) );
162                     CHECK( (it1 <= it2) == !(it2 < it1) );
163                     CHECK( (it1 <= it3) == !(it3 < it1) );
164                     CHECK( (it2 <= it3) == !(it3 < it2) );
165                     CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );
166                     CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );
167                     CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );
168                     CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );
169                 }
170             }
171 
172             // comparison: greater than
173             {
174                 if (j.type() == json::value_t::object)
175                 {
176                     CHECK_THROWS_AS(it1 > it1, json::invalid_iterator&);
177                     CHECK_THROWS_AS(it1 > it2, json::invalid_iterator&);
178                     CHECK_THROWS_AS(it2 > it3, json::invalid_iterator&);
179                     CHECK_THROWS_AS(it1 > it3, json::invalid_iterator&);
180                     CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator&);
181                     CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);
182                     CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);
183                     CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);
184 #if JSON_DIAGNOSTICS
185                     CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
186                     CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
187                     CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
188                     CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
189                     CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
190                     CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
191                     CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
192                     CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
193 #else
194                     CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
195                     CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
196                     CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
197                     CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
198                     CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
199                     CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
200                     CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
201                     CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
202 #endif
203                 }
204                 else
205                 {
206                     // check definition
207                     CHECK( (it1 > it1) == (it1 < it1) );
208                     CHECK( (it1 > it2) == (it2 < it1) );
209                     CHECK( (it1 > it3) == (it3 < it1) );
210                     CHECK( (it2 > it3) == (it3 < it2) );
211                     CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
212                     CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
213                     CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
214                     CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
215                 }
216             }
217 
218             // comparison: greater than or equal
219             {
220                 if (j.type() == json::value_t::object)
221                 {
222                     CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator&);
223                     CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator&);
224                     CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator&);
225                     CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator&);
226                     CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator&);
227                     CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);
228                     CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);
229                     CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);
230 #if JSON_DIAGNOSTICS
231                     CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
232                     CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
233                     CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
234                     CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
235                     CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
236                     CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
237                     CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
238                     CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
239 #else
240                     CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
241                     CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
242                     CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
243                     CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
244                     CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
245                     CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
246                     CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
247                     CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
248 #endif
249                 }
250                 else
251                 {
252                     // check definition
253                     CHECK( (it1 >= it1) == !(it1 < it1) );
254                     CHECK( (it1 >= it2) == !(it1 < it2) );
255                     CHECK( (it1 >= it3) == !(it1 < it3) );
256                     CHECK( (it2 >= it3) == !(it2 < it3) );
257                     CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );
258                     CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );
259                     CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );
260                     CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );
261                 }
262             }
263         }
264 
265         // check exceptions if different objects are compared
266         for (auto j : j_values)
267         {
268             for (auto k : j_values)
269             {
270                 if (j != k)
271                 {
272                     CHECK_THROWS_AS(j.begin() == k.begin(), json::invalid_iterator&);
273                     CHECK_THROWS_AS(j.cbegin() == k.cbegin(), json::invalid_iterator&);
274                     CHECK_THROWS_AS(j.begin() < k.begin(), json::invalid_iterator&);
275                     CHECK_THROWS_AS(j.cbegin() < k.cbegin(), json::invalid_iterator&);
276 #if JSON_DIAGNOSTICS
277                     // the output differs in each loop, so we cannot fix a string for the expected exception
278 #else
279                     CHECK_THROWS_WITH(j.begin() == k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
280                     CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
281                     CHECK_THROWS_WITH(j.begin() < k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
282                     CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
283 #endif
284                 }
285             }
286         }
287     }
288 
289     SECTION("iterator arithmetic")
290     {
291         json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
292         json j_array = {1, 2, 3, 4, 5, 6};
293         json j_null = nullptr;
294         json j_value = 42;
295 
296         SECTION("addition and subtraction")
297         {
298             SECTION("object")
299             {
300                 {
301                     auto it = j_object.begin();
302                     CHECK_THROWS_AS(it += 1, json::invalid_iterator&);
303                     CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
304                 }
305                 {
306                     auto it = j_object.cbegin();
307                     CHECK_THROWS_AS(it += 1, json::invalid_iterator&);
308                     CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
309                 }
310                 {
311                     auto it = j_object.begin();
312                     CHECK_THROWS_AS(it + 1, json::invalid_iterator&);
313                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
314                 }
315                 {
316                     auto it = j_object.cbegin();
317                     CHECK_THROWS_AS(it + 1, json::invalid_iterator&);
318                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
319                 }
320                 {
321                     auto it = j_object.begin();
322                     CHECK_THROWS_AS(1 + it, json::invalid_iterator&);
323                     CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
324                 }
325                 {
326                     auto it = j_object.cbegin();
327                     CHECK_THROWS_AS(1 + it, json::invalid_iterator&);
328                     CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
329                 }
330                 {
331                     auto it = j_object.begin();
332                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);
333                     CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
334                 }
335                 {
336                     auto it = j_object.cbegin();
337                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);
338                     CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
339                 }
340                 {
341                     auto it = j_object.begin();
342                     CHECK_THROWS_AS(it - 1, json::invalid_iterator&);
343                     CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
344                 }
345                 {
346                     auto it = j_object.cbegin();
347                     CHECK_THROWS_AS(it - 1, json::invalid_iterator&);
348                     CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
349                 }
350                 {
351                     auto it = j_object.begin();
352                     CHECK_THROWS_AS(it - it, json::invalid_iterator&);
353                     CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
354                 }
355                 {
356                     auto it = j_object.cbegin();
357                     CHECK_THROWS_AS(it - it, json::invalid_iterator&);
358                     CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
359                 }
360             }
361 
362             SECTION("array")
363             {
364                 {
365                     auto it = j_array.begin();
366                     it += 3;
367                     CHECK((j_array.begin() + 3) == it);
368                     CHECK((3 + j_array.begin()) == it);
369                     CHECK((it - 3) == j_array.begin());
370                     CHECK((it - j_array.begin()) == 3);
371                     CHECK(*it == json(4));
372                     it -= 2;
373                     CHECK(*it == json(2));
374                 }
375                 {
376                     auto it = j_array.cbegin();
377                     it += 3;
378                     CHECK((j_array.cbegin() + 3) == it);
379                     CHECK((3 + j_array.cbegin()) == it);
380                     CHECK((it - 3) == j_array.cbegin());
381                     CHECK((it - j_array.cbegin()) == 3);
382                     CHECK(*it == json(4));
383                     it -= 2;
384                     CHECK(*it == json(2));
385                 }
386             }
387 
388             SECTION("null")
389             {
390                 {
391                     auto it = j_null.begin();
392                     it += 3;
393                     CHECK((j_null.begin() + 3) == it);
394                     CHECK((3 + j_null.begin()) == it);
395                     CHECK((it - 3) == j_null.begin());
396                     CHECK((it - j_null.begin()) == 3);
397                     CHECK(it != j_null.end());
398                     it -= 3;
399                     CHECK(it == j_null.end());
400                 }
401                 {
402                     auto it = j_null.cbegin();
403                     it += 3;
404                     CHECK((j_null.cbegin() + 3) == it);
405                     CHECK((3 + j_null.cbegin()) == it);
406                     CHECK((it - 3) == j_null.cbegin());
407                     CHECK((it - j_null.cbegin()) == 3);
408                     CHECK(it != j_null.cend());
409                     it -= 3;
410                     CHECK(it == j_null.cend());
411                 }
412             }
413 
414             SECTION("value")
415             {
416                 {
417                     auto it = j_value.begin();
418                     it += 3;
419                     CHECK((j_value.begin() + 3) == it);
420                     CHECK((3 + j_value.begin()) == it);
421                     CHECK((it - 3) == j_value.begin());
422                     CHECK((it - j_value.begin()) == 3);
423                     CHECK(it != j_value.end());
424                     it -= 3;
425                     CHECK(*it == json(42));
426                 }
427                 {
428                     auto it = j_value.cbegin();
429                     it += 3;
430                     CHECK((j_value.cbegin() + 3) == it);
431                     CHECK((3 + j_value.cbegin()) == it);
432                     CHECK((it - 3) == j_value.cbegin());
433                     CHECK((it - j_value.cbegin()) == 3);
434                     CHECK(it != j_value.cend());
435                     it -= 3;
436                     CHECK(*it == json(42));
437                 }
438             }
439         }
440 
441         SECTION("subscript operator")
442         {
443             SECTION("object")
444             {
445                 {
446                     auto it = j_object.begin();
447                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
448                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
449                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
450                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
451                 }
452                 {
453                     auto it = j_object.cbegin();
454                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
455                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
456                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
457                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
458                 }
459             }
460 
461             SECTION("array")
462             {
463                 {
464                     auto it = j_array.begin();
465                     CHECK(it[0] == json(1));
466                     CHECK(it[1] == json(2));
467                     CHECK(it[2] == json(3));
468                     CHECK(it[3] == json(4));
469                     CHECK(it[4] == json(5));
470                     CHECK(it[5] == json(6));
471                 }
472                 {
473                     auto it = j_array.cbegin();
474                     CHECK(it[0] == json(1));
475                     CHECK(it[1] == json(2));
476                     CHECK(it[2] == json(3));
477                     CHECK(it[3] == json(4));
478                     CHECK(it[4] == json(5));
479                     CHECK(it[5] == json(6));
480                 }
481             }
482 
483             SECTION("null")
484             {
485                 {
486                     auto it = j_null.begin();
487                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
488                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
489                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
490                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
491                 }
492                 {
493                     auto it = j_null.cbegin();
494                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
495                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
496                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
497                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
498                 }
499             }
500 
501             SECTION("value")
502             {
503                 {
504                     auto it = j_value.begin();
505                     CHECK(it[0] == json(42));
506                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
507                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
508                 }
509                 {
510                     auto it = j_value.cbegin();
511                     CHECK(it[0] == json(42));
512                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
513                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
514                 }
515             }
516         }
517     }
518 
519     SECTION("reverse iterator comparisons")
520     {
521         json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
522 
523         for (json& j : j_values)
524         {
525             auto it1 = j.rbegin();
526             auto it2 = j.rbegin();
527             auto it3 = j.rbegin();
528             ++it2;
529             ++it3;
530             ++it3;
531             auto it1_c = j.crbegin();
532             auto it2_c = j.crbegin();
533             auto it3_c = j.crbegin();
534             ++it2_c;
535             ++it3_c;
536             ++it3_c;
537 
538             // comparison: equal
539             {
540                 CHECK(it1 == it1);
541                 CHECK(!(it1 == it2));
542                 CHECK(!(it1 == it3));
543                 CHECK(!(it2 == it3));
544                 CHECK(it1_c == it1_c);
545                 CHECK(!(it1_c == it2_c));
546                 CHECK(!(it1_c == it3_c));
547                 CHECK(!(it2_c == it3_c));
548             }
549 
550             // comparison: not equal
551             {
552                 // check definition
553                 CHECK( (it1 != it1) == !(it1 == it1) );
554                 CHECK( (it1 != it2) == !(it1 == it2) );
555                 CHECK( (it1 != it3) == !(it1 == it3) );
556                 CHECK( (it2 != it3) == !(it2 == it3) );
557                 CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );
558                 CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );
559                 CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );
560                 CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );
561             }
562 
563             // comparison: smaller
564             {
565                 if (j.type() == json::value_t::object)
566                 {
567                     CHECK_THROWS_AS(it1 < it1, json::invalid_iterator&);
568                     CHECK_THROWS_AS(it1 < it2, json::invalid_iterator&);
569                     CHECK_THROWS_AS(it2 < it3, json::invalid_iterator&);
570                     CHECK_THROWS_AS(it1 < it3, json::invalid_iterator&);
571                     CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator&);
572                     CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);
573                     CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);
574                     CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);
575 #if JSON_DIAGNOSTICS
576                     CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
577                     CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
578                     CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
579                     CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
580                     CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
581                     CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
582                     CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
583                     CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
584 #else
585                     CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
586                     CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
587                     CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
588                     CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
589                     CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
590                     CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
591                     CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
592                     CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
593 #endif
594                 }
595                 else
596                 {
597                     CHECK(!(it1 < it1));
598                     CHECK(it1 < it2);
599                     CHECK(it1 < it3);
600                     CHECK(it2 < it3);
601                     CHECK(!(it1_c < it1_c));
602                     CHECK(it1_c < it2_c);
603                     CHECK(it1_c < it3_c);
604                     CHECK(it2_c < it3_c);
605                 }
606             }
607 
608             // comparison: less than or equal
609             {
610                 if (j.type() == json::value_t::object)
611                 {
612                     CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator&);
613                     CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator&);
614                     CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator&);
615                     CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator&);
616                     CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator&);
617                     CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);
618                     CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);
619                     CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);
620 #if JSON_DIAGNOSTICS
621                     CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
622                     CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
623                     CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
624                     CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
625                     CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
626                     CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
627                     CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
628                     CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
629 #else
630                     CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
631                     CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
632                     CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
633                     CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
634                     CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
635                     CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
636                     CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
637                     CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
638 #endif
639                 }
640                 else
641                 {
642                     // check definition
643                     CHECK( (it1 <= it1) == !(it1 < it1) );
644                     CHECK( (it1 <= it2) == !(it2 < it1) );
645                     CHECK( (it1 <= it3) == !(it3 < it1) );
646                     CHECK( (it2 <= it3) == !(it3 < it2) );
647                     CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );
648                     CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );
649                     CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );
650                     CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );
651                 }
652             }
653 
654             // comparison: greater than
655             {
656                 if (j.type() == json::value_t::object)
657                 {
658                     CHECK_THROWS_AS(it1 > it1, json::invalid_iterator&);
659                     CHECK_THROWS_AS(it1 > it2, json::invalid_iterator&);
660                     CHECK_THROWS_AS(it2 > it3, json::invalid_iterator&);
661                     CHECK_THROWS_AS(it1 > it3, json::invalid_iterator&);
662                     CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator&);
663                     CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);
664                     CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);
665                     CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);
666 #if JSON_DIAGNOSTICS
667                     CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
668                     CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
669                     CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
670                     CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
671                     CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
672                     CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
673                     CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
674                     CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
675 #else
676                     CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
677                     CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
678                     CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
679                     CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
680                     CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
681                     CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
682                     CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
683                     CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
684 #endif
685                 }
686                 else
687                 {
688                     // check definition
689                     CHECK( (it1 > it1) == (it1 < it1) );
690                     CHECK( (it1 > it2) == (it2 < it1) );
691                     CHECK( (it1 > it3) == (it3 < it1) );
692                     CHECK( (it2 > it3) == (it3 < it2) );
693                     CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
694                     CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
695                     CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
696                     CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
697                 }
698             }
699 
700             // comparison: greater than or equal
701             {
702                 if (j.type() == json::value_t::object)
703                 {
704                     CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator&);
705                     CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator&);
706                     CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator&);
707                     CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator&);
708                     CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator&);
709                     CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);
710                     CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);
711                     CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);
712 #if JSON_DIAGNOSTICS
713                     CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
714                     CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
715                     CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
716                     CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
717                     CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
718                     CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
719                     CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
720                     CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
721 #else
722                     CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
723                     CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
724                     CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
725                     CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
726                     CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
727                     CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
728                     CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
729                     CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
730 #endif
731                 }
732                 else
733                 {
734                     // check definition
735                     CHECK( (it1 >= it1) == !(it1 < it1) );
736                     CHECK( (it1 >= it2) == !(it1 < it2) );
737                     CHECK( (it1 >= it3) == !(it1 < it3) );
738                     CHECK( (it2 >= it3) == !(it2 < it3) );
739                     CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );
740                     CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );
741                     CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );
742                     CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );
743                 }
744             }
745         }
746 
747         // check exceptions if different objects are compared
748         for (auto j : j_values)
749         {
750             for (auto k : j_values)
751             {
752                 if (j != k)
753                 {
754                     CHECK_THROWS_AS(j.rbegin() == k.rbegin(), json::invalid_iterator&);
755                     CHECK_THROWS_AS(j.crbegin() == k.crbegin(), json::invalid_iterator&);
756                     CHECK_THROWS_AS(j.rbegin() < k.rbegin(), json::invalid_iterator&);
757                     CHECK_THROWS_AS(j.crbegin() < k.crbegin(), json::invalid_iterator&);
758 #if JSON_DIAGNOSTICS
759                     // the output differs in each loop, so we cannot fix a string for the expected exception
760 #else
761                     CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
762                     CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
763                     CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
764                     CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
765 #endif
766                 }
767             }
768         }
769     }
770 
771     SECTION("reverse iterator arithmetic")
772     {
773         json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
774         json j_array = {1, 2, 3, 4, 5, 6};
775         json j_null = nullptr;
776         json j_value = 42;
777 
778         SECTION("addition and subtraction")
779         {
780             SECTION("object")
781             {
782                 {
783                     auto it = j_object.rbegin();
784                     CHECK_THROWS_AS(it += 1, json::invalid_iterator&);
785                     CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
786                 }
787                 {
788                     auto it = j_object.crbegin();
789                     CHECK_THROWS_AS(it += 1, json::invalid_iterator&);
790                     CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
791                 }
792                 {
793                     auto it = j_object.rbegin();
794                     CHECK_THROWS_AS(it + 1, json::invalid_iterator&);
795                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
796                 }
797                 {
798                     auto it = j_object.crbegin();
799                     CHECK_THROWS_AS(it + 1, json::invalid_iterator&);
800                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
801                 }
802                 {
803                     auto it = j_object.rbegin();
804                     CHECK_THROWS_AS(1 + it, json::invalid_iterator&);
805                     CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
806                 }
807                 {
808                     auto it = j_object.crbegin();
809                     CHECK_THROWS_AS(1 + it, json::invalid_iterator&);
810                     CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
811                 }
812                 {
813                     auto it = j_object.rbegin();
814                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);
815                     CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
816                 }
817                 {
818                     auto it = j_object.crbegin();
819                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);
820                     CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
821                 }
822                 {
823                     auto it = j_object.rbegin();
824                     CHECK_THROWS_AS(it - 1, json::invalid_iterator&);
825                     CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
826                 }
827                 {
828                     auto it = j_object.crbegin();
829                     CHECK_THROWS_AS(it - 1, json::invalid_iterator&);
830                     CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
831                 }
832                 {
833                     auto it = j_object.rbegin();
834                     CHECK_THROWS_AS(it - it, json::invalid_iterator&);
835                     CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
836                 }
837                 {
838                     auto it = j_object.crbegin();
839                     CHECK_THROWS_AS(it - it, json::invalid_iterator&);
840                     CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
841                 }
842             }
843 
844             SECTION("array")
845             {
846                 {
847                     auto it = j_array.rbegin();
848                     it += 3;
849                     CHECK((j_array.rbegin() + 3) == it);
850                     CHECK(json::reverse_iterator(3 + j_array.rbegin()) == it);
851                     CHECK((it - 3) == j_array.rbegin());
852                     CHECK((it - j_array.rbegin()) == 3);
853                     CHECK(*it == json(3));
854                     it -= 2;
855                     CHECK(*it == json(5));
856                 }
857                 {
858                     auto it = j_array.crbegin();
859                     it += 3;
860                     CHECK((j_array.crbegin() + 3) == it);
861                     CHECK(json::const_reverse_iterator(3 + j_array.crbegin()) == it);
862                     CHECK((it - 3) == j_array.crbegin());
863                     CHECK((it - j_array.crbegin()) == 3);
864                     CHECK(*it == json(3));
865                     it -= 2;
866                     CHECK(*it == json(5));
867                 }
868             }
869 
870             SECTION("null")
871             {
872                 {
873                     auto it = j_null.rbegin();
874                     it += 3;
875                     CHECK((j_null.rbegin() + 3) == it);
876                     CHECK(json::reverse_iterator(3 + j_null.rbegin()) == it);
877                     CHECK((it - 3) == j_null.rbegin());
878                     CHECK((it - j_null.rbegin()) == 3);
879                     CHECK(it != j_null.rend());
880                     it -= 3;
881                     CHECK(it == j_null.rend());
882                 }
883                 {
884                     auto it = j_null.crbegin();
885                     it += 3;
886                     CHECK((j_null.crbegin() + 3) == it);
887                     CHECK(json::const_reverse_iterator(3 + j_null.crbegin()) == it);
888                     CHECK((it - 3) == j_null.crbegin());
889                     CHECK((it - j_null.crbegin()) == 3);
890                     CHECK(it != j_null.crend());
891                     it -= 3;
892                     CHECK(it == j_null.crend());
893                 }
894             }
895 
896             SECTION("value")
897             {
898                 {
899                     auto it = j_value.rbegin();
900                     it += 3;
901                     CHECK((j_value.rbegin() + 3) == it);
902                     CHECK(json::reverse_iterator(3 + j_value.rbegin()) == it);
903                     CHECK((it - 3) == j_value.rbegin());
904                     CHECK((it - j_value.rbegin()) == 3);
905                     CHECK(it != j_value.rend());
906                     it -= 3;
907                     CHECK(*it == json(42));
908                 }
909                 {
910                     auto it = j_value.crbegin();
911                     it += 3;
912                     CHECK((j_value.crbegin() + 3) == it);
913                     CHECK(json::const_reverse_iterator(3 + j_value.crbegin()) == it);
914                     CHECK((it - 3) == j_value.crbegin());
915                     CHECK((it - j_value.crbegin()) == 3);
916                     CHECK(it != j_value.crend());
917                     it -= 3;
918                     CHECK(*it == json(42));
919                 }
920             }
921         }
922 
923         SECTION("subscript operator")
924         {
925             SECTION("object")
926             {
927                 {
928                     auto it = j_object.rbegin();
929                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
930                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
931                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
932                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
933                 }
934                 {
935                     auto it = j_object.crbegin();
936                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
937                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
938                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
939                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
940                 }
941             }
942 
943             SECTION("array")
944             {
945                 {
946                     auto it = j_array.rbegin();
947                     CHECK(it[0] == json(6));
948                     CHECK(it[1] == json(5));
949                     CHECK(it[2] == json(4));
950                     CHECK(it[3] == json(3));
951                     CHECK(it[4] == json(2));
952                     CHECK(it[5] == json(1));
953                 }
954                 {
955                     auto it = j_array.crbegin();
956                     CHECK(it[0] == json(6));
957                     CHECK(it[1] == json(5));
958                     CHECK(it[2] == json(4));
959                     CHECK(it[3] == json(3));
960                     CHECK(it[4] == json(2));
961                     CHECK(it[5] == json(1));
962                 }
963             }
964 
965             SECTION("null")
966             {
967                 {
968                     auto it = j_null.rbegin();
969                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
970                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
971                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
972                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
973                 }
974                 {
975                     auto it = j_null.crbegin();
976                     CHECK_THROWS_AS(it[0], json::invalid_iterator&);
977                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
978                     CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
979                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
980                 }
981             }
982 
983             SECTION("value")
984             {
985                 {
986                     auto it = j_value.rbegin();
987                     CHECK(it[0] == json(42));
988                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
989                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
990                 }
991                 {
992                     auto it = j_value.crbegin();
993                     CHECK(it[0] == json(42));
994                     CHECK_THROWS_AS(it[1], json::invalid_iterator&);
995                     CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
996                 }
997             }
998         }
999     }
1000 }
1001