1 // __ _____ _____ _____ 2 // __| | __| | | | JSON for Modern C++ (supporting code) 3 // | | |__ | | | | | | version 3.11.3 4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 // 6 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me> 7 // SPDX-License-Identifier: MIT 8 9 #include "doctest_compatibility.h" 10 11 #define JSON_TESTS_PRIVATE 12 #include <nlohmann/json.hpp> 13 using nlohmann::json; 14 15 #include <deque> 16 #include <forward_list> 17 #include <fstream> 18 #include <list> 19 #include <set> 20 #include <unordered_map> 21 #include <unordered_set> 22 #include <valarray> 23 24 TEST_CASE("constructors") 25 { 26 SECTION("create an empty value with a given type") 27 { 28 SECTION("null") 29 { 30 auto const t = json::value_t::null; 31 json const j(t); 32 CHECK(j.type() == t); 33 } 34 35 SECTION("discarded") 36 { 37 auto const t = json::value_t::discarded; 38 json const j(t); 39 CHECK(j.type() == t); 40 } 41 42 SECTION("object") 43 { 44 auto const t = json::value_t::object; 45 json const j(t); 46 CHECK(j.type() == t); 47 } 48 49 SECTION("array") 50 { 51 auto const t = json::value_t::array; 52 json const j(t); 53 CHECK(j.type() == t); 54 } 55 56 SECTION("boolean") 57 { 58 auto const t = json::value_t::boolean; 59 json const j(t); 60 CHECK(j.type() == t); 61 CHECK(j == false); 62 } 63 64 SECTION("string") 65 { 66 auto const t = json::value_t::string; 67 json const j(t); 68 CHECK(j.type() == t); 69 CHECK(j == ""); 70 } 71 72 SECTION("number_integer") 73 { 74 auto const t = json::value_t::number_integer; 75 json const j(t); 76 CHECK(j.type() == t); 77 CHECK(j == 0); 78 } 79 80 SECTION("number_unsigned") 81 { 82 auto const t = json::value_t::number_unsigned; 83 json const j(t); 84 CHECK(j.type() == t); 85 CHECK(j == 0); 86 } 87 88 SECTION("number_float") 89 { 90 auto const t = json::value_t::number_float; 91 json const j(t); 92 CHECK(j.type() == t); 93 CHECK(j == 0.0); 94 } 95 96 SECTION("binary") 97 { 98 auto const t = json::value_t::binary; 99 json const j(t); 100 CHECK(j.type() == t); 101 CHECK(j == json::binary({})); 102 } 103 } 104 105 SECTION("create a null object (implicitly)") 106 { 107 SECTION("no parameter") 108 { 109 json const j{}; 110 CHECK(j.type() == json::value_t::null); 111 } 112 } 113 114 SECTION("create a null object (explicitly)") 115 { 116 SECTION("parameter") 117 { 118 json const j(nullptr); 119 CHECK(j.type() == json::value_t::null); 120 } 121 } 122 123 SECTION("create an object (explicit)") 124 { 125 SECTION("empty object") 126 { 127 json::object_t const o{}; 128 json const j(o); 129 CHECK(j.type() == json::value_t::object); 130 } 131 132 SECTION("filled object") 133 { 134 json::object_t const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 135 json const j(o); 136 CHECK(j.type() == json::value_t::object); 137 } 138 } 139 140 SECTION("create an object (implicit)") 141 { 142 // reference object 143 json::object_t const o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 144 json const j_reference(o_reference); 145 146 SECTION("std::map<json::string_t, json>") 147 { 148 std::map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 149 json const j(o); 150 CHECK(j.type() == json::value_t::object); 151 CHECK(j == j_reference); 152 } 153 154 SECTION("std::map<std::string, std::string> #600") 155 { 156 const std::map<std::string, std::string> m 157 { 158 {"a", "b"}, 159 {"c", "d"}, 160 {"e", "f"}, 161 }; 162 163 json const j(m); 164 CHECK((j.get<decltype(m)>() == m)); 165 } 166 167 SECTION("std::map<const char*, json>") 168 { 169 std::map<const char*, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 170 json const j(o); 171 CHECK(j.type() == json::value_t::object); 172 CHECK(j == j_reference); 173 } 174 175 SECTION("std::multimap<json::string_t, json>") 176 { 177 std::multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 178 json const j(o); 179 CHECK(j.type() == json::value_t::object); 180 CHECK(j == j_reference); 181 } 182 183 SECTION("std::unordered_map<json::string_t, json>") 184 { 185 std::unordered_map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 186 json const j(o); 187 CHECK(j.type() == json::value_t::object); 188 CHECK(j == j_reference); 189 } 190 191 SECTION("std::unordered_multimap<json::string_t, json>") 192 { 193 std::unordered_multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; 194 json const j(o); 195 CHECK(j.type() == json::value_t::object); 196 CHECK(j == j_reference); 197 } 198 199 SECTION("associative container literal") 200 { 201 json const j({{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}); 202 CHECK(j.type() == json::value_t::object); 203 CHECK(j == j_reference); 204 } 205 } 206 207 SECTION("create an array (explicit)") 208 { 209 SECTION("empty array") 210 { 211 json::array_t const a{}; 212 json const j(a); 213 CHECK(j.type() == json::value_t::array); 214 } 215 216 SECTION("filled array") 217 { 218 json::array_t const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 219 json const j(a); 220 CHECK(j.type() == json::value_t::array); 221 } 222 } 223 224 SECTION("create an array (implicit)") 225 { 226 // reference array 227 json::array_t const a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 228 json const j_reference(a_reference); 229 230 SECTION("std::list<json>") 231 { 232 std::list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 233 json const j(a); 234 CHECK(j.type() == json::value_t::array); 235 CHECK(j == j_reference); 236 } 237 238 SECTION("std::pair") 239 { 240 std::pair<float, std::string> const p{1.0f, "string"}; 241 json const j(p); 242 243 CHECK(j.type() == json::value_t::array); 244 CHECK(j.get<decltype(p)>() == p); 245 REQUIRE(j.size() == 2); 246 CHECK(j[0] == std::get<0>(p)); 247 CHECK(j[1] == std::get<1>(p)); 248 } 249 250 SECTION("std::pair with discarded values") 251 { 252 json const j{1, 2.0, "string"}; 253 254 const auto p = j.get<std::pair<int, float>>(); 255 CHECK(p.first == j[0]); 256 CHECK(p.second == j[1]); 257 } 258 259 SECTION("std::tuple") 260 { 261 const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector<int> {0, 1}); 262 json const j(t); 263 264 CHECK(j.type() == json::value_t::array); 265 REQUIRE(j.size() == 4); 266 CHECK(j.get<decltype(t)>() == t); 267 CHECK(j[0] == std::get<0>(t)); 268 CHECK(j[1] == std::get<1>(t)); 269 CHECK(j[2] == std::get<2>(t)); 270 CHECK(j[3][0] == 0); 271 CHECK(j[3][1] == 1); 272 } 273 274 SECTION("std::tuple with discarded values") 275 { 276 json const j{1, 2.0, "string", 42}; 277 278 const auto t = j.get<std::tuple<int, float, std::string>>(); 279 CHECK(std::get<0>(t) == j[0]); 280 CHECK(std::get<1>(t) == j[1]); 281 // CHECK(std::get<2>(t) == j[2]); // commented out due to CI issue, see https://github.com/nlohmann/json/pull/3985 and https://github.com/nlohmann/json/issues/4025 282 } 283 284 SECTION("std::pair/tuple/array failures") 285 { 286 json const j{1}; 287 288 CHECK_THROWS_WITH_AS((j.get<std::pair<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); 289 CHECK_THROWS_WITH_AS((j.get<std::tuple<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); 290 CHECK_THROWS_WITH_AS((j.get<std::array<int, 3>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); 291 } 292 293 SECTION("std::forward_list<json>") 294 { 295 std::forward_list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 296 json const j(a); 297 CHECK(j.type() == json::value_t::array); 298 CHECK(j == j_reference); 299 } 300 301 SECTION("std::array<json, 6>") 302 { 303 std::array<json, 6> const a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}}; 304 json const j(a); 305 CHECK(j.type() == json::value_t::array); 306 CHECK(j == j_reference); 307 308 const auto a2 = j.get<std::array<json, 6>>(); 309 CHECK(a2 == a); 310 } 311 312 SECTION("std::valarray<int>") 313 { 314 std::valarray<int> const va = {1, 2, 3, 4, 5}; 315 json const j(va); 316 CHECK(j.type() == json::value_t::array); 317 CHECK(j == json({1, 2, 3, 4, 5})); 318 319 auto jva = j.get<std::valarray<int>>(); 320 CHECK(jva.size() == va.size()); 321 for (size_t i = 0; i < jva.size(); ++i) 322 { 323 CHECK(va[i] == jva[i]); 324 } 325 } 326 327 SECTION("std::valarray<double>") 328 { 329 std::valarray<double> const va = {1.2, 2.3, 3.4, 4.5, 5.6}; 330 json const j(va); 331 CHECK(j.type() == json::value_t::array); 332 CHECK(j == json({1.2, 2.3, 3.4, 4.5, 5.6})); 333 334 auto jva = j.get<std::valarray<double>>(); 335 CHECK(jva.size() == va.size()); 336 for (size_t i = 0; i < jva.size(); ++i) 337 { 338 CHECK(va[i] == jva[i]); 339 } 340 } 341 342 SECTION("std::vector<json>") 343 { 344 std::vector<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 345 json const j(a); 346 CHECK(j.type() == json::value_t::array); 347 CHECK(j == j_reference); 348 } 349 350 SECTION("std::deque<json>") 351 { 352 std::deque<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 353 json const j(a); 354 CHECK(j.type() == json::value_t::array); 355 CHECK(j == j_reference); 356 } 357 358 SECTION("std::set<json>") 359 { 360 std::set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 361 json const j(a); 362 CHECK(j.type() == json::value_t::array); 363 // we cannot really check for equality here 364 } 365 366 SECTION("std::unordered_set<json>") 367 { 368 std::unordered_set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; 369 json const j(a); 370 CHECK(j.type() == json::value_t::array); 371 // we cannot really check for equality here 372 } 373 374 SECTION("sequence container literal") 375 { 376 json const j({json(1), json(1u), json(2.2), json(false), json("string"), json()}); 377 CHECK(j.type() == json::value_t::array); 378 CHECK(j == j_reference); 379 } 380 } 381 382 SECTION("create a string (explicit)") 383 { 384 SECTION("empty string") 385 { 386 json::string_t const s{}; 387 json const j(s); 388 CHECK(j.type() == json::value_t::string); 389 } 390 391 SECTION("filled string") 392 { 393 json::string_t const s {"Hello world"}; 394 json const j(s); 395 CHECK(j.type() == json::value_t::string); 396 } 397 } 398 399 SECTION("create a string (implicit)") 400 { 401 // reference string 402 json::string_t const s_reference {"Hello world"}; 403 json const j_reference(s_reference); 404 405 SECTION("std::string") 406 { 407 std::string const s {"Hello world"}; 408 json const j(s); 409 CHECK(j.type() == json::value_t::string); 410 CHECK(j == j_reference); 411 } 412 413 SECTION("char[]") 414 { 415 char const s[] {"Hello world"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 416 json const j(s); 417 CHECK(j.type() == json::value_t::string); 418 CHECK(j == j_reference); 419 } 420 421 SECTION("const char*") 422 { 423 const char* s {"Hello world"}; 424 json const j(s); 425 CHECK(j.type() == json::value_t::string); 426 CHECK(j == j_reference); 427 } 428 429 SECTION("string literal") 430 { 431 json const j("Hello world"); 432 CHECK(j.type() == json::value_t::string); 433 CHECK(j == j_reference); 434 } 435 } 436 437 SECTION("create a boolean (explicit)") 438 { 439 SECTION("empty boolean") 440 { 441 json::boolean_t const b{}; 442 json const j(b); 443 CHECK(j.type() == json::value_t::boolean); 444 } 445 446 SECTION("filled boolean (true)") 447 { 448 json const j(true); 449 CHECK(j.type() == json::value_t::boolean); 450 } 451 452 SECTION("filled boolean (false)") 453 { 454 json const j(false); 455 CHECK(j.type() == json::value_t::boolean); 456 } 457 458 SECTION("from std::vector<bool>::reference") 459 { 460 std::vector<bool> v{true}; 461 json const j(v[0]); 462 CHECK(std::is_same<decltype(v[0]), std::vector<bool>::reference>::value); 463 CHECK(j.type() == json::value_t::boolean); 464 } 465 466 SECTION("from std::vector<bool>::const_reference") 467 { 468 const std::vector<bool> v{true}; 469 json const j(v[0]); 470 CHECK(std::is_same<decltype(v[0]), std::vector<bool>::const_reference>::value); 471 CHECK(j.type() == json::value_t::boolean); 472 } 473 } 474 475 SECTION("create a binary (explicit)") 476 { 477 SECTION("empty binary") 478 { 479 json::binary_t const b{}; 480 json const j(b); 481 CHECK(j.type() == json::value_t::binary); 482 } 483 484 SECTION("filled binary") 485 { 486 json::binary_t const b({1, 2, 3}); 487 json const j(b); 488 CHECK(j.type() == json::value_t::binary); 489 } 490 } 491 492 SECTION("create an integer number (explicit)") 493 { 494 SECTION("uninitialized value") 495 { 496 json::number_integer_t const n{}; 497 json const j(n); 498 CHECK(j.type() == json::value_t::number_integer); 499 } 500 501 SECTION("initialized value") 502 { 503 json::number_integer_t const n(42); 504 json const j(n); 505 CHECK(j.type() == json::value_t::number_integer); 506 } 507 } 508 509 SECTION("create an integer number (implicit)") 510 { 511 // reference objects 512 json::number_integer_t const n_reference = 42; 513 json const j_reference(n_reference); 514 json::number_unsigned_t const n_unsigned_reference = 42; 515 json const j_unsigned_reference(n_unsigned_reference); 516 517 SECTION("short") 518 { 519 short const n = 42; 520 json const j(n); 521 CHECK(j.type() == json::value_t::number_integer); 522 CHECK(j == j_reference); 523 } 524 525 SECTION("unsigned short") 526 { 527 unsigned short const n = 42; 528 json const j(n); 529 CHECK(j.type() == json::value_t::number_unsigned); 530 CHECK(j == j_unsigned_reference); 531 } 532 533 SECTION("int") 534 { 535 int const n = 42; 536 json const j(n); 537 CHECK(j.type() == json::value_t::number_integer); 538 CHECK(j == j_reference); 539 } 540 541 SECTION("unsigned int") 542 { 543 unsigned int const n = 42; 544 json const j(n); 545 CHECK(j.type() == json::value_t::number_unsigned); 546 CHECK(j == j_unsigned_reference); 547 } 548 549 SECTION("long") 550 { 551 long const n = 42; 552 json const j(n); 553 CHECK(j.type() == json::value_t::number_integer); 554 CHECK(j == j_reference); 555 } 556 557 SECTION("unsigned long") 558 { 559 unsigned long const n = 42; 560 json const j(n); 561 CHECK(j.type() == json::value_t::number_unsigned); 562 CHECK(j == j_unsigned_reference); 563 } 564 565 SECTION("long long") 566 { 567 long long const n = 42; 568 json const j(n); 569 CHECK(j.type() == json::value_t::number_integer); 570 CHECK(j == j_reference); 571 } 572 573 SECTION("unsigned long long") 574 { 575 unsigned long long const n = 42; 576 json const j(n); 577 CHECK(j.type() == json::value_t::number_unsigned); 578 CHECK(j == j_unsigned_reference); 579 } 580 581 SECTION("int8_t") 582 { 583 int8_t const n = 42; 584 json const j(n); 585 CHECK(j.type() == json::value_t::number_integer); 586 CHECK(j == j_reference); 587 } 588 589 SECTION("int16_t") 590 { 591 int16_t const n = 42; 592 json const j(n); 593 CHECK(j.type() == json::value_t::number_integer); 594 CHECK(j == j_reference); 595 } 596 597 SECTION("int32_t") 598 { 599 int32_t const n = 42; 600 json const j(n); 601 CHECK(j.type() == json::value_t::number_integer); 602 CHECK(j == j_reference); 603 } 604 605 SECTION("int64_t") 606 { 607 int64_t const n = 42; 608 json const j(n); 609 CHECK(j.type() == json::value_t::number_integer); 610 CHECK(j == j_reference); 611 } 612 613 SECTION("int_fast8_t") 614 { 615 int_fast8_t const n = 42; 616 json const j(n); 617 CHECK(j.type() == json::value_t::number_integer); 618 CHECK(j == j_reference); 619 } 620 621 SECTION("int_fast16_t") 622 { 623 int_fast16_t const n = 42; 624 json const j(n); 625 CHECK(j.type() == json::value_t::number_integer); 626 CHECK(j == j_reference); 627 } 628 629 SECTION("int_fast32_t") 630 { 631 int_fast32_t const n = 42; 632 json const j(n); 633 CHECK(j.type() == json::value_t::number_integer); 634 CHECK(j == j_reference); 635 } 636 637 SECTION("int_fast64_t") 638 { 639 int_fast64_t const n = 42; 640 json const j(n); 641 CHECK(j.type() == json::value_t::number_integer); 642 CHECK(j == j_reference); 643 } 644 645 SECTION("int_least8_t") 646 { 647 int_least8_t const n = 42; 648 json const j(n); 649 CHECK(j.type() == json::value_t::number_integer); 650 CHECK(j == j_reference); 651 } 652 653 SECTION("int_least16_t") 654 { 655 int_least16_t const n = 42; 656 json const j(n); 657 CHECK(j.type() == json::value_t::number_integer); 658 CHECK(j == j_reference); 659 } 660 661 SECTION("int_least32_t") 662 { 663 int_least32_t const n = 42; 664 json const j(n); 665 CHECK(j.type() == json::value_t::number_integer); 666 CHECK(j == j_reference); 667 } 668 669 SECTION("int_least64_t") 670 { 671 int_least64_t const n = 42; 672 json const j(n); 673 CHECK(j.type() == json::value_t::number_integer); 674 CHECK(j == j_reference); 675 } 676 677 SECTION("uint8_t") 678 { 679 uint8_t const n = 42; 680 json const j(n); 681 CHECK(j.type() == json::value_t::number_unsigned); 682 CHECK(j == j_unsigned_reference); 683 } 684 685 SECTION("uint16_t") 686 { 687 uint16_t const n = 42; 688 json const j(n); 689 CHECK(j.type() == json::value_t::number_unsigned); 690 CHECK(j == j_unsigned_reference); 691 } 692 693 SECTION("uint32_t") 694 { 695 uint32_t const n = 42; 696 json const j(n); 697 CHECK(j.type() == json::value_t::number_unsigned); 698 CHECK(j == j_unsigned_reference); 699 } 700 701 SECTION("uint64_t") 702 { 703 uint64_t const n = 42; 704 json const j(n); 705 CHECK(j.type() == json::value_t::number_unsigned); 706 CHECK(j == j_unsigned_reference); 707 } 708 709 SECTION("uint_fast8_t") 710 { 711 uint_fast8_t const n = 42; 712 json const j(n); 713 CHECK(j.type() == json::value_t::number_unsigned); 714 CHECK(j == j_unsigned_reference); 715 } 716 717 SECTION("uint_fast16_t") 718 { 719 uint_fast16_t const n = 42; 720 json const j(n); 721 CHECK(j.type() == json::value_t::number_unsigned); 722 CHECK(j == j_unsigned_reference); 723 } 724 725 SECTION("uint_fast32_t") 726 { 727 uint_fast32_t const n = 42; 728 json const j(n); 729 CHECK(j.type() == json::value_t::number_unsigned); 730 CHECK(j == j_unsigned_reference); 731 } 732 733 SECTION("uint_fast64_t") 734 { 735 uint_fast64_t const n = 42; 736 json const j(n); 737 CHECK(j.type() == json::value_t::number_unsigned); 738 CHECK(j == j_unsigned_reference); 739 } 740 741 SECTION("uint_least8_t") 742 { 743 uint_least8_t const n = 42; 744 json const j(n); 745 CHECK(j.type() == json::value_t::number_unsigned); 746 CHECK(j == j_unsigned_reference); 747 } 748 749 SECTION("uint_least16_t") 750 { 751 uint_least16_t const n = 42; 752 json const j(n); 753 CHECK(j.type() == json::value_t::number_unsigned); 754 CHECK(j == j_unsigned_reference); 755 } 756 757 SECTION("uint_least32_t") 758 { 759 uint_least32_t const n = 42; 760 json const j(n); 761 CHECK(j.type() == json::value_t::number_unsigned); 762 CHECK(j == j_unsigned_reference); 763 } 764 765 SECTION("uint_least64_t") 766 { 767 uint_least64_t const n = 42; 768 json const j(n); 769 CHECK(j.type() == json::value_t::number_unsigned); 770 CHECK(j == j_unsigned_reference); 771 } 772 773 SECTION("integer literal without suffix") 774 { 775 json const j(42); 776 CHECK(j.type() == json::value_t::number_integer); 777 CHECK(j == j_reference); 778 } 779 780 SECTION("integer literal with u suffix") 781 { 782 json j(42u); 783 CHECK(j.type() == json::value_t::number_unsigned); 784 CHECK(j == j_unsigned_reference); 785 } 786 787 SECTION("integer literal with l suffix") 788 { 789 json const j(42L); 790 CHECK(j.type() == json::value_t::number_integer); 791 CHECK(j == j_reference); 792 } 793 794 SECTION("integer literal with ul suffix") 795 { 796 json j(42ul); 797 CHECK(j.type() == json::value_t::number_unsigned); 798 CHECK(j == j_unsigned_reference); 799 } 800 801 SECTION("integer literal with ll suffix") 802 { 803 json const j(42LL); 804 CHECK(j.type() == json::value_t::number_integer); 805 CHECK(j == j_reference); 806 } 807 808 SECTION("integer literal with ull suffix") 809 { 810 json j(42ull); 811 CHECK(j.type() == json::value_t::number_unsigned); 812 CHECK(j == j_unsigned_reference); 813 } 814 } 815 816 SECTION("create a floating-point number (explicit)") 817 { 818 SECTION("uninitialized value") 819 { 820 json::number_float_t const n{}; 821 json const j(n); 822 CHECK(j.type() == json::value_t::number_float); 823 } 824 825 SECTION("initialized value") 826 { 827 json::number_float_t const n(42.23); 828 json const j(n); 829 CHECK(j.type() == json::value_t::number_float); 830 } 831 832 SECTION("NaN") 833 { 834 // NaN is stored properly, but serialized to null 835 json::number_float_t const n(std::numeric_limits<json::number_float_t>::quiet_NaN()); 836 json const j(n); 837 CHECK(j.type() == json::value_t::number_float); 838 839 // check round trip of NaN 840 json::number_float_t const d{j}; 841 CHECK((std::isnan(d) && std::isnan(n)) == true); 842 843 // check that NaN is serialized to null 844 CHECK(j.dump() == "null"); 845 } 846 847 SECTION("infinity") 848 { 849 // infinity is stored properly, but serialized to null 850 json::number_float_t const n(std::numeric_limits<json::number_float_t>::infinity()); 851 json const j(n); 852 CHECK(j.type() == json::value_t::number_float); 853 854 // check round trip of infinity 855 json::number_float_t const d{j}; 856 CHECK(d == n); 857 858 // check that inf is serialized to null 859 CHECK(j.dump() == "null"); 860 } 861 } 862 863 SECTION("create a floating-point number (implicit)") 864 { 865 // reference object 866 json::number_float_t const n_reference = 42.23; 867 json const j_reference(n_reference); 868 869 SECTION("float") 870 { 871 float const n = 42.23f; 872 json const j(n); 873 CHECK(j.type() == json::value_t::number_float); 874 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 875 } 876 877 SECTION("double") 878 { 879 double const n = 42.23; 880 json const j(n); 881 CHECK(j.type() == json::value_t::number_float); 882 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 883 } 884 885 SECTION("long double") 886 { 887 long double const n = 42.23L; 888 json const j(n); 889 CHECK(j.type() == json::value_t::number_float); 890 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 891 } 892 893 SECTION("floating-point literal without suffix") 894 { 895 json const j(42.23); 896 CHECK(j.type() == json::value_t::number_float); 897 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 898 } 899 900 SECTION("integer literal with f suffix") 901 { 902 json const j(42.23f); 903 CHECK(j.type() == json::value_t::number_float); 904 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 905 } 906 907 SECTION("integer literal with l suffix") 908 { 909 json const j(42.23L); 910 CHECK(j.type() == json::value_t::number_float); 911 CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float)); 912 } 913 } 914 915 SECTION("create a container (array or object) from an initializer list") 916 { 917 SECTION("empty initializer list") 918 { 919 SECTION("explicit") 920 { 921 json const j(json::initializer_list_t {}); 922 CHECK(j.type() == json::value_t::object); 923 } 924 925 SECTION("implicit") 926 { 927 json const j {}; 928 CHECK(j.type() == json::value_t::null); 929 } 930 } 931 932 SECTION("one element") 933 { 934 SECTION("array") 935 { 936 SECTION("explicit") 937 { 938 json const j(json::initializer_list_t {json(json::array_t())}); 939 CHECK(j.type() == json::value_t::array); 940 } 941 942 SECTION("implicit") 943 { 944 json const j {json::array_t()}; 945 CHECK(j.type() == json::value_t::array); 946 } 947 } 948 949 SECTION("object") 950 { 951 SECTION("explicit") 952 { 953 json const j(json::initializer_list_t {json(json::object_t())}); 954 CHECK(j.type() == json::value_t::array); 955 } 956 957 SECTION("implicit") 958 { 959 json const j {json::object_t()}; 960 CHECK(j.type() == json::value_t::array); 961 } 962 } 963 964 SECTION("string") 965 { 966 SECTION("explicit") 967 { 968 json const j(json::initializer_list_t {json("Hello world")}); 969 CHECK(j.type() == json::value_t::array); 970 } 971 972 SECTION("implicit") 973 { 974 json const j {"Hello world"}; 975 CHECK(j.type() == json::value_t::array); 976 } 977 } 978 979 SECTION("boolean") 980 { 981 SECTION("explicit") 982 { 983 json const j(json::initializer_list_t {json(true)}); 984 CHECK(j.type() == json::value_t::array); 985 } 986 987 SECTION("implicit") 988 { 989 json const j {true}; 990 CHECK(j.type() == json::value_t::array); 991 } 992 } 993 994 SECTION("number (integer)") 995 { 996 SECTION("explicit") 997 { 998 json const j(json::initializer_list_t {json(1)}); 999 CHECK(j.type() == json::value_t::array); 1000 } 1001 1002 SECTION("implicit") 1003 { 1004 json const j {1}; 1005 CHECK(j.type() == json::value_t::array); 1006 } 1007 } 1008 1009 SECTION("number (unsigned)") 1010 { 1011 SECTION("explicit") 1012 { 1013 json const j(json::initializer_list_t {json(1u)}); 1014 CHECK(j.type() == json::value_t::array); 1015 } 1016 1017 SECTION("implicit") 1018 { 1019 json const j {1u}; 1020 CHECK(j.type() == json::value_t::array); 1021 } 1022 } 1023 1024 SECTION("number (floating-point)") 1025 { 1026 SECTION("explicit") 1027 { 1028 json const j(json::initializer_list_t {json(42.23)}); 1029 CHECK(j.type() == json::value_t::array); 1030 } 1031 1032 SECTION("implicit") 1033 { 1034 json const j {42.23}; 1035 CHECK(j.type() == json::value_t::array); 1036 } 1037 } 1038 } 1039 1040 SECTION("more elements") 1041 { 1042 SECTION("explicit") 1043 { 1044 json const j(json::initializer_list_t {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()}); 1045 CHECK(j.type() == json::value_t::array); 1046 } 1047 1048 SECTION("implicit") 1049 { 1050 json const j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()}; 1051 CHECK(j.type() == json::value_t::array); 1052 } 1053 } 1054 1055 SECTION("implicit type deduction") 1056 { 1057 SECTION("object") 1058 { 1059 json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }; 1060 CHECK(j.type() == json::value_t::object); 1061 } 1062 1063 SECTION("array") 1064 { 1065 json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }; 1066 CHECK(j.type() == json::value_t::array); 1067 } 1068 } 1069 1070 SECTION("explicit type deduction") 1071 { 1072 SECTION("empty object") 1073 { 1074 json const j = json::object(); 1075 CHECK(j.type() == json::value_t::object); 1076 } 1077 1078 SECTION("object") 1079 { 1080 json const j = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }); 1081 CHECK(j.type() == json::value_t::object); 1082 } 1083 1084 SECTION("object with error") 1085 { 1086 json _; 1087 CHECK_THROWS_WITH_AS(_ = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), "[json.exception.type_error.301] cannot create object from initializer list", json::type_error&); 1088 } 1089 1090 SECTION("empty array") 1091 { 1092 json const j = json::array(); 1093 CHECK(j.type() == json::value_t::array); 1094 } 1095 1096 SECTION("array") 1097 { 1098 json const j = json::array({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }); 1099 CHECK(j.type() == json::value_t::array); 1100 } 1101 } 1102 1103 SECTION("move from initializer_list") 1104 { 1105 SECTION("string") 1106 { 1107 SECTION("constructor with implicit types (array)") 1108 { 1109 // This should break through any short string optimization in std::string 1110 std::string source(1024, '!'); 1111 const auto* source_addr = source.data(); 1112 json j = {std::move(source)}; 1113 const auto* target_addr = j[0].get_ref<std::string const&>().data(); 1114 const bool success = (target_addr == source_addr); 1115 CHECK(success); 1116 } 1117 1118 SECTION("constructor with implicit types (object)") 1119 { 1120 // This should break through any short string optimization in std::string 1121 std::string source(1024, '!'); 1122 const auto* source_addr = source.data(); 1123 json j = {{"key", std::move(source)}}; 1124 const auto* target_addr = j["key"].get_ref<std::string const&>().data(); 1125 const bool success = (target_addr == source_addr); 1126 CHECK(success); 1127 } 1128 1129 SECTION("constructor with implicit types (object key)") 1130 { 1131 // This should break through any short string optimization in std::string 1132 std::string source(1024, '!'); 1133 const auto* source_addr = source.data(); 1134 json j = {{std::move(source), 42}}; 1135 const auto* target_addr = j.get_ref<json::object_t&>().begin()->first.data(); 1136 const bool success = (target_addr == source_addr); 1137 CHECK(success); 1138 } 1139 } 1140 1141 SECTION("array") 1142 { 1143 SECTION("constructor with implicit types (array)") 1144 { 1145 json::array_t source = {1, 2, 3}; 1146 const auto* source_addr = source.data(); 1147 json j {std::move(source)}; 1148 const auto* target_addr = j[0].get_ref<json::array_t const&>().data(); 1149 const bool success = (target_addr == source_addr); 1150 CHECK(success); 1151 } 1152 1153 SECTION("constructor with implicit types (object)") 1154 { 1155 json::array_t source = {1, 2, 3}; 1156 const auto* source_addr = source.data(); 1157 json const j {{"key", std::move(source)}}; 1158 const auto* target_addr = j["key"].get_ref<json::array_t const&>().data(); 1159 const bool success = (target_addr == source_addr); 1160 CHECK(success); 1161 } 1162 1163 SECTION("assignment with implicit types (array)") 1164 { 1165 json::array_t source = {1, 2, 3}; 1166 const auto* source_addr = source.data(); 1167 json j = {std::move(source)}; 1168 const auto* target_addr = j[0].get_ref<json::array_t const&>().data(); 1169 const bool success = (target_addr == source_addr); 1170 CHECK(success); 1171 } 1172 1173 SECTION("assignment with implicit types (object)") 1174 { 1175 json::array_t source = {1, 2, 3}; 1176 const auto* source_addr = source.data(); 1177 json j = {{"key", std::move(source)}}; 1178 const auto* target_addr = j["key"].get_ref<json::array_t const&>().data(); 1179 const bool success = (target_addr == source_addr); 1180 CHECK(success); 1181 } 1182 } 1183 1184 SECTION("object") 1185 { 1186 SECTION("constructor with implicit types (array)") 1187 { 1188 json::object_t source = {{"hello", "world"}}; 1189 const json* source_addr = &source.at("hello"); 1190 json j {std::move(source)}; 1191 CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr); 1192 } 1193 1194 SECTION("constructor with implicit types (object)") 1195 { 1196 json::object_t source = {{"hello", "world"}}; 1197 const json* source_addr = &source.at("hello"); 1198 json j {{"key", std::move(source)}}; 1199 CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr); 1200 } 1201 1202 SECTION("assignment with implicit types (array)") 1203 { 1204 json::object_t source = {{"hello", "world"}}; 1205 const json* source_addr = &source.at("hello"); 1206 json j = {std::move(source)}; 1207 CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr); 1208 } 1209 1210 SECTION("assignment with implicit types (object)") 1211 { 1212 json::object_t source = {{"hello", "world"}}; 1213 const json* source_addr = &source.at("hello"); 1214 json j = {{"key", std::move(source)}}; 1215 CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr); 1216 } 1217 } 1218 1219 SECTION("json") 1220 { 1221 SECTION("constructor with implicit types (array)") 1222 { 1223 json source {1, 2, 3}; 1224 const json* source_addr = &source[0]; 1225 json j {std::move(source), {}}; 1226 CHECK(&j[0][0] == source_addr); 1227 } 1228 1229 SECTION("constructor with implicit types (object)") 1230 { 1231 json source {1, 2, 3}; 1232 const json* source_addr = &source[0]; 1233 json j {{"key", std::move(source)}}; 1234 CHECK(&j["key"][0] == source_addr); 1235 } 1236 1237 SECTION("assignment with implicit types (array)") 1238 { 1239 json source {1, 2, 3}; 1240 const json* source_addr = &source[0]; 1241 json j = {std::move(source), {}}; 1242 CHECK(&j[0][0] == source_addr); 1243 } 1244 1245 SECTION("assignment with implicit types (object)") 1246 { 1247 json source {1, 2, 3}; 1248 const json* source_addr = &source[0]; 1249 json j = {{"key", std::move(source)}}; 1250 CHECK(&j["key"][0] == source_addr); 1251 } 1252 } 1253 1254 } 1255 } 1256 1257 SECTION("create an array of n copies of a given value") 1258 { 1259 SECTION("cnt = 0") 1260 { 1261 json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; 1262 json const arr(0, v); 1263 CHECK(arr.size() == 0); 1264 } 1265 1266 SECTION("cnt = 1") 1267 { 1268 json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; 1269 json const arr(1, v); 1270 CHECK(arr.size() == 1); 1271 for (const auto& x : arr) 1272 { 1273 CHECK(x == v); 1274 } 1275 } 1276 1277 SECTION("cnt = 3") 1278 { 1279 json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; 1280 json const arr(3, v); 1281 CHECK(arr.size() == 3); 1282 for (const auto& x : arr) 1283 { 1284 CHECK(x == v); 1285 } 1286 } 1287 } 1288 1289 SECTION("create a JSON container from an iterator range") 1290 { 1291 SECTION("object") 1292 { 1293 SECTION("json(begin(), end())") 1294 { 1295 { 1296 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1297 json const j_new(jobject.begin(), jobject.end()); 1298 CHECK(j_new == jobject); 1299 } 1300 { 1301 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1302 json const j_new(jobject.cbegin(), jobject.cend()); 1303 CHECK(j_new == jobject); 1304 } 1305 } 1306 1307 SECTION("json(begin(), begin())") 1308 { 1309 { 1310 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1311 json const j_new(jobject.begin(), jobject.begin()); 1312 CHECK(j_new == json::object()); 1313 } 1314 { 1315 json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1316 json const j_new(jobject.cbegin(), jobject.cbegin()); 1317 CHECK(j_new == json::object()); 1318 } 1319 } 1320 1321 SECTION("construct from subrange") 1322 { 1323 json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 1324 json const j_new(jobject.find("b"), jobject.find("e")); 1325 CHECK(j_new == json({{"b", 1}, {"c", 17u}, {"d", false}})); 1326 } 1327 1328 SECTION("incompatible iterators") 1329 { 1330 { 1331 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 1332 json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1333 CHECK_THROWS_WITH_AS(json(jobject.begin(), jobject2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1334 CHECK_THROWS_WITH_AS(json(jobject2.begin(), jobject.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1335 } 1336 { 1337 json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 1338 json const jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 1339 CHECK_THROWS_WITH_AS(json(jobject.cbegin(), jobject2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1340 CHECK_THROWS_WITH_AS(json(jobject2.cbegin(), jobject.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1341 } 1342 } 1343 } 1344 1345 SECTION("array") 1346 { 1347 SECTION("json(begin(), end())") 1348 { 1349 { 1350 json jarray = {1, 2, 3, 4, 5}; 1351 json const j_new(jarray.begin(), jarray.end()); 1352 CHECK(j_new == jarray); 1353 } 1354 { 1355 json const jarray = {1, 2, 3, 4, 5}; 1356 json const j_new(jarray.cbegin(), jarray.cend()); 1357 CHECK(j_new == jarray); 1358 } 1359 } 1360 1361 SECTION("json(begin(), begin())") 1362 { 1363 { 1364 json jarray = {1, 2, 3, 4, 5}; 1365 json j_new(jarray.begin(), jarray.begin()); 1366 CHECK(j_new == json::array()); 1367 } 1368 { 1369 json const jarray = {1, 2, 3, 4, 5}; 1370 json const j_new(jarray.cbegin(), jarray.cbegin()); 1371 CHECK(j_new == json::array()); 1372 } 1373 } 1374 1375 SECTION("construct from subrange") 1376 { 1377 { 1378 json jarray = {1, 2, 3, 4, 5}; 1379 json const j_new(jarray.begin() + 1, jarray.begin() + 3); 1380 CHECK(j_new == json({2, 3})); 1381 } 1382 { 1383 json const jarray = {1, 2, 3, 4, 5}; 1384 json const j_new(jarray.cbegin() + 1, jarray.cbegin() + 3); 1385 CHECK(j_new == json({2, 3})); 1386 } 1387 } 1388 1389 SECTION("incompatible iterators") 1390 { 1391 { 1392 json jarray = {1, 2, 3, 4}; 1393 json jarray2 = {2, 3, 4, 5}; 1394 CHECK_THROWS_WITH_AS(json(jarray.begin(), jarray2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1395 CHECK_THROWS_WITH_AS(json(jarray2.begin(), jarray.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1396 } 1397 { 1398 json const jarray = {1, 2, 3, 4}; 1399 json const jarray2 = {2, 3, 4, 5}; 1400 CHECK_THROWS_WITH_AS(json(jarray.cbegin(), jarray2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1401 CHECK_THROWS_WITH_AS(json(jarray2.cbegin(), jarray.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); 1402 } 1403 } 1404 } 1405 1406 SECTION("other values") 1407 { 1408 SECTION("construct with two valid iterators") 1409 { 1410 SECTION("null") 1411 { 1412 { 1413 json j; 1414 CHECK_THROWS_WITH_AS(json(j.begin(), j.end()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&); 1415 } 1416 { 1417 json const j; 1418 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cend()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&); 1419 } 1420 } 1421 1422 SECTION("string") 1423 { 1424 { 1425 json j = "foo"; 1426 json const j_new(j.begin(), j.end()); 1427 CHECK(j == j_new); 1428 } 1429 { 1430 json const j = "bar"; 1431 json const j_new(j.cbegin(), j.cend()); 1432 CHECK(j == j_new); 1433 } 1434 } 1435 1436 SECTION("number (boolean)") 1437 { 1438 { 1439 json j = false; 1440 json const j_new(j.begin(), j.end()); 1441 CHECK(j == j_new); 1442 } 1443 { 1444 json const j = true; 1445 json const j_new(j.cbegin(), j.cend()); 1446 CHECK(j == j_new); 1447 } 1448 } 1449 1450 SECTION("number (integer)") 1451 { 1452 { 1453 json j = 17; 1454 json const j_new(j.begin(), j.end()); 1455 CHECK(j == j_new); 1456 } 1457 { 1458 json const j = 17; 1459 json const j_new(j.cbegin(), j.cend()); 1460 CHECK(j == j_new); 1461 } 1462 } 1463 1464 SECTION("number (unsigned)") 1465 { 1466 { 1467 json j = 17u; 1468 json const j_new(j.begin(), j.end()); 1469 CHECK(j == j_new); 1470 } 1471 { 1472 json const j = 17u; 1473 json const j_new(j.cbegin(), j.cend()); 1474 CHECK(j == j_new); 1475 } 1476 } 1477 1478 SECTION("number (floating point)") 1479 { 1480 { 1481 json j = 23.42; 1482 json const j_new(j.begin(), j.end()); 1483 CHECK(j == j_new); 1484 } 1485 { 1486 json const j = 23.42; 1487 json const j_new(j.cbegin(), j.cend()); 1488 CHECK(j == j_new); 1489 } 1490 } 1491 1492 SECTION("binary") 1493 { 1494 { 1495 json j = json::binary({1, 2, 3}); 1496 json const j_new(j.begin(), j.end()); 1497 CHECK((j == j_new)); 1498 } 1499 { 1500 json const j = json::binary({1, 2, 3}); 1501 json const j_new(j.cbegin(), j.cend()); 1502 CHECK((j == j_new)); 1503 } 1504 } 1505 } 1506 1507 SECTION("construct with two invalid iterators") 1508 { 1509 SECTION("string") 1510 { 1511 { 1512 json j = "foo"; 1513 CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1514 CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1515 } 1516 { 1517 json const j = "bar"; 1518 CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1519 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1520 } 1521 } 1522 1523 SECTION("number (boolean)") 1524 { 1525 { 1526 json j = false; 1527 CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1528 CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1529 } 1530 { 1531 json const j = true; 1532 CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1533 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1534 } 1535 } 1536 1537 SECTION("number (integer)") 1538 { 1539 { 1540 json j = 17; 1541 CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1542 CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1543 } 1544 { 1545 json const j = 17; 1546 CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1547 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1548 } 1549 } 1550 1551 SECTION("number (integer)") 1552 { 1553 { 1554 json j = 17u; 1555 CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1556 CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1557 } 1558 { 1559 json const j = 17u; 1560 CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1561 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1562 } 1563 } 1564 1565 SECTION("number (floating point)") 1566 { 1567 { 1568 json j = 23.42; 1569 CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1570 CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1571 } 1572 { 1573 json const j = 23.42; 1574 CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1575 CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); 1576 } 1577 } 1578 } 1579 } 1580 } 1581 } 1582