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