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