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