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