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