00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #define CATCH_CONFIG_MAIN
00030 #include "catch.hpp"
00031
00032 #include <array>
00033 #include <deque>
00034 #include <forward_list>
00035 #include <list>
00036 #include <map>
00037 #include <set>
00038 #include <string>
00039 #include <unordered_map>
00040 #include <unordered_set>
00041 #include <vector>
00042
00043 #define private public
00044 #include "json.hpp"
00045 using nlohmann::json;
00046
00047
00048 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
00049 #pragma GCC diagnostic ignored "-Wfloat-equal"
00050 #endif
00051
00052 TEST_CASE("constructors")
00053 {
00054 SECTION("create an empty value with a given type")
00055 {
00056 SECTION("null")
00057 {
00058 auto t = json::value_t::null;
00059 json j(t);
00060 CHECK(j.type() == t);
00061 }
00062
00063 SECTION("discarded")
00064 {
00065 auto t = json::value_t::discarded;
00066 json j(t);
00067 CHECK(j.type() == t);
00068 }
00069
00070 SECTION("object")
00071 {
00072 auto t = json::value_t::object;
00073 json j(t);
00074 CHECK(j.type() == t);
00075 }
00076
00077 SECTION("array")
00078 {
00079 auto t = json::value_t::array;
00080 json j(t);
00081 CHECK(j.type() == t);
00082 }
00083
00084 SECTION("boolean")
00085 {
00086 auto t = json::value_t::boolean;
00087 json j(t);
00088 CHECK(j.type() == t);
00089 }
00090
00091 SECTION("string")
00092 {
00093 auto t = json::value_t::string;
00094 json j(t);
00095 CHECK(j.type() == t);
00096 }
00097
00098 SECTION("number_integer")
00099 {
00100 auto t = json::value_t::number_integer;
00101 json j(t);
00102 CHECK(j.type() == t);
00103 }
00104
00105 SECTION("number_unsigned")
00106 {
00107 auto t = json::value_t::number_unsigned;
00108 json j(t);
00109 CHECK(j.type() == t);
00110 }
00111
00112 SECTION("number_float")
00113 {
00114 auto t = json::value_t::number_float;
00115 json j(t);
00116 CHECK(j.type() == t);
00117 }
00118 }
00119
00120 SECTION("create a null object (implicitly)")
00121 {
00122 SECTION("no parameter")
00123 {
00124 json j{};
00125 CHECK(j.type() == json::value_t::null);
00126 }
00127 }
00128
00129 SECTION("create a null object (explicitly)")
00130 {
00131 SECTION("parameter")
00132 {
00133 json j(nullptr);
00134 CHECK(j.type() == json::value_t::null);
00135 }
00136 }
00137
00138 SECTION("create an object (explicit)")
00139 {
00140 SECTION("empty object")
00141 {
00142 json::object_t o;
00143 json j(o);
00144 CHECK(j.type() == json::value_t::object);
00145 }
00146
00147 SECTION("filled object")
00148 {
00149 json::object_t o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00150 json j(o);
00151 CHECK(j.type() == json::value_t::object);
00152 }
00153 }
00154
00155 SECTION("create an object (implicit)")
00156 {
00157
00158 json::object_t o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00159 json j_reference(o_reference);
00160
00161 SECTION("std::map<json::string_t, json>")
00162 {
00163 std::map<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00164 json j(o);
00165 CHECK(j.type() == json::value_t::object);
00166 CHECK(j == j_reference);
00167 }
00168
00169 SECTION("std::map<const char*, json>")
00170 {
00171 std::map<const char*, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00172 json j(o);
00173 CHECK(j.type() == json::value_t::object);
00174 CHECK(j == j_reference);
00175 }
00176
00177 SECTION("std::multimap<json::string_t, json>")
00178 {
00179 std::multimap<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00180 json j(o);
00181 CHECK(j.type() == json::value_t::object);
00182 CHECK(j == j_reference);
00183 }
00184
00185 SECTION("std::unordered_map<json::string_t, json>")
00186 {
00187 std::unordered_map<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00188 json j(o);
00189 CHECK(j.type() == json::value_t::object);
00190 CHECK(j == j_reference);
00191 }
00192
00193 SECTION("std::unordered_multimap<json::string_t, json>")
00194 {
00195 std::unordered_multimap<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
00196 json j(o);
00197 CHECK(j.type() == json::value_t::object);
00198 CHECK(j == j_reference);
00199 }
00200
00201 SECTION("associative container literal")
00202 {
00203 json j({{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}});
00204 CHECK(j.type() == json::value_t::object);
00205 CHECK(j == j_reference);
00206 }
00207 }
00208
00209 SECTION("create an array (explicit)")
00210 {
00211 SECTION("empty array")
00212 {
00213 json::array_t a;
00214 json j(a);
00215 CHECK(j.type() == json::value_t::array);
00216 }
00217
00218 SECTION("filled array")
00219 {
00220 json::array_t a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00221 json j(a);
00222 CHECK(j.type() == json::value_t::array);
00223 }
00224 }
00225
00226 SECTION("create an array (implicit)")
00227 {
00228
00229 json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00230 json j_reference(a_reference);
00231
00232 SECTION("std::list<json>")
00233 {
00234 std::list<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00235 json j(a);
00236 CHECK(j.type() == json::value_t::array);
00237 CHECK(j == j_reference);
00238 }
00239
00240 SECTION("std::forward_list<json>")
00241 {
00242 std::forward_list<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00243 json j(a);
00244 CHECK(j.type() == json::value_t::array);
00245 CHECK(j == j_reference);
00246 }
00247
00248 SECTION("std::array<json, 5>")
00249 {
00250 std::array<json, 6> a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}};
00251 json j(a);
00252 CHECK(j.type() == json::value_t::array);
00253 CHECK(j == j_reference);
00254 }
00255
00256 SECTION("std::vector<json>")
00257 {
00258 std::vector<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00259 json j(a);
00260 CHECK(j.type() == json::value_t::array);
00261 CHECK(j == j_reference);
00262 }
00263
00264 SECTION("std::deque<json>")
00265 {
00266 std::deque<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00267 json j(a);
00268 CHECK(j.type() == json::value_t::array);
00269 CHECK(j == j_reference);
00270 }
00271
00272 SECTION("std::set<json>")
00273 {
00274 std::set<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00275 json j(a);
00276 CHECK(j.type() == json::value_t::array);
00277
00278 }
00279
00280 SECTION("std::unordered_set<json>")
00281 {
00282 std::unordered_set<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
00283 json j(a);
00284 CHECK(j.type() == json::value_t::array);
00285
00286 }
00287
00288 SECTION("sequence container literal")
00289 {
00290 json j({json(1), json(1u), json(2.2), json(false), json("string"), json()});
00291 CHECK(j.type() == json::value_t::array);
00292 CHECK(j == j_reference);
00293 }
00294 }
00295
00296 SECTION("create a string (explicit)")
00297 {
00298 SECTION("empty string")
00299 {
00300 json::string_t s;
00301 json j(s);
00302 CHECK(j.type() == json::value_t::string);
00303 }
00304
00305 SECTION("filled string")
00306 {
00307 json::string_t s {"Hello world"};
00308 json j(s);
00309 CHECK(j.type() == json::value_t::string);
00310 }
00311 }
00312
00313 SECTION("create a string (implicit)")
00314 {
00315
00316 json::string_t s_reference {"Hello world"};
00317 json j_reference(s_reference);
00318
00319 SECTION("std::string")
00320 {
00321 std::string s {"Hello world"};
00322 json j(s);
00323 CHECK(j.type() == json::value_t::string);
00324 CHECK(j == j_reference);
00325 }
00326
00327 SECTION("char[]")
00328 {
00329 char s[] {"Hello world"};
00330 json j(s);
00331 CHECK(j.type() == json::value_t::string);
00332 CHECK(j == j_reference);
00333 }
00334
00335 SECTION("const char*")
00336 {
00337 const char* s {"Hello world"};
00338 json j(s);
00339 CHECK(j.type() == json::value_t::string);
00340 CHECK(j == j_reference);
00341 }
00342
00343 SECTION("string literal")
00344 {
00345 json j("Hello world");
00346 CHECK(j.type() == json::value_t::string);
00347 CHECK(j == j_reference);
00348 }
00349 }
00350
00351 SECTION("create a boolean (explicit)")
00352 {
00353 SECTION("empty boolean")
00354 {
00355 json::boolean_t b{};
00356 json j(b);
00357 CHECK(j.type() == json::value_t::boolean);
00358 }
00359
00360 SECTION("filled boolean (true)")
00361 {
00362 json j(true);
00363 CHECK(j.type() == json::value_t::boolean);
00364 }
00365
00366 SECTION("filled boolean (false)")
00367 {
00368 json j(false);
00369 CHECK(j.type() == json::value_t::boolean);
00370 }
00371 }
00372
00373 SECTION("create an integer number (explicit)")
00374 {
00375 SECTION("uninitialized value")
00376 {
00377 json::number_integer_t n{};
00378 json j(n);
00379 CHECK(j.type() == json::value_t::number_integer);
00380 }
00381
00382 SECTION("initialized value")
00383 {
00384 json::number_integer_t n(42);
00385 json j(n);
00386 CHECK(j.type() == json::value_t::number_integer);
00387 }
00388 }
00389
00390 SECTION("create an integer number (implicit)")
00391 {
00392
00393 json::number_integer_t n_reference = 42;
00394 json j_reference(n_reference);
00395 json::number_unsigned_t n_unsigned_reference = 42;
00396 json j_unsigned_reference(n_unsigned_reference);
00397
00398 SECTION("short")
00399 {
00400 short n = 42;
00401 json j(n);
00402 CHECK(j.type() == json::value_t::number_integer);
00403 CHECK(j == j_reference);
00404 }
00405
00406 SECTION("unsigned short")
00407 {
00408 unsigned short n = 42;
00409 json j(n);
00410 CHECK(j.type() == json::value_t::number_unsigned);
00411 CHECK(j == j_unsigned_reference);
00412 }
00413
00414 SECTION("int")
00415 {
00416 int n = 42;
00417 json j(n);
00418 CHECK(j.type() == json::value_t::number_integer);
00419 CHECK(j == j_reference);
00420 }
00421
00422 SECTION("unsigned int")
00423 {
00424 unsigned int n = 42;
00425 json j(n);
00426 CHECK(j.type() == json::value_t::number_unsigned);
00427 CHECK(j == j_unsigned_reference);
00428 }
00429
00430 SECTION("long")
00431 {
00432 long n = 42;
00433 json j(n);
00434 CHECK(j.type() == json::value_t::number_integer);
00435 CHECK(j == j_reference);
00436 }
00437
00438 SECTION("unsigned long")
00439 {
00440 unsigned long n = 42;
00441 json j(n);
00442 CHECK(j.type() == json::value_t::number_unsigned);
00443 CHECK(j == j_unsigned_reference);
00444 }
00445
00446 SECTION("long long")
00447 {
00448 long long n = 42;
00449 json j(n);
00450 CHECK(j.type() == json::value_t::number_integer);
00451 CHECK(j == j_reference);
00452 }
00453
00454 SECTION("unsigned long long")
00455 {
00456 unsigned long long n = 42;
00457 json j(n);
00458 CHECK(j.type() == json::value_t::number_unsigned);
00459 CHECK(j == j_unsigned_reference);
00460 }
00461
00462 SECTION("int8_t")
00463 {
00464 int8_t n = 42;
00465 json j(n);
00466 CHECK(j.type() == json::value_t::number_integer);
00467 CHECK(j == j_reference);
00468 }
00469
00470 SECTION("int16_t")
00471 {
00472 int16_t n = 42;
00473 json j(n);
00474 CHECK(j.type() == json::value_t::number_integer);
00475 CHECK(j == j_reference);
00476 }
00477
00478 SECTION("int32_t")
00479 {
00480 int32_t n = 42;
00481 json j(n);
00482 CHECK(j.type() == json::value_t::number_integer);
00483 CHECK(j == j_reference);
00484 }
00485
00486 SECTION("int64_t")
00487 {
00488 int64_t n = 42;
00489 json j(n);
00490 CHECK(j.type() == json::value_t::number_integer);
00491 CHECK(j == j_reference);
00492 }
00493
00494 SECTION("int_fast8_t")
00495 {
00496 int_fast8_t n = 42;
00497 json j(n);
00498 CHECK(j.type() == json::value_t::number_integer);
00499 CHECK(j == j_reference);
00500 }
00501
00502 SECTION("int_fast16_t")
00503 {
00504 int_fast16_t n = 42;
00505 json j(n);
00506 CHECK(j.type() == json::value_t::number_integer);
00507 CHECK(j == j_reference);
00508 }
00509
00510 SECTION("int_fast32_t")
00511 {
00512 int_fast32_t n = 42;
00513 json j(n);
00514 CHECK(j.type() == json::value_t::number_integer);
00515 CHECK(j == j_reference);
00516 }
00517
00518 SECTION("int_fast64_t")
00519 {
00520 int_fast64_t n = 42;
00521 json j(n);
00522 CHECK(j.type() == json::value_t::number_integer);
00523 CHECK(j == j_reference);
00524 }
00525
00526 SECTION("int_least8_t")
00527 {
00528 int_least8_t n = 42;
00529 json j(n);
00530 CHECK(j.type() == json::value_t::number_integer);
00531 CHECK(j == j_reference);
00532 }
00533
00534 SECTION("int_least16_t")
00535 {
00536 int_least16_t n = 42;
00537 json j(n);
00538 CHECK(j.type() == json::value_t::number_integer);
00539 CHECK(j == j_reference);
00540 }
00541
00542 SECTION("int_least32_t")
00543 {
00544 int_least32_t n = 42;
00545 json j(n);
00546 CHECK(j.type() == json::value_t::number_integer);
00547 CHECK(j == j_reference);
00548 }
00549
00550 SECTION("int_least64_t")
00551 {
00552 int_least64_t n = 42;
00553 json j(n);
00554 CHECK(j.type() == json::value_t::number_integer);
00555 CHECK(j == j_reference);
00556 }
00557
00558 SECTION("uint8_t")
00559 {
00560 uint8_t n = 42;
00561 json j(n);
00562 CHECK(j.type() == json::value_t::number_unsigned);
00563 CHECK(j == j_unsigned_reference);
00564 }
00565
00566 SECTION("uint16_t")
00567 {
00568 uint16_t n = 42;
00569 json j(n);
00570 CHECK(j.type() == json::value_t::number_unsigned);
00571 CHECK(j == j_unsigned_reference);
00572 }
00573
00574 SECTION("uint32_t")
00575 {
00576 uint32_t n = 42;
00577 json j(n);
00578 CHECK(j.type() == json::value_t::number_unsigned);
00579 CHECK(j == j_unsigned_reference);
00580 }
00581
00582 SECTION("uint64_t")
00583 {
00584 uint64_t n = 42;
00585 json j(n);
00586 CHECK(j.type() == json::value_t::number_unsigned);
00587 CHECK(j == j_unsigned_reference);
00588 }
00589
00590 SECTION("uint_fast8_t")
00591 {
00592 uint_fast8_t n = 42;
00593 json j(n);
00594 CHECK(j.type() == json::value_t::number_unsigned);
00595 CHECK(j == j_unsigned_reference);
00596 }
00597
00598 SECTION("uint_fast16_t")
00599 {
00600 uint_fast16_t n = 42;
00601 json j(n);
00602 CHECK(j.type() == json::value_t::number_unsigned);
00603 CHECK(j == j_unsigned_reference);
00604 }
00605
00606 SECTION("uint_fast32_t")
00607 {
00608 uint_fast32_t n = 42;
00609 json j(n);
00610 CHECK(j.type() == json::value_t::number_unsigned);
00611 CHECK(j == j_unsigned_reference);
00612 }
00613
00614 SECTION("uint_fast64_t")
00615 {
00616 uint_fast64_t n = 42;
00617 json j(n);
00618 CHECK(j.type() == json::value_t::number_unsigned);
00619 CHECK(j == j_unsigned_reference);
00620 }
00621
00622 SECTION("uint_least8_t")
00623 {
00624 uint_least8_t n = 42;
00625 json j(n);
00626 CHECK(j.type() == json::value_t::number_unsigned);
00627 CHECK(j == j_unsigned_reference);
00628 }
00629
00630 SECTION("uint_least16_t")
00631 {
00632 uint_least16_t n = 42;
00633 json j(n);
00634 CHECK(j.type() == json::value_t::number_unsigned);
00635 CHECK(j == j_unsigned_reference);
00636 }
00637
00638 SECTION("uint_least32_t")
00639 {
00640 uint_least32_t n = 42;
00641 json j(n);
00642 CHECK(j.type() == json::value_t::number_unsigned);
00643 CHECK(j == j_unsigned_reference);
00644 }
00645
00646 SECTION("uint_least64_t")
00647 {
00648 uint_least64_t n = 42;
00649 json j(n);
00650 CHECK(j.type() == json::value_t::number_unsigned);
00651 CHECK(j == j_unsigned_reference);
00652 }
00653
00654 SECTION("integer literal without suffix")
00655 {
00656 json j(42);
00657 CHECK(j.type() == json::value_t::number_integer);
00658 CHECK(j == j_reference);
00659 }
00660
00661 SECTION("integer literal with u suffix")
00662 {
00663 json j(42u);
00664 CHECK(j.type() == json::value_t::number_unsigned);
00665 CHECK(j == j_unsigned_reference);
00666 }
00667
00668 SECTION("integer literal with l suffix")
00669 {
00670 json j(42l);
00671 CHECK(j.type() == json::value_t::number_integer);
00672 CHECK(j == j_reference);
00673 }
00674
00675 SECTION("integer literal with ul suffix")
00676 {
00677 json j(42ul);
00678 CHECK(j.type() == json::value_t::number_unsigned);
00679 CHECK(j == j_unsigned_reference);
00680 }
00681
00682 SECTION("integer literal with ll suffix")
00683 {
00684 json j(42ll);
00685 CHECK(j.type() == json::value_t::number_integer);
00686 CHECK(j == j_reference);
00687 }
00688
00689 SECTION("integer literal with ull suffix")
00690 {
00691 json j(42ull);
00692 CHECK(j.type() == json::value_t::number_unsigned);
00693 CHECK(j == j_unsigned_reference);
00694 }
00695 }
00696
00697 SECTION("create a floating-point number (explicit)")
00698 {
00699 SECTION("uninitialized value")
00700 {
00701 json::number_float_t n{};
00702 json j(n);
00703 CHECK(j.type() == json::value_t::number_float);
00704 }
00705
00706 SECTION("initialized value")
00707 {
00708 json::number_float_t n(42.23);
00709 json j(n);
00710 CHECK(j.type() == json::value_t::number_float);
00711 }
00712 }
00713
00714 SECTION("create a floating-point number (implicit)")
00715 {
00716
00717 json::number_float_t n_reference = 42.23;
00718 json j_reference(n_reference);
00719
00720 SECTION("float")
00721 {
00722 float n = 42.23;
00723 json j(n);
00724 CHECK(j.type() == json::value_t::number_float);
00725 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00726 }
00727
00728 SECTION("double")
00729 {
00730 double n = 42.23;
00731 json j(n);
00732 CHECK(j.type() == json::value_t::number_float);
00733 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00734 }
00735
00736 SECTION("long double")
00737 {
00738 long double n = 42.23;
00739 json j(n);
00740 CHECK(j.type() == json::value_t::number_float);
00741 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00742 }
00743
00744 SECTION("floating-point literal without suffix")
00745 {
00746 json j(42.23);
00747 CHECK(j.type() == json::value_t::number_float);
00748 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00749 }
00750
00751 SECTION("integer literal with f suffix")
00752 {
00753 json j(42.23f);
00754 CHECK(j.type() == json::value_t::number_float);
00755 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00756 }
00757
00758 SECTION("integer literal with l suffix")
00759 {
00760 json j(42.23l);
00761 CHECK(j.type() == json::value_t::number_float);
00762 CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
00763 }
00764 }
00765
00766 SECTION("create a container (array or object) from an initializer list")
00767 {
00768 SECTION("empty initializer list")
00769 {
00770 SECTION("explicit")
00771 {
00772 std::initializer_list<json> l;
00773 json j(l);
00774 CHECK(j.type() == json::value_t::object);
00775 }
00776
00777 SECTION("implicit")
00778 {
00779 json j {};
00780 CHECK(j.type() == json::value_t::null);
00781 }
00782 }
00783
00784 SECTION("one element")
00785 {
00786 SECTION("array")
00787 {
00788 SECTION("explicit")
00789 {
00790 std::initializer_list<json> l = {json(json::array_t())};
00791 json j(l);
00792 CHECK(j.type() == json::value_t::array);
00793 }
00794
00795 SECTION("implicit")
00796 {
00797 json j {json::array_t()};
00798 CHECK(j.type() == json::value_t::array);
00799 }
00800 }
00801
00802 SECTION("object")
00803 {
00804 SECTION("explicit")
00805 {
00806 std::initializer_list<json> l = {json(json::object_t())};
00807 json j(l);
00808 CHECK(j.type() == json::value_t::array);
00809 }
00810
00811 SECTION("implicit")
00812 {
00813 json j {json::object_t()};
00814 CHECK(j.type() == json::value_t::array);
00815 }
00816 }
00817
00818 SECTION("string")
00819 {
00820 SECTION("explicit")
00821 {
00822 std::initializer_list<json> l = {json("Hello world")};
00823 json j(l);
00824 CHECK(j.type() == json::value_t::array);
00825 }
00826
00827 SECTION("implicit")
00828 {
00829 json j {"Hello world"};
00830 CHECK(j.type() == json::value_t::array);
00831 }
00832 }
00833
00834 SECTION("boolean")
00835 {
00836 SECTION("explicit")
00837 {
00838 std::initializer_list<json> l = {json(true)};
00839 json j(l);
00840 CHECK(j.type() == json::value_t::array);
00841 }
00842
00843 SECTION("implicit")
00844 {
00845 json j {true};
00846 CHECK(j.type() == json::value_t::array);
00847 }
00848 }
00849
00850 SECTION("number (integer)")
00851 {
00852 SECTION("explicit")
00853 {
00854 std::initializer_list<json> l = {json(1)};
00855 json j(l);
00856 CHECK(j.type() == json::value_t::array);
00857 }
00858
00859 SECTION("implicit")
00860 {
00861 json j {1};
00862 CHECK(j.type() == json::value_t::array);
00863 }
00864 }
00865
00866 SECTION("number (unsigned)")
00867 {
00868 SECTION("explicit")
00869 {
00870 std::initializer_list<json> l = {json(1u)};
00871 json j(l);
00872 CHECK(j.type() == json::value_t::array);
00873 }
00874
00875 SECTION("implicit")
00876 {
00877 json j {1u};
00878 CHECK(j.type() == json::value_t::array);
00879 }
00880 }
00881
00882 SECTION("number (floating-point)")
00883 {
00884 SECTION("explicit")
00885 {
00886 std::initializer_list<json> l = {json(42.23)};
00887 json j(l);
00888 CHECK(j.type() == json::value_t::array);
00889 }
00890
00891 SECTION("implicit")
00892 {
00893 json j {42.23};
00894 CHECK(j.type() == json::value_t::array);
00895 }
00896 }
00897 }
00898
00899 SECTION("more elements")
00900 {
00901 SECTION("explicit")
00902 {
00903 std::initializer_list<json> l = {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};
00904 json j(l);
00905 CHECK(j.type() == json::value_t::array);
00906 }
00907
00908 SECTION("implicit")
00909 {
00910 json j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};
00911 CHECK(j.type() == json::value_t::array);
00912 }
00913 }
00914
00915 SECTION("implicit type deduction")
00916 {
00917 SECTION("object")
00918 {
00919 json j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} };
00920 CHECK(j.type() == json::value_t::object);
00921 }
00922
00923 SECTION("array")
00924 {
00925 json j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} , 13 };
00926 CHECK(j.type() == json::value_t::array);
00927 }
00928 }
00929
00930 SECTION("explicit type deduction")
00931 {
00932 SECTION("empty object")
00933 {
00934 json j = json::object();
00935 CHECK(j.type() == json::value_t::object);
00936 }
00937
00938 SECTION("object")
00939 {
00940 json j = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
00941 CHECK(j.type() == json::value_t::object);
00942 }
00943
00944 SECTION("object with error")
00945 {
00946 CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }),
00947 std::logic_error);
00948 CHECK_THROWS_WITH(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }),
00949 "cannot create object from initializer list");
00950 }
00951
00952 SECTION("empty array")
00953 {
00954 json j = json::array();
00955 CHECK(j.type() == json::value_t::array);
00956 }
00957
00958 SECTION("array")
00959 {
00960 json j = json::array({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
00961 CHECK(j.type() == json::value_t::array);
00962 }
00963 }
00964 }
00965
00966 SECTION("create an array of n copies of a given value")
00967 {
00968 json v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
00969 json arr(3, v);
00970 CHECK(arr.size() == 3);
00971 for (auto& x : arr)
00972 {
00973 CHECK(x == v);
00974 }
00975 }
00976
00977 SECTION("create a JSON container from an iterator range")
00978 {
00979 SECTION("object")
00980 {
00981 SECTION("json(begin(), end())")
00982 {
00983 {
00984 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
00985 json j_new(jobject.begin(), jobject.end());
00986 CHECK(j_new == jobject);
00987 }
00988 {
00989 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
00990 json j_new(jobject.cbegin(), jobject.cend());
00991 CHECK(j_new == jobject);
00992 }
00993 }
00994
00995 SECTION("json(begin(), begin())")
00996 {
00997 {
00998 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
00999 json j_new(jobject.begin(), jobject.begin());
01000 CHECK(j_new == json::object());
01001 }
01002 {
01003 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
01004 json j_new(jobject.cbegin(), jobject.cbegin());
01005 CHECK(j_new == json::object());
01006 }
01007 }
01008
01009 SECTION("construct from subrange")
01010 {
01011 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
01012 json j_new(jobject.find("b"), jobject.find("e"));
01013 CHECK(j_new == json({{"b", 1}, {"c", 17u}, {"d", false}}));
01014 }
01015
01016 SECTION("incompatible iterators")
01017 {
01018 {
01019 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
01020 json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
01021 CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), std::domain_error);
01022 CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), std::domain_error);
01023 CHECK_THROWS_WITH(json(jobject.begin(), jobject2.end()), "iterators are not compatible");
01024 CHECK_THROWS_WITH(json(jobject2.begin(), jobject.end()), "iterators are not compatible");
01025 }
01026 {
01027 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
01028 json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
01029 CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), std::domain_error);
01030 CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), std::domain_error);
01031 CHECK_THROWS_WITH(json(jobject.cbegin(), jobject2.cend()), "iterators are not compatible");
01032 CHECK_THROWS_WITH(json(jobject2.cbegin(), jobject.cend()), "iterators are not compatible");
01033 }
01034 }
01035 }
01036
01037 SECTION("array")
01038 {
01039 SECTION("json(begin(), end())")
01040 {
01041 {
01042 json jarray = {1, 2, 3, 4, 5};
01043 json j_new(jarray.begin(), jarray.end());
01044 CHECK(j_new == jarray);
01045 }
01046 {
01047 json jarray = {1, 2, 3, 4, 5};
01048 json j_new(jarray.cbegin(), jarray.cend());
01049 CHECK(j_new == jarray);
01050 }
01051 }
01052
01053 SECTION("json(begin(), begin())")
01054 {
01055 {
01056 json jarray = {1, 2, 3, 4, 5};
01057 json j_new(jarray.begin(), jarray.begin());
01058 CHECK(j_new == json::array());
01059 }
01060 {
01061 json jarray = {1, 2, 3, 4, 5};
01062 json j_new(jarray.cbegin(), jarray.cbegin());
01063 CHECK(j_new == json::array());
01064 }
01065 }
01066
01067 SECTION("construct from subrange")
01068 {
01069 {
01070 json jarray = {1, 2, 3, 4, 5};
01071 json j_new(jarray.begin() + 1, jarray.begin() + 3);
01072 CHECK(j_new == json({2, 3}));
01073 }
01074 {
01075 json jarray = {1, 2, 3, 4, 5};
01076 json j_new(jarray.cbegin() + 1, jarray.cbegin() + 3);
01077 CHECK(j_new == json({2, 3}));
01078 }
01079 }
01080
01081 SECTION("incompatible iterators")
01082 {
01083 {
01084 json jarray = {1, 2, 3, 4};
01085 json jarray2 = {2, 3, 4, 5};
01086 CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), std::domain_error);
01087 CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), std::domain_error);
01088 CHECK_THROWS_WITH(json(jarray.begin(), jarray2.end()), "iterators are not compatible");
01089 CHECK_THROWS_WITH(json(jarray2.begin(), jarray.end()), "iterators are not compatible");
01090 }
01091 {
01092 json jarray = {1, 2, 3, 4};
01093 json jarray2 = {2, 3, 4, 5};
01094 CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), std::domain_error);
01095 CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), std::domain_error);
01096 CHECK_THROWS_WITH(json(jarray.cbegin(), jarray2.cend()), "iterators are not compatible");
01097 CHECK_THROWS_WITH(json(jarray2.cbegin(), jarray.cend()), "iterators are not compatible");
01098 }
01099 }
01100 }
01101
01102 SECTION("other values")
01103 {
01104 SECTION("construct with two valid iterators")
01105 {
01106 SECTION("null")
01107 {
01108 {
01109 json j;
01110 CHECK_THROWS_AS(json(j.begin(), j.end()), std::domain_error);
01111 CHECK_THROWS_WITH(json(j.begin(), j.end()), "cannot use construct with iterators from null");
01112 }
01113 {
01114 json j;
01115 CHECK_THROWS_AS(json(j.cbegin(), j.cend()), std::domain_error);
01116 CHECK_THROWS_WITH(json(j.cbegin(), j.cend()), "cannot use construct with iterators from null");
01117 }
01118 }
01119
01120 SECTION("string")
01121 {
01122 {
01123 json j = "foo";
01124 json j_new(j.begin(), j.end());
01125 CHECK(j == j_new);
01126 }
01127 {
01128 json j = "bar";
01129 json j_new(j.cbegin(), j.cend());
01130 CHECK(j == j_new);
01131 }
01132 }
01133
01134 SECTION("number (boolean)")
01135 {
01136 {
01137 json j = false;
01138 json j_new(j.begin(), j.end());
01139 CHECK(j == j_new);
01140 }
01141 {
01142 json j = true;
01143 json j_new(j.cbegin(), j.cend());
01144 CHECK(j == j_new);
01145 }
01146 }
01147
01148 SECTION("number (integer)")
01149 {
01150 {
01151 json j = 17;
01152 json j_new(j.begin(), j.end());
01153 CHECK(j == j_new);
01154 }
01155 {
01156 json j = 17;
01157 json j_new(j.cbegin(), j.cend());
01158 CHECK(j == j_new);
01159 }
01160 }
01161
01162 SECTION("number (unsigned)")
01163 {
01164 {
01165 json j = 17u;
01166 json j_new(j.begin(), j.end());
01167 CHECK(j == j_new);
01168 }
01169 {
01170 json j = 17u;
01171 json j_new(j.cbegin(), j.cend());
01172 CHECK(j == j_new);
01173 }
01174 }
01175
01176 SECTION("number (floating point)")
01177 {
01178 {
01179 json j = 23.42;
01180 json j_new(j.begin(), j.end());
01181 CHECK(j == j_new);
01182 }
01183 {
01184 json j = 23.42;
01185 json j_new(j.cbegin(), j.cend());
01186 CHECK(j == j_new);
01187 }
01188 }
01189 }
01190
01191 SECTION("construct with two invalid iterators")
01192 {
01193 SECTION("string")
01194 {
01195 {
01196 json j = "foo";
01197 CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
01198 CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
01199 CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
01200 CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
01201 }
01202 {
01203 json j = "bar";
01204 CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
01205 CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
01206 CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
01207 CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
01208 }
01209 }
01210
01211 SECTION("number (boolean)")
01212 {
01213 {
01214 json j = false;
01215 CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
01216 CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
01217 CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
01218 CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
01219 }
01220 {
01221 json j = true;
01222 CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
01223 CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
01224 CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
01225 CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
01226 }
01227 }
01228
01229 SECTION("number (integer)")
01230 {
01231 {
01232 json j = 17;
01233 CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
01234 CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
01235 CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
01236 CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
01237 }
01238 {
01239 json j = 17;
01240 CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
01241 CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
01242 CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
01243 CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
01244 }
01245 }
01246
01247 SECTION("number (integer)")
01248 {
01249 {
01250 json j = 17u;
01251 CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
01252 CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
01253 CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
01254 CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
01255 }
01256 {
01257 json j = 17u;
01258 CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
01259 CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
01260 CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
01261 CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
01262 }
01263 }
01264
01265 SECTION("number (floating point)")
01266 {
01267 {
01268 json j = 23.42;
01269 CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
01270 CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
01271 CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
01272 CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
01273 }
01274 {
01275 json j = 23.42;
01276 CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
01277 CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
01278 CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
01279 CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
01280 }
01281 }
01282 }
01283 }
01284 }
01285
01286 SECTION("create a JSON value from an input stream")
01287 {
01288 SECTION("std::stringstream")
01289 {
01290 std::stringstream ss;
01291 ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
01292 json j(ss);
01293 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
01294 }
01295
01296 SECTION("with callback function")
01297 {
01298 std::stringstream ss;
01299 ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
01300 json j(ss, [](int, json::parse_event_t, const json & val)
01301 {
01302
01303 if (val == json(2))
01304 {
01305 return false;
01306 }
01307 else
01308 {
01309 return true;
01310 }
01311 });
01312 CHECK(j == json({"foo", 1, 3, false, {{"one", 1}}}));
01313 }
01314
01315 SECTION("std::ifstream")
01316 {
01317 std::ifstream f("test/data/json_tests/pass1.json");
01318 json j(f);
01319 }
01320 }
01321 }
01322
01323 TEST_CASE("other constructors and destructor")
01324 {
01325 SECTION("copy constructor")
01326 {
01327 SECTION("object")
01328 {
01329 json j {{"foo", 1}, {"bar", false}};
01330 json k(j);
01331 CHECK(j == k);
01332 }
01333
01334 SECTION("array")
01335 {
01336 json j {"foo", 1, 42.23, false};
01337 json k(j);
01338 CHECK(j == k);
01339 }
01340
01341 SECTION("null")
01342 {
01343 json j(nullptr);
01344 json k(j);
01345 CHECK(j == k);
01346 }
01347
01348 SECTION("boolean")
01349 {
01350 json j(true);
01351 json k(j);
01352 CHECK(j == k);
01353 }
01354
01355 SECTION("string")
01356 {
01357 json j("Hello world");
01358 json k(j);
01359 CHECK(j == k);
01360 }
01361
01362 SECTION("number (integer)")
01363 {
01364 json j(42);
01365 json k(j);
01366 CHECK(j == k);
01367 }
01368
01369 SECTION("number (unsigned)")
01370 {
01371 json j(42u);
01372 json k(j);
01373 CHECK(j == k);
01374 }
01375
01376 SECTION("number (floating-point)")
01377 {
01378 json j(42.23);
01379 json k(j);
01380 CHECK(j == k);
01381 }
01382 }
01383
01384 SECTION("move constructor")
01385 {
01386 json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
01387 CHECK(j.type() == json::value_t::object);
01388 json k(std::move(j));
01389 CHECK(k.type() == json::value_t::object);
01390 CHECK(j.type() == json::value_t::null);
01391 }
01392
01393 SECTION("copy assignment")
01394 {
01395 SECTION("object")
01396 {
01397 json j {{"foo", 1}, {"bar", false}};
01398 json k;
01399 k = j;
01400 CHECK(j == k);
01401 }
01402
01403 SECTION("array")
01404 {
01405 json j {"foo", 1, 42.23, false};
01406 json k;
01407 k = j;
01408 CHECK(j == k);
01409 }
01410
01411 SECTION("null")
01412 {
01413 json j(nullptr);
01414 json k;
01415 k = j;
01416 CHECK(j == k);
01417 }
01418
01419 SECTION("boolean")
01420 {
01421 json j(true);
01422 json k;
01423 k = j;
01424 CHECK(j == k);
01425 }
01426
01427 SECTION("string")
01428 {
01429 json j("Hello world");
01430 json k;
01431 k = j;
01432 CHECK(j == k);
01433 }
01434
01435 SECTION("number (integer)")
01436 {
01437 json j(42);
01438 json k;
01439 k = j;
01440 CHECK(j == k);
01441 }
01442
01443 SECTION("number (unsigned)")
01444 {
01445 json j(42u);
01446 json k;
01447 k = j;
01448 CHECK(j == k);
01449 }
01450
01451 SECTION("number (floating-point)")
01452 {
01453 json j(42.23);
01454 json k;
01455 k = j;
01456 CHECK(j == k);
01457 }
01458 }
01459
01460 SECTION("destructor")
01461 {
01462 SECTION("object")
01463 {
01464 auto j = new json {{"foo", 1}, {"bar", false}};
01465 delete j;
01466 }
01467
01468 SECTION("array")
01469 {
01470 auto j = new json {"foo", 1, 1u, false, 23.42};
01471 delete j;
01472 }
01473
01474 SECTION("string")
01475 {
01476 auto j = new json("Hello world");
01477 delete j;
01478 }
01479 }
01480 }
01481
01482 TEST_CASE("object inspection")
01483 {
01484 SECTION("convenience type checker")
01485 {
01486 SECTION("object")
01487 {
01488 json j {{"foo", 1}, {"bar", false}};
01489 CHECK(not j.is_null());
01490 CHECK(not j.is_boolean());
01491 CHECK(not j.is_number());
01492 CHECK(not j.is_number_integer());
01493 CHECK(not j.is_number_unsigned());
01494 CHECK(not j.is_number_float());
01495 CHECK(j.is_object());
01496 CHECK(not j.is_array());
01497 CHECK(not j.is_string());
01498 CHECK(not j.is_discarded());
01499 CHECK(not j.is_primitive());
01500 CHECK(j.is_structured());
01501 }
01502
01503 SECTION("array")
01504 {
01505 json j {"foo", 1, 1u, 42.23, false};
01506 CHECK(not j.is_null());
01507 CHECK(not j.is_boolean());
01508 CHECK(not j.is_number());
01509 CHECK(not j.is_number_integer());
01510 CHECK(not j.is_number_unsigned());
01511 CHECK(not j.is_number_float());
01512 CHECK(not j.is_object());
01513 CHECK(j.is_array());
01514 CHECK(not j.is_string());
01515 CHECK(not j.is_discarded());
01516 CHECK(not j.is_primitive());
01517 CHECK(j.is_structured());
01518 }
01519
01520 SECTION("null")
01521 {
01522 json j(nullptr);
01523 CHECK(j.is_null());
01524 CHECK(not j.is_boolean());
01525 CHECK(not j.is_number());
01526 CHECK(not j.is_number_integer());
01527 CHECK(not j.is_number_unsigned());
01528 CHECK(not j.is_number_float());
01529 CHECK(not j.is_object());
01530 CHECK(not j.is_array());
01531 CHECK(not j.is_string());
01532 CHECK(not j.is_discarded());
01533 CHECK(j.is_primitive());
01534 CHECK(not j.is_structured());
01535 }
01536
01537 SECTION("boolean")
01538 {
01539 json j(true);
01540 CHECK(not j.is_null());
01541 CHECK(j.is_boolean());
01542 CHECK(not j.is_number());
01543 CHECK(not j.is_number_integer());
01544 CHECK(not j.is_number_unsigned());
01545 CHECK(not j.is_number_float());
01546 CHECK(not j.is_object());
01547 CHECK(not j.is_array());
01548 CHECK(not j.is_string());
01549 CHECK(not j.is_discarded());
01550 CHECK(j.is_primitive());
01551 CHECK(not j.is_structured());
01552 }
01553
01554 SECTION("string")
01555 {
01556 json j("Hello world");
01557 CHECK(not j.is_null());
01558 CHECK(not j.is_boolean());
01559 CHECK(not j.is_number());
01560 CHECK(not j.is_number_integer());
01561 CHECK(not j.is_number_unsigned());
01562 CHECK(not j.is_number_float());
01563 CHECK(not j.is_object());
01564 CHECK(not j.is_array());
01565 CHECK(j.is_string());
01566 CHECK(not j.is_discarded());
01567 CHECK(j.is_primitive());
01568 CHECK(not j.is_structured());
01569 }
01570
01571 SECTION("number (integer)")
01572 {
01573 json j(42);
01574 CHECK(not j.is_null());
01575 CHECK(not j.is_boolean());
01576 CHECK(j.is_number());
01577 CHECK(j.is_number_integer());
01578 CHECK(not j.is_number_unsigned());
01579 CHECK(not j.is_number_float());
01580 CHECK(not j.is_object());
01581 CHECK(not j.is_array());
01582 CHECK(not j.is_string());
01583 CHECK(not j.is_discarded());
01584 CHECK(j.is_primitive());
01585 CHECK(not j.is_structured());
01586 }
01587
01588 SECTION("number (unsigned)")
01589 {
01590 json j(42u);
01591 CHECK(not j.is_null());
01592 CHECK(not j.is_boolean());
01593 CHECK(j.is_number());
01594 CHECK(j.is_number_integer());
01595 CHECK(j.is_number_unsigned());
01596 CHECK(not j.is_number_float());
01597 CHECK(not j.is_object());
01598 CHECK(not j.is_array());
01599 CHECK(not j.is_string());
01600 CHECK(not j.is_discarded());
01601 CHECK(j.is_primitive());
01602 CHECK(not j.is_structured());
01603 }
01604
01605 SECTION("number (floating-point)")
01606 {
01607 json j(42.23);
01608 CHECK(not j.is_null());
01609 CHECK(not j.is_boolean());
01610 CHECK(j.is_number());
01611 CHECK(not j.is_number_integer());
01612 CHECK(not j.is_number_unsigned());
01613 CHECK(j.is_number_float());
01614 CHECK(not j.is_object());
01615 CHECK(not j.is_array());
01616 CHECK(not j.is_string());
01617 CHECK(not j.is_discarded());
01618 CHECK(j.is_primitive());
01619 CHECK(not j.is_structured());
01620 }
01621
01622 SECTION("discarded")
01623 {
01624 json j(json::value_t::discarded);
01625 CHECK(not j.is_null());
01626 CHECK(not j.is_boolean());
01627 CHECK(not j.is_number());
01628 CHECK(not j.is_number_integer());
01629 CHECK(not j.is_number_unsigned());
01630 CHECK(not j.is_number_float());
01631 CHECK(not j.is_object());
01632 CHECK(not j.is_array());
01633 CHECK(not j.is_string());
01634 CHECK(j.is_discarded());
01635 CHECK(not j.is_primitive());
01636 CHECK(not j.is_structured());
01637 }
01638 }
01639
01640 SECTION("serialization")
01641 {
01642 json j {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
01643
01644 SECTION("no indent / indent=-1")
01645 {
01646 CHECK(j.dump() ==
01647 "{\"array\":[1,2,3,4],\"boolean\":false,\"null\":null,\"number\":42,\"object\":{},\"string\":\"Hello world\"}");
01648
01649 CHECK(j.dump() == j.dump(-1));
01650 }
01651
01652 SECTION("indent=0")
01653 {
01654 CHECK(j.dump(0) ==
01655 "{\n\"array\": [\n1,\n2,\n3,\n4\n],\n\"boolean\": false,\n\"null\": null,\n\"number\": 42,\n\"object\": {},\n\"string\": \"Hello world\"\n}");
01656 }
01657
01658 SECTION("indent=4")
01659 {
01660 CHECK(j.dump(4) ==
01661 "{\n \"array\": [\n 1,\n 2,\n 3,\n 4\n ],\n \"boolean\": false,\n \"null\": null,\n \"number\": 42,\n \"object\": {},\n \"string\": \"Hello world\"\n}");
01662 }
01663
01664 SECTION("dump and floating-point numbers")
01665 {
01666 auto s = json(42.23).dump();
01667 CHECK(s.find("42.23") != std::string::npos);
01668 }
01669
01670 SECTION("dump and small floating-point numbers")
01671 {
01672 auto s = json(1.23456e-78).dump();
01673 CHECK(s.find("1.23456e-78") != std::string::npos);
01674 }
01675
01676 SECTION("dump and non-ASCII characters")
01677 {
01678 CHECK(json("ä").dump() == "\"ä\"");
01679 CHECK(json("Ö").dump() == "\"Ö\"");
01680 CHECK(json("❤️").dump() == "\"❤️\"");
01681 }
01682
01683 SECTION("serialization of discarded element")
01684 {
01685 json j_discarded(json::value_t::discarded);
01686 CHECK(j_discarded.dump() == "<discarded>");
01687 }
01688 }
01689
01690 SECTION("return the type of the object (explicit)")
01691 {
01692 SECTION("null")
01693 {
01694 json j = nullptr;
01695 CHECK(j.type() == json::value_t::null);
01696 }
01697
01698 SECTION("object")
01699 {
01700 json j = {{"foo", "bar"}};
01701 CHECK(j.type() == json::value_t::object);
01702 }
01703
01704 SECTION("array")
01705 {
01706 json j = {1, 2, 3, 4};
01707 CHECK(j.type() == json::value_t::array);
01708 }
01709
01710 SECTION("boolean")
01711 {
01712 json j = true;
01713 CHECK(j.type() == json::value_t::boolean);
01714 }
01715
01716 SECTION("string")
01717 {
01718 json j = "Hello world";
01719 CHECK(j.type() == json::value_t::string);
01720 }
01721
01722 SECTION("number (integer)")
01723 {
01724 json j = 23;
01725 CHECK(j.type() == json::value_t::number_integer);
01726 }
01727
01728 SECTION("number (unsigned)")
01729 {
01730 json j = 23u;
01731 CHECK(j.type() == json::value_t::number_unsigned);
01732 }
01733
01734 SECTION("number (floating-point)")
01735 {
01736 json j = 42.23;
01737 CHECK(j.type() == json::value_t::number_float);
01738 }
01739 }
01740
01741 SECTION("return the type of the object (implicit)")
01742 {
01743 SECTION("null")
01744 {
01745 json j = nullptr;
01746 json::value_t t = j;
01747 CHECK(t == j.type());
01748 }
01749
01750 SECTION("object")
01751 {
01752 json j = {{"foo", "bar"}};
01753 json::value_t t = j;
01754 CHECK(t == j.type());
01755 }
01756
01757 SECTION("array")
01758 {
01759 json j = {1, 2, 3, 4};
01760 json::value_t t = j;
01761 CHECK(t == j.type());
01762 }
01763
01764 SECTION("boolean")
01765 {
01766 json j = true;
01767 json::value_t t = j;
01768 CHECK(t == j.type());
01769 }
01770
01771 SECTION("string")
01772 {
01773 json j = "Hello world";
01774 json::value_t t = j;
01775 CHECK(t == j.type());
01776 }
01777
01778 SECTION("number (integer)")
01779 {
01780 json j = 23;
01781 json::value_t t = j;
01782 CHECK(t == j.type());
01783 }
01784
01785 SECTION("number (unsigned)")
01786 {
01787 json j = 23u;
01788 json::value_t t = j;
01789 CHECK(t == j.type());
01790 }
01791
01792 SECTION("number (floating-point)")
01793 {
01794 json j = 42.23;
01795 json::value_t t = j;
01796 CHECK(t == j.type());
01797 }
01798 }
01799 }
01800
01801 TEST_CASE("value conversion")
01802 {
01803 SECTION("get an object (explicit)")
01804 {
01805 json::object_t o_reference = {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
01806 json j(o_reference);
01807
01808 SECTION("json::object_t")
01809 {
01810 json::object_t o = j.get<json::object_t>();
01811 CHECK(json(o) == j);
01812 }
01813
01814 SECTION("std::map<json::string_t, json>")
01815 {
01816 std::map<json::string_t, json> o = j.get<std::map<json::string_t, json>>();
01817 CHECK(json(o) == j);
01818 }
01819
01820 SECTION("std::multimap<json::string_t, json>")
01821 {
01822 std::multimap<json::string_t, json> o = j.get<std::multimap<json::string_t, json>>();
01823 CHECK(json(o) == j);
01824 }
01825
01826 SECTION("std::unordered_map<json::string_t, json>")
01827 {
01828 std::unordered_map<json::string_t, json> o = j.get<std::unordered_map<json::string_t, json>>();
01829 CHECK(json(o) == j);
01830 }
01831
01832 SECTION("std::unordered_multimap<json::string_t, json>")
01833 {
01834 std::unordered_multimap<json::string_t, json> o =
01835 j.get<std::unordered_multimap<json::string_t, json>>();
01836 CHECK(json(o) == j);
01837 }
01838
01839 SECTION("exception in case of a non-object type")
01840 {
01841 CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(), std::logic_error);
01842 CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(), std::logic_error);
01843 CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(), std::logic_error);
01844 CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), std::logic_error);
01845 CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error);
01846 CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::object_t>(), std::logic_error);
01847 CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), std::logic_error);
01848
01849 CHECK_THROWS_WITH(json(json::value_t::null).get<json::object_t>(),
01850 "type must be object, but is null");
01851 CHECK_THROWS_WITH(json(json::value_t::array).get<json::object_t>(),
01852 "type must be object, but is array");
01853 CHECK_THROWS_WITH(json(json::value_t::string).get<json::object_t>(),
01854 "type must be object, but is string");
01855 CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),
01856 "type must be object, but is boolean");
01857 CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::object_t>(),
01858 "type must be object, but is number");
01859 CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::object_t>(),
01860 "type must be object, but is number");
01861 CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::object_t>(),
01862 "type must be object, but is number");
01863 }
01864 }
01865
01866 SECTION("get an object (implicit)")
01867 {
01868 json::object_t o_reference = {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
01869 json j(o_reference);
01870
01871 SECTION("json::object_t")
01872 {
01873 json::object_t o = j;
01874 CHECK(json(o) == j);
01875 }
01876
01877 SECTION("std::map<json::string_t, json>")
01878 {
01879 std::map<json::string_t, json> o = j;
01880 CHECK(json(o) == j);
01881 }
01882
01883 SECTION("std::multimap<json::string_t, json>")
01884 {
01885 std::multimap<json::string_t, json> o = j;
01886 CHECK(json(o) == j);
01887 }
01888
01889 SECTION("std::unordered_map<json::string_t, json>")
01890 {
01891 std::unordered_map<json::string_t, json> o = j;
01892 CHECK(json(o) == j);
01893 }
01894
01895 SECTION("std::unordered_multimap<json::string_t, json>")
01896 {
01897 std::unordered_multimap<json::string_t, json> o = j;
01898 CHECK(json(o) == j);
01899 }
01900 }
01901
01902 SECTION("get an array (explicit)")
01903 {
01904 json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
01905 json j(a_reference);
01906
01907 SECTION("json::array_t")
01908 {
01909 json::array_t a = j.get<json::array_t>();
01910 CHECK(json(a) == j);
01911 }
01912
01913 SECTION("std::list<json>")
01914 {
01915 std::list<json> a = j.get<std::list<json>>();
01916 CHECK(json(a) == j);
01917 }
01918
01919 SECTION("std::forward_list<json>")
01920 {
01921 std::forward_list<json> a = j.get<std::forward_list<json>>();
01922 CHECK(json(a) == j);
01923 }
01924
01925 SECTION("std::vector<json>")
01926 {
01927 std::vector<json> a = j.get<std::vector<json>>();
01928 CHECK(json(a) == j);
01929 }
01930
01931 SECTION("std::deque<json>")
01932 {
01933 std::deque<json> a = j.get<std::deque<json>>();
01934 CHECK(json(a) == j);
01935 }
01936
01937 SECTION("exception in case of a non-array type")
01938 {
01939 CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(), std::logic_error);
01940 CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(), std::logic_error);
01941 CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(), std::logic_error);
01942 CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), std::logic_error);
01943 CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error);
01944 CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(), std::logic_error);
01945 CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), std::logic_error);
01946
01947 CHECK_THROWS_WITH(json(json::value_t::null).get<json::array_t>(),
01948 "type must be array, but is null");
01949 CHECK_THROWS_WITH(json(json::value_t::object).get<json::array_t>(),
01950 "type must be array, but is object");
01951 CHECK_THROWS_WITH(json(json::value_t::string).get<json::array_t>(),
01952 "type must be array, but is string");
01953 CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::array_t>(),
01954 "type must be array, but is boolean");
01955 CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::array_t>(),
01956 "type must be array, but is number");
01957 CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::array_t>(),
01958 "type must be array, but is number");
01959 CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::array_t>(),
01960 "type must be array, but is number");
01961 }
01962 }
01963
01964 SECTION("get an array (implicit)")
01965 {
01966 json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
01967 json j(a_reference);
01968
01969 SECTION("json::array_t")
01970 {
01971 json::array_t a = j;
01972 CHECK(json(a) == j);
01973 }
01974
01975 SECTION("std::list<json>")
01976 {
01977 std::list<json> a = j;
01978 CHECK(json(a) == j);
01979 }
01980
01981 SECTION("std::forward_list<json>")
01982 {
01983 std::forward_list<json> a = j;
01984 CHECK(json(a) == j);
01985 }
01986
01987 SECTION("std::vector<json>")
01988 {
01989 std::vector<json> a = j;
01990 CHECK(json(a) == j);
01991 }
01992
01993 SECTION("std::deque<json>")
01994 {
01995 std::deque<json> a = j;
01996 CHECK(json(a) == j);
01997 }
01998 }
01999
02000 SECTION("get a string (explicit)")
02001 {
02002 json::string_t s_reference {"Hello world"};
02003 json j(s_reference);
02004
02005 SECTION("string_t")
02006 {
02007 json::string_t s = j.get<json::string_t>();
02008 CHECK(json(s) == j);
02009 }
02010
02011 SECTION("std::string")
02012 {
02013 std::string s = j.get<std::string>();
02014 CHECK(json(s) == j);
02015 }
02016
02017 SECTION("exception in case of a non-string type")
02018 {
02019 CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(), std::logic_error);
02020 CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(), std::logic_error);
02021 CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(), std::logic_error);
02022 CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), std::logic_error);
02023 CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error);
02024 CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::string_t>(), std::logic_error);
02025 CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), std::logic_error);
02026
02027 CHECK_THROWS_WITH(json(json::value_t::null).get<json::string_t>(),
02028 "type must be string, but is null");
02029 CHECK_THROWS_WITH(json(json::value_t::object).get<json::string_t>(),
02030 "type must be string, but is object");
02031 CHECK_THROWS_WITH(json(json::value_t::array).get<json::string_t>(),
02032 "type must be string, but is array");
02033 CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
02034 "type must be string, but is boolean");
02035 CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::string_t>(),
02036 "type must be string, but is number");
02037 CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::string_t>(),
02038 "type must be string, but is number");
02039 CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::string_t>(),
02040 "type must be string, but is number");
02041 }
02042 }
02043
02044 SECTION("get a string (implicit)")
02045 {
02046 json::string_t s_reference {"Hello world"};
02047 json j(s_reference);
02048
02049 SECTION("string_t")
02050 {
02051 json::string_t s = j;
02052 CHECK(json(s) == j);
02053 }
02054
02055 SECTION("std::string")
02056 {
02057 std::string s = j;
02058 CHECK(json(s) == j);
02059 }
02060 }
02061
02062 SECTION("get a boolean (explicit)")
02063 {
02064 json::boolean_t b_reference {true};
02065 json j(b_reference);
02066
02067 SECTION("boolean_t")
02068 {
02069 json::boolean_t b = j.get<json::boolean_t>();
02070 CHECK(json(b) == j);
02071 }
02072
02073 SECTION("bool")
02074 {
02075 bool b = j.get<bool>();
02076 CHECK(json(b) == j);
02077 }
02078
02079 SECTION("exception in case of a non-string type")
02080 {
02081 CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(), std::logic_error);
02082 CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(), std::logic_error);
02083 CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(), std::logic_error);
02084 CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), std::logic_error);
02085 CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error);
02086 CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::boolean_t>(), std::logic_error);
02087 CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error);
02088
02089 CHECK_THROWS_WITH(json(json::value_t::null).get<json::boolean_t>(),
02090 "type must be boolean, but is null");
02091 CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
02092 "type must be boolean, but is object");
02093 CHECK_THROWS_WITH(json(json::value_t::array).get<json::boolean_t>(),
02094 "type must be boolean, but is array");
02095 CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
02096 "type must be boolean, but is string");
02097 CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::boolean_t>(),
02098 "type must be boolean, but is number");
02099 CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::boolean_t>(),
02100 "type must be boolean, but is number");
02101 CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::boolean_t>(),
02102 "type must be boolean, but is number");
02103 }
02104 }
02105
02106 SECTION("get a boolean (implicit)")
02107 {
02108 json::boolean_t b_reference {true};
02109 json j(b_reference);
02110
02111 SECTION("boolean_t")
02112 {
02113 json::boolean_t b = j;
02114 CHECK(json(b) == j);
02115 }
02116
02117 SECTION("bool")
02118 {
02119 bool b = j;
02120 CHECK(json(b) == j);
02121 }
02122 }
02123
02124 SECTION("get an integer number (explicit)")
02125 {
02126 json::number_integer_t n_reference {42};
02127 json j(n_reference);
02128 json::number_unsigned_t n_unsigned_reference {42u};
02129 json j_unsigned(n_unsigned_reference);
02130
02131 SECTION("number_integer_t")
02132 {
02133 json::number_integer_t n = j.get<json::number_integer_t>();
02134 CHECK(json(n) == j);
02135 }
02136
02137 SECTION("number_unsigned_t")
02138 {
02139 json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
02140 CHECK(json(n) == j_unsigned);
02141 }
02142
02143 SECTION("short")
02144 {
02145 short n = j.get<short>();
02146 CHECK(json(n) == j);
02147 }
02148
02149 SECTION("unsigned short")
02150 {
02151 unsigned short n = j.get<unsigned short>();
02152 CHECK(json(n) == j);
02153 }
02154
02155 SECTION("int")
02156 {
02157 int n = j.get<int>();
02158 CHECK(json(n) == j);
02159 }
02160
02161 SECTION("unsigned int")
02162 {
02163 unsigned int n = j.get<unsigned int>();
02164 CHECK(json(n) == j);
02165 }
02166
02167 SECTION("long")
02168 {
02169 long n = j.get<long>();
02170 CHECK(json(n) == j);
02171 }
02172
02173 SECTION("unsigned long")
02174 {
02175 unsigned long n = j.get<unsigned long>();
02176 CHECK(json(n) == j);
02177 }
02178
02179 SECTION("long long")
02180 {
02181 long long n = j.get<long long>();
02182 CHECK(json(n) == j);
02183 }
02184
02185 SECTION("unsigned long long")
02186 {
02187 unsigned long long n = j.get<unsigned long long>();
02188 CHECK(json(n) == j);
02189 }
02190
02191 SECTION("int8_t")
02192 {
02193 int8_t n = j.get<int8_t>();
02194 CHECK(json(n) == j);
02195 }
02196
02197 SECTION("int16_t")
02198 {
02199 int16_t n = j.get<int16_t>();
02200 CHECK(json(n) == j);
02201 }
02202
02203 SECTION("int32_t")
02204 {
02205 int32_t n = j.get<int32_t>();
02206 CHECK(json(n) == j);
02207 }
02208
02209 SECTION("int64_t")
02210 {
02211 int64_t n = j.get<int64_t>();
02212 CHECK(json(n) == j);
02213 }
02214
02215 SECTION("int8_fast_t")
02216 {
02217 int_fast8_t n = j.get<int_fast8_t>();
02218 CHECK(json(n) == j);
02219 }
02220
02221 SECTION("int16_fast_t")
02222 {
02223 int_fast16_t n = j.get<int_fast16_t>();
02224 CHECK(json(n) == j);
02225 }
02226
02227 SECTION("int32_fast_t")
02228 {
02229 int_fast32_t n = j.get<int_fast32_t>();
02230 CHECK(json(n) == j);
02231 }
02232
02233 SECTION("int64_fast_t")
02234 {
02235 int_fast64_t n = j.get<int_fast64_t>();
02236 CHECK(json(n) == j);
02237 }
02238
02239 SECTION("int8_least_t")
02240 {
02241 int_least8_t n = j.get<int_least8_t>();
02242 CHECK(json(n) == j);
02243 }
02244
02245 SECTION("int16_least_t")
02246 {
02247 int_least16_t n = j.get<int_least16_t>();
02248 CHECK(json(n) == j);
02249 }
02250
02251 SECTION("int32_least_t")
02252 {
02253 int_least32_t n = j.get<int_least32_t>();
02254 CHECK(json(n) == j);
02255 }
02256
02257 SECTION("int64_least_t")
02258 {
02259 int_least64_t n = j.get<int_least64_t>();
02260 CHECK(json(n) == j);
02261 }
02262
02263 SECTION("uint8_t")
02264 {
02265 uint8_t n = j.get<uint8_t>();
02266 CHECK(json(n) == j);
02267 }
02268
02269 SECTION("uint16_t")
02270 {
02271 uint16_t n = j.get<uint16_t>();
02272 CHECK(json(n) == j);
02273 }
02274
02275 SECTION("uint32_t")
02276 {
02277 uint32_t n = j.get<uint32_t>();
02278 CHECK(json(n) == j);
02279 }
02280
02281 SECTION("uint64_t")
02282 {
02283 uint64_t n = j.get<uint64_t>();
02284 CHECK(json(n) == j);
02285 }
02286
02287 SECTION("uint8_fast_t")
02288 {
02289 uint_fast8_t n = j.get<uint_fast8_t>();
02290 CHECK(json(n) == j);
02291 }
02292
02293 SECTION("uint16_fast_t")
02294 {
02295 uint_fast16_t n = j.get<uint_fast16_t>();
02296 CHECK(json(n) == j);
02297 }
02298
02299 SECTION("uint32_fast_t")
02300 {
02301 uint_fast32_t n = j.get<uint_fast32_t>();
02302 CHECK(json(n) == j);
02303 }
02304
02305 SECTION("uint64_fast_t")
02306 {
02307 uint_fast64_t n = j.get<uint_fast64_t>();
02308 CHECK(json(n) == j);
02309 }
02310
02311 SECTION("uint8_least_t")
02312 {
02313 uint_least8_t n = j.get<uint_least8_t>();
02314 CHECK(json(n) == j);
02315 }
02316
02317 SECTION("uint16_least_t")
02318 {
02319 uint_least16_t n = j.get<uint_least16_t>();
02320 CHECK(json(n) == j);
02321 }
02322
02323 SECTION("uint32_least_t")
02324 {
02325 uint_least32_t n = j.get<uint_least32_t>();
02326 CHECK(json(n) == j);
02327 }
02328
02329 SECTION("uint64_least_t")
02330 {
02331 uint_least64_t n = j.get<uint_least64_t>();
02332 CHECK(json(n) == j);
02333 }
02334
02335 SECTION("exception in case of a non-number type")
02336 {
02337 CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(), std::logic_error);
02338 CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(), std::logic_error);
02339 CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error);
02340 CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error);
02341 CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error);
02342
02343 CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_integer_t>(),
02344 "type must be number, but is null");
02345 CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_integer_t>(),
02346 "type must be number, but is object");
02347 CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_integer_t>(),
02348 "type must be number, but is array");
02349 CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_integer_t>(),
02350 "type must be number, but is string");
02351 CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_integer_t>(),
02352 "type must be number, but is boolean");
02353
02354 CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
02355 CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_unsigned_t>());
02356 }
02357 }
02358
02359 SECTION("get an integer number (implicit)")
02360 {
02361 json::number_integer_t n_reference {42};
02362 json j(n_reference);
02363 json::number_unsigned_t n_unsigned_reference {42u};
02364 json j_unsigned(n_unsigned_reference);
02365
02366 SECTION("number_integer_t")
02367 {
02368 json::number_integer_t n = j.get<json::number_integer_t>();
02369 CHECK(json(n) == j);
02370 }
02371
02372 SECTION("number_unsigned_t")
02373 {
02374 json::number_unsigned_t n = j_unsigned.get<json::number_unsigned_t>();
02375 CHECK(json(n) == j_unsigned);
02376 }
02377
02378 SECTION("short")
02379 {
02380 short n = j;
02381 CHECK(json(n) == j);
02382 }
02383
02384 SECTION("unsigned short")
02385 {
02386 unsigned short n = j_unsigned;
02387 CHECK(json(n) == j_unsigned);
02388 }
02389
02390 SECTION("int")
02391 {
02392 int n = j;
02393 CHECK(json(n) == j);
02394 }
02395
02396 SECTION("unsigned int")
02397 {
02398 unsigned int n = j_unsigned;
02399 CHECK(json(n) == j_unsigned);
02400 }
02401
02402 SECTION("long")
02403 {
02404 long n = j;
02405 CHECK(json(n) == j);
02406 }
02407
02408 SECTION("unsigned long")
02409 {
02410 unsigned long n = j_unsigned;
02411 CHECK(json(n) == j_unsigned);
02412 }
02413
02414 SECTION("long long")
02415 {
02416 long long n = j;
02417 CHECK(json(n) == j);
02418 }
02419
02420 SECTION("unsigned long long")
02421 {
02422 unsigned long long n = j_unsigned;
02423 CHECK(json(n) == j_unsigned);
02424 }
02425
02426 SECTION("int8_t")
02427 {
02428 int8_t n = j;
02429 CHECK(json(n) == j);
02430 }
02431
02432 SECTION("int16_t")
02433 {
02434 int16_t n = j;
02435 CHECK(json(n) == j);
02436 }
02437
02438 SECTION("int32_t")
02439 {
02440 int32_t n = j;
02441 CHECK(json(n) == j);
02442 }
02443
02444 SECTION("int64_t")
02445 {
02446 int64_t n = j;
02447 CHECK(json(n) == j);
02448 }
02449
02450 SECTION("int8_fast_t")
02451 {
02452 int_fast8_t n = j;
02453 CHECK(json(n) == j);
02454 }
02455
02456 SECTION("int16_fast_t")
02457 {
02458 int_fast16_t n = j;
02459 CHECK(json(n) == j);
02460 }
02461
02462 SECTION("int32_fast_t")
02463 {
02464 int_fast32_t n = j;
02465 CHECK(json(n) == j);
02466 }
02467
02468 SECTION("int64_fast_t")
02469 {
02470 int_fast64_t n = j;
02471 CHECK(json(n) == j);
02472 }
02473
02474 SECTION("int8_least_t")
02475 {
02476 int_least8_t n = j;
02477 CHECK(json(n) == j);
02478 }
02479
02480 SECTION("int16_least_t")
02481 {
02482 int_least16_t n = j;
02483 CHECK(json(n) == j);
02484 }
02485
02486 SECTION("int32_least_t")
02487 {
02488 int_least32_t n = j;
02489 CHECK(json(n) == j);
02490 }
02491
02492 SECTION("int64_least_t")
02493 {
02494 int_least64_t n = j;
02495 CHECK(json(n) == j);
02496 }
02497
02498 SECTION("uint8_t")
02499 {
02500 uint8_t n = j_unsigned;
02501 CHECK(json(n) == j_unsigned);
02502 }
02503
02504 SECTION("uint16_t")
02505 {
02506 uint16_t n = j_unsigned;
02507 CHECK(json(n) == j_unsigned);
02508 }
02509
02510 SECTION("uint32_t")
02511 {
02512 uint32_t n = j_unsigned;
02513 CHECK(json(n) == j_unsigned);
02514 }
02515
02516 SECTION("uint64_t")
02517 {
02518 uint64_t n = j_unsigned;
02519 CHECK(json(n) == j_unsigned);
02520 }
02521
02522 SECTION("uint8_fast_t")
02523 {
02524 uint_fast8_t n = j_unsigned;
02525 CHECK(json(n) == j_unsigned);
02526 }
02527
02528 SECTION("uint16_fast_t")
02529 {
02530 uint_fast16_t n = j_unsigned;
02531 CHECK(json(n) == j_unsigned);
02532 }
02533
02534 SECTION("uint32_fast_t")
02535 {
02536 uint_fast32_t n = j_unsigned;
02537 CHECK(json(n) == j_unsigned);
02538 }
02539
02540 SECTION("uint64_fast_t")
02541 {
02542 uint_fast64_t n = j_unsigned;
02543 CHECK(json(n) == j_unsigned);
02544 }
02545
02546 SECTION("uint8_least_t")
02547 {
02548 uint_least8_t n = j_unsigned;
02549 CHECK(json(n) == j_unsigned);
02550 }
02551
02552 SECTION("uint16_least_t")
02553 {
02554 uint_least16_t n = j_unsigned;
02555 CHECK(json(n) == j_unsigned);
02556 }
02557
02558 SECTION("uint32_least_t")
02559 {
02560 uint_least32_t n = j_unsigned;
02561 CHECK(json(n) == j_unsigned);
02562 }
02563
02564 SECTION("uint64_least_t")
02565 {
02566 uint_least64_t n = j_unsigned;
02567 CHECK(json(n) == j_unsigned);
02568 }
02569 }
02570
02571 SECTION("get a floating-point number (explicit)")
02572 {
02573 json::number_float_t n_reference {42.23};
02574 json j(n_reference);
02575
02576 SECTION("number_float_t")
02577 {
02578 json::number_float_t n = j.get<json::number_float_t>();
02579 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02580 }
02581
02582 SECTION("float")
02583 {
02584 float n = j.get<float>();
02585 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02586 }
02587
02588 SECTION("double")
02589 {
02590 double n = j.get<double>();
02591 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02592 }
02593
02594 SECTION("exception in case of a non-string type")
02595 {
02596 CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(), std::logic_error);
02597 CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(), std::logic_error);
02598 CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), std::logic_error);
02599 CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), std::logic_error);
02600 CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error);
02601
02602 CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_float_t>(),
02603 "type must be number, but is null");
02604 CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_float_t>(),
02605 "type must be number, but is object");
02606 CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_float_t>(),
02607 "type must be number, but is array");
02608 CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_float_t>(),
02609 "type must be number, but is string");
02610 CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_float_t>(),
02611 "type must be number, but is boolean");
02612
02613 CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
02614 CHECK_NOTHROW(json(json::value_t::number_unsigned).get<json::number_float_t>());
02615 }
02616 }
02617
02618 SECTION("get a floating-point number (implicit)")
02619 {
02620 json::number_float_t n_reference {42.23};
02621 json j(n_reference);
02622
02623 SECTION("number_float_t")
02624 {
02625 json::number_float_t n = j;
02626 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02627 }
02628
02629 SECTION("float")
02630 {
02631 float n = j;
02632 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02633 }
02634
02635 SECTION("double")
02636 {
02637 double n = j;
02638 CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
02639 }
02640 }
02641
02642 SECTION("more involved conversions")
02643 {
02644 SECTION("object-like STL containers")
02645 {
02646 json j1 = {{"one", 1}, {"two", 2}, {"three", 3}};
02647 json j2 = {{"one", 1u}, {"two", 2u}, {"three", 3u}};
02648 json j3 = {{"one", 1.1}, {"two", 2.2}, {"three", 3.3}};
02649 json j4 = {{"one", true}, {"two", false}, {"three", true}};
02650 json j5 = {{"one", "eins"}, {"two", "zwei"}, {"three", "drei"}};
02651
02652 SECTION("std::map")
02653 {
02654 auto m1 = j1.get<std::map<std::string, int>>();
02655 auto m2 = j2.get<std::map<std::string, unsigned int>>();
02656 auto m3 = j3.get<std::map<std::string, double>>();
02657 auto m4 = j4.get<std::map<std::string, bool>>();
02658
02659 }
02660
02661 SECTION("std::unordered_map")
02662 {
02663 auto m1 = j1.get<std::unordered_map<std::string, int>>();
02664 auto m2 = j2.get<std::unordered_map<std::string, unsigned int>>();
02665 auto m3 = j3.get<std::unordered_map<std::string, double>>();
02666 auto m4 = j4.get<std::unordered_map<std::string, bool>>();
02667
02668
02669 }
02670
02671 SECTION("std::multimap")
02672 {
02673 auto m1 = j1.get<std::multimap<std::string, int>>();
02674 auto m2 = j2.get<std::multimap<std::string, unsigned int>>();
02675 auto m3 = j3.get<std::multimap<std::string, double>>();
02676 auto m4 = j4.get<std::multimap<std::string, bool>>();
02677
02678
02679 }
02680
02681 SECTION("std::unordered_multimap")
02682 {
02683 auto m1 = j1.get<std::unordered_multimap<std::string, int>>();
02684 auto m2 = j2.get<std::unordered_multimap<std::string, unsigned int>>();
02685 auto m3 = j3.get<std::unordered_multimap<std::string, double>>();
02686 auto m4 = j4.get<std::unordered_multimap<std::string, bool>>();
02687
02688
02689 }
02690
02691 SECTION("exception in case of a non-object type")
02692 {
02693 CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), std::logic_error);
02694 CHECK_THROWS_WITH((json().get<std::map<std::string, int>>()), "type must be object, but is null");
02695 }
02696 }
02697
02698 SECTION("array-like STL containers")
02699 {
02700 json j1 = {1, 2, 3, 4};
02701 json j2 = {1u, 2u, 3u, 4u};
02702 json j3 = {1.2, 2.3, 3.4, 4.5};
02703 json j4 = {true, false, true};
02704 json j5 = {"one", "two", "three"};
02705
02706 SECTION("std::list")
02707 {
02708 auto m1 = j1.get<std::list<int>>();
02709 auto m2 = j2.get<std::list<unsigned int>>();
02710 auto m3 = j3.get<std::list<double>>();
02711 auto m4 = j4.get<std::list<bool>>();
02712 auto m5 = j5.get<std::list<std::string>>();
02713 }
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724 SECTION("std::vector")
02725 {
02726 auto m1 = j1.get<std::vector<int>>();
02727 auto m2 = j2.get<std::vector<unsigned int>>();
02728 auto m3 = j3.get<std::vector<double>>();
02729 auto m4 = j4.get<std::vector<bool>>();
02730 auto m5 = j5.get<std::vector<std::string>>();
02731 }
02732
02733 SECTION("std::deque")
02734 {
02735 auto m1 = j1.get<std::deque<int>>();
02736 auto m2 = j2.get<std::deque<unsigned int>>();
02737 auto m3 = j2.get<std::deque<double>>();
02738 auto m4 = j4.get<std::deque<bool>>();
02739 auto m5 = j5.get<std::deque<std::string>>();
02740 }
02741
02742 SECTION("std::set")
02743 {
02744 auto m1 = j1.get<std::set<int>>();
02745 auto m2 = j2.get<std::set<unsigned int>>();
02746 auto m3 = j3.get<std::set<double>>();
02747 auto m4 = j4.get<std::set<bool>>();
02748 auto m5 = j5.get<std::set<std::string>>();
02749 }
02750
02751 SECTION("std::unordered_set")
02752 {
02753 auto m1 = j1.get<std::unordered_set<int>>();
02754 auto m2 = j2.get<std::unordered_set<unsigned int>>();
02755 auto m3 = j3.get<std::unordered_set<double>>();
02756 auto m4 = j4.get<std::unordered_set<bool>>();
02757 auto m5 = j5.get<std::unordered_set<std::string>>();
02758 }
02759
02760 SECTION("exception in case of a non-object type")
02761 {
02762 CHECK_THROWS_AS((json().get<std::list<int>>()), std::logic_error);
02763 CHECK_THROWS_AS((json().get<std::vector<int>>()), std::logic_error);
02764 CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error);
02765 CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error);
02766
02767 CHECK_THROWS_WITH((json().get<std::list<int>>()), "type must be array, but is null");
02768 CHECK_THROWS_WITH((json().get<std::vector<int>>()), "type must be array, but is null");
02769 CHECK_THROWS_WITH((json().get<std::vector<json>>()), "type must be array, but is null");
02770 CHECK_THROWS_WITH((json().get<std::list<json>>()), "type must be array, but is null");
02771 }
02772 }
02773 }
02774 }
02775
02776 TEST_CASE("pointer access")
02777 {
02778
02779 json json_types =
02780 {
02781 {"boolean", true},
02782 {
02783 "number", {
02784 {"integer", 42},
02785 {"unsigned", 42u},
02786 {"floating-point", 17.23}
02787 }
02788 },
02789 {"string", "Hello, world!"},
02790 {"array", {1, 2, 3, 4, 5}},
02791 {"null", nullptr}
02792 };
02793
02794 SECTION("pointer access to object_t")
02795 {
02796 using test_type = json::object_t;
02797 json value = {{"one", 1}, {"two", 2}};
02798
02799
02800 test_type* p1 = value.get_ptr<test_type*>();
02801 CHECK(p1 == value.get_ptr<test_type*>());
02802 CHECK(*p1 == value.get<test_type>());
02803
02804 const test_type* p2 = value.get_ptr<const test_type*>();
02805 CHECK(p1 == value.get_ptr<const test_type*>());
02806 CHECK(*p2 == value.get<test_type>());
02807
02808 const test_type* const p3 = value.get_ptr<const test_type* const>();
02809 CHECK(p1 == value.get_ptr<const test_type* const>());
02810 CHECK(*p3 == value.get<test_type>());
02811
02812
02813 CHECK(value.get_ptr<json::object_t*>() != nullptr);
02814 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02815 CHECK(value.get_ptr<json::string_t*>() == nullptr);
02816 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
02817 CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
02818 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
02819 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02820 }
02821
02822 SECTION("pointer access to const object_t")
02823 {
02824 using test_type = json::object_t;
02825 const json value = {{"one", 1}, {"two", 2}};
02826
02827
02828
02829
02830
02831 const test_type* p2 = value.get_ptr<const test_type*>();
02832 CHECK(*p2 == value.get<test_type>());
02833
02834 const test_type* const p3 = value.get_ptr<const test_type* const>();
02835 CHECK(p2 == p3);
02836 }
02837
02838 SECTION("pointer access to array_t")
02839 {
02840 using test_type = json::array_t;
02841 json value = {1, 2, 3, 4};
02842
02843
02844 test_type* p1 = value.get_ptr<test_type*>();
02845 CHECK(p1 == value.get_ptr<test_type*>());
02846 CHECK(*p1 == value.get<test_type>());
02847
02848 const test_type* p2 = value.get_ptr<const test_type*>();
02849 CHECK(p1 == value.get_ptr<const test_type*>());
02850 CHECK(*p2 == value.get<test_type>());
02851
02852 const test_type* const p3 = value.get_ptr<const test_type* const>();
02853 CHECK(p1 == value.get_ptr<const test_type* const>());
02854 CHECK(*p3 == value.get<test_type>());
02855
02856
02857 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02858 CHECK(value.get_ptr<json::array_t*>() != nullptr);
02859 CHECK(value.get_ptr<json::string_t*>() == nullptr);
02860 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
02861 CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
02862 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
02863 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02864 }
02865
02866 SECTION("pointer access to string_t")
02867 {
02868 using test_type = json::string_t;
02869 json value = "hello";
02870
02871
02872 test_type* p1 = value.get_ptr<test_type*>();
02873 CHECK(p1 == value.get_ptr<test_type*>());
02874 CHECK(*p1 == value.get<test_type>());
02875
02876 const test_type* p2 = value.get_ptr<const test_type*>();
02877 CHECK(p1 == value.get_ptr<const test_type*>());
02878 CHECK(*p2 == value.get<test_type>());
02879
02880 const test_type* const p3 = value.get_ptr<const test_type* const>();
02881 CHECK(p1 == value.get_ptr<const test_type* const>());
02882 CHECK(*p3 == value.get<test_type>());
02883
02884
02885 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02886 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02887 CHECK(value.get_ptr<json::string_t*>() != nullptr);
02888 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
02889 CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
02890 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
02891 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02892 }
02893
02894 SECTION("pointer access to boolean_t")
02895 {
02896 using test_type = json::boolean_t;
02897 json value = false;
02898
02899
02900 test_type* p1 = value.get_ptr<test_type*>();
02901 CHECK(p1 == value.get_ptr<test_type*>());
02902 CHECK(*p1 == value.get<test_type>());
02903
02904 const test_type* p2 = value.get_ptr<const test_type*>();
02905 CHECK(p1 == value.get_ptr<const test_type*>());
02906 CHECK(*p2 == value.get<test_type>());
02907
02908 const test_type* const p3 = value.get_ptr<const test_type* const>();
02909 CHECK(p1 == value.get_ptr<const test_type* const>());
02910 CHECK(*p3 == value.get<test_type>());
02911
02912
02913 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02914 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02915 CHECK(value.get_ptr<json::string_t*>() == nullptr);
02916 CHECK(value.get_ptr<json::boolean_t*>() != nullptr);
02917 CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
02918 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
02919 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02920 }
02921
02922 SECTION("pointer access to number_integer_t")
02923 {
02924 using test_type = json::number_integer_t;
02925 json value = 23;
02926
02927
02928 test_type* p1 = value.get_ptr<test_type*>();
02929 CHECK(p1 == value.get_ptr<test_type*>());
02930 CHECK(*p1 == value.get<test_type>());
02931
02932 const test_type* p2 = value.get_ptr<const test_type*>();
02933 CHECK(p1 == value.get_ptr<const test_type*>());
02934 CHECK(*p2 == value.get<test_type>());
02935
02936 const test_type* const p3 = value.get_ptr<const test_type* const>();
02937 CHECK(p1 == value.get_ptr<const test_type* const>());
02938 CHECK(*p3 == value.get<test_type>());
02939
02940
02941 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02942 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02943 CHECK(value.get_ptr<json::string_t*>() == nullptr);
02944 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
02945 CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
02946 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
02947 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02948 }
02949
02950 SECTION("pointer access to number_unsigned_t")
02951 {
02952 using test_type = json::number_unsigned_t;
02953 json value = 23u;
02954
02955
02956 test_type* p1 = value.get_ptr<test_type*>();
02957 CHECK(p1 == value.get_ptr<test_type*>());
02958 CHECK(*p1 == value.get<test_type>());
02959
02960 const test_type* p2 = value.get_ptr<const test_type*>();
02961 CHECK(p1 == value.get_ptr<const test_type*>());
02962 CHECK(*p2 == value.get<test_type>());
02963
02964 const test_type* const p3 = value.get_ptr<const test_type* const>();
02965 CHECK(p1 == value.get_ptr<const test_type* const>());
02966 CHECK(*p3 == value.get<test_type>());
02967
02968
02969 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02970 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02971 CHECK(value.get_ptr<json::string_t*>() == nullptr);
02972 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
02973 CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
02974 CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
02975 CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
02976 }
02977
02978 SECTION("pointer access to number_float_t")
02979 {
02980 using test_type = json::number_float_t;
02981 json value = 42.23;
02982
02983
02984 test_type* p1 = value.get_ptr<test_type*>();
02985 CHECK(p1 == value.get_ptr<test_type*>());
02986 CHECK(*p1 == Approx(value.get<test_type>()));
02987
02988 const test_type* p2 = value.get_ptr<const test_type*>();
02989 CHECK(p1 == value.get_ptr<const test_type*>());
02990 CHECK(*p2 == Approx(value.get<test_type>()));
02991
02992 const test_type* const p3 = value.get_ptr<const test_type* const>();
02993 CHECK(p1 == value.get_ptr<const test_type* const>());
02994 CHECK(*p3 == Approx(value.get<test_type>()));
02995
02996
02997 CHECK(value.get_ptr<json::object_t*>() == nullptr);
02998 CHECK(value.get_ptr<json::array_t*>() == nullptr);
02999 CHECK(value.get_ptr<json::string_t*>() == nullptr);
03000 CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
03001 CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
03002 CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
03003 CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
03004 }
03005 }
03006
03007 TEST_CASE("reference access")
03008 {
03009
03010 json json_types =
03011 {
03012 {"boolean", true},
03013 {
03014 "number", {
03015 {"integer", 42},
03016 {"floating-point", 17.23}
03017 }
03018 },
03019 {"string", "Hello, world!"},
03020 {"array", {1, 2, 3, 4, 5}},
03021 {"null", nullptr}
03022 };
03023
03024 SECTION("reference access to object_t")
03025 {
03026 using test_type = json::object_t;
03027 json value = {{"one", 1}, {"two", 2}};
03028
03029
03030 test_type& p1 = value.get_ref<test_type&>();
03031 CHECK(&p1 == value.get_ptr<test_type*>());
03032 CHECK(p1 == value.get<test_type>());
03033
03034 const test_type& p2 = value.get_ref<const test_type&>();
03035 CHECK(&p2 == value.get_ptr<const test_type*>());
03036 CHECK(p2 == value.get<test_type>());
03037
03038
03039 CHECK_NOTHROW(value.get_ref<json::object_t&>());
03040 CHECK_THROWS(value.get_ref<json::array_t&>());
03041 CHECK_THROWS(value.get_ref<json::string_t&>());
03042 CHECK_THROWS(value.get_ref<json::boolean_t&>());
03043 CHECK_THROWS(value.get_ref<json::number_integer_t&>());
03044 CHECK_THROWS(value.get_ref<json::number_float_t&>());
03045 }
03046
03047 SECTION("const reference access to const object_t")
03048 {
03049 using test_type = json::object_t;
03050 const json value = {{"one", 1}, {"two", 2}};
03051
03052
03053
03054
03055
03056 const test_type& p2 = value.get_ref<const test_type&>();
03057 CHECK(&p2 == value.get_ptr<const test_type*>());
03058 CHECK(p2 == value.get<test_type>());
03059 }
03060
03061 SECTION("reference access to array_t")
03062 {
03063 using test_type = json::array_t;
03064 json value = {1, 2, 3, 4};
03065
03066
03067 test_type& p1 = value.get_ref<test_type&>();
03068 CHECK(&p1 == value.get_ptr<test_type*>());
03069 CHECK(p1 == value.get<test_type>());
03070
03071 const test_type& p2 = value.get_ref<const test_type&>();
03072 CHECK(&p2 == value.get_ptr<const test_type*>());
03073 CHECK(p2 == value.get<test_type>());
03074
03075
03076 CHECK_THROWS(value.get_ref<json::object_t&>());
03077 CHECK_NOTHROW(value.get_ref<json::array_t&>());
03078 CHECK_THROWS(value.get_ref<json::string_t&>());
03079 CHECK_THROWS(value.get_ref<json::boolean_t&>());
03080 CHECK_THROWS(value.get_ref<json::number_integer_t&>());
03081 CHECK_THROWS(value.get_ref<json::number_float_t&>());
03082 }
03083
03084 SECTION("reference access to string_t")
03085 {
03086 using test_type = json::string_t;
03087 json value = "hello";
03088
03089
03090 test_type& p1 = value.get_ref<test_type&>();
03091 CHECK(&p1 == value.get_ptr<test_type*>());
03092 CHECK(p1 == value.get<test_type>());
03093
03094 const test_type& p2 = value.get_ref<const test_type&>();
03095 CHECK(&p2 == value.get_ptr<const test_type*>());
03096 CHECK(p2 == value.get<test_type>());
03097
03098
03099 CHECK_THROWS(value.get_ref<json::object_t&>());
03100 CHECK_THROWS(value.get_ref<json::array_t&>());
03101 CHECK_NOTHROW(value.get_ref<json::string_t&>());
03102 CHECK_THROWS(value.get_ref<json::boolean_t&>());
03103 CHECK_THROWS(value.get_ref<json::number_integer_t&>());
03104 CHECK_THROWS(value.get_ref<json::number_float_t&>());
03105 }
03106
03107 SECTION("reference access to boolean_t")
03108 {
03109 using test_type = json::boolean_t;
03110 json value = false;
03111
03112
03113 test_type& p1 = value.get_ref<test_type&>();
03114 CHECK(&p1 == value.get_ptr<test_type*>());
03115 CHECK(p1 == value.get<test_type>());
03116
03117 const test_type& p2 = value.get_ref<const test_type&>();
03118 CHECK(&p2 == value.get_ptr<const test_type*>());
03119 CHECK(p2 == value.get<test_type>());
03120
03121
03122 CHECK_THROWS(value.get_ref<json::object_t&>());
03123 CHECK_THROWS(value.get_ref<json::array_t&>());
03124 CHECK_THROWS(value.get_ref<json::string_t&>());
03125 CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
03126 CHECK_THROWS(value.get_ref<json::number_integer_t&>());
03127 CHECK_THROWS(value.get_ref<json::number_float_t&>());
03128 }
03129
03130 SECTION("reference access to number_integer_t")
03131 {
03132 using test_type = json::number_integer_t;
03133 json value = 23;
03134
03135
03136 test_type& p1 = value.get_ref<test_type&>();
03137 CHECK(&p1 == value.get_ptr<test_type*>());
03138 CHECK(p1 == value.get<test_type>());
03139
03140 const test_type& p2 = value.get_ref<const test_type&>();
03141 CHECK(&p2 == value.get_ptr<const test_type*>());
03142 CHECK(p2 == value.get<test_type>());
03143
03144
03145 CHECK_THROWS(value.get_ref<json::object_t&>());
03146 CHECK_THROWS(value.get_ref<json::array_t&>());
03147 CHECK_THROWS(value.get_ref<json::string_t&>());
03148 CHECK_THROWS(value.get_ref<json::boolean_t&>());
03149 CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
03150 CHECK_THROWS(value.get_ref<json::number_float_t&>());
03151 }
03152
03153 SECTION("reference access to number_float_t")
03154 {
03155 using test_type = json::number_float_t;
03156 json value = 42.23;
03157
03158
03159 test_type& p1 = value.get_ref<test_type&>();
03160 CHECK(&p1 == value.get_ptr<test_type*>());
03161 CHECK(p1 == value.get<test_type>());
03162
03163 const test_type& p2 = value.get_ref<const test_type&>();
03164 CHECK(&p2 == value.get_ptr<const test_type*>());
03165 CHECK(p2 == value.get<test_type>());
03166
03167
03168 CHECK_THROWS(value.get_ref<json::object_t&>());
03169 CHECK_THROWS(value.get_ref<json::array_t&>());
03170 CHECK_THROWS(value.get_ref<json::string_t&>());
03171 CHECK_THROWS(value.get_ref<json::boolean_t&>());
03172 CHECK_THROWS(value.get_ref<json::number_integer_t&>());
03173 CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
03174 }
03175 }
03176
03177 TEST_CASE("element access")
03178 {
03179 SECTION("array")
03180 {
03181 json j = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03182 const json j_const = j;
03183
03184 SECTION("access specified element with bounds checking")
03185 {
03186 SECTION("access within bounds")
03187 {
03188 CHECK(j.at(0) == json(1));
03189 CHECK(j.at(1) == json(1u));
03190 CHECK(j.at(2) == json(true));
03191 CHECK(j.at(3) == json(nullptr));
03192 CHECK(j.at(4) == json("string"));
03193 CHECK(j.at(5) == json(42.23));
03194 CHECK(j.at(6) == json(json::object()));
03195 CHECK(j.at(7) == json({1, 2, 3}));
03196
03197 CHECK(j_const.at(0) == json(1));
03198 CHECK(j_const.at(1) == json(1u));
03199 CHECK(j_const.at(2) == json(true));
03200 CHECK(j_const.at(3) == json(nullptr));
03201 CHECK(j_const.at(4) == json("string"));
03202 CHECK(j_const.at(5) == json(42.23));
03203 CHECK(j_const.at(6) == json(json::object()));
03204 CHECK(j_const.at(7) == json({1, 2, 3}));
03205 }
03206
03207 SECTION("access outside bounds")
03208 {
03209 CHECK_THROWS_AS(j.at(8), std::out_of_range);
03210 CHECK_THROWS_AS(j_const.at(8), std::out_of_range);
03211
03212 CHECK_THROWS_WITH(j.at(8), "array index 8 is out of range");
03213 CHECK_THROWS_WITH(j_const.at(8), "array index 8 is out of range");
03214 }
03215
03216 SECTION("access on non-array type")
03217 {
03218 SECTION("null")
03219 {
03220 json j_nonarray(json::value_t::null);
03221 const json j_nonarray_const(j_nonarray);
03222 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03223 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03224
03225 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with null");
03226 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with null");
03227 }
03228
03229 SECTION("boolean")
03230 {
03231 json j_nonarray(json::value_t::boolean);
03232 const json j_nonarray_const(j_nonarray);
03233 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03234 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03235
03236 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with boolean");
03237 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with boolean");
03238 }
03239
03240 SECTION("string")
03241 {
03242 json j_nonarray(json::value_t::string);
03243 const json j_nonarray_const(j_nonarray);
03244 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03245 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03246
03247 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with string");
03248 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with string");
03249 }
03250
03251 SECTION("object")
03252 {
03253 json j_nonarray(json::value_t::object);
03254 const json j_nonarray_const(j_nonarray);
03255 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03256 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03257
03258 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with object");
03259 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with object");
03260 }
03261
03262 SECTION("number (integer)")
03263 {
03264 json j_nonarray(json::value_t::number_integer);
03265 const json j_nonarray_const(j_nonarray);
03266 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03267 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03268
03269 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
03270 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
03271 }
03272
03273 SECTION("number (unsigned)")
03274 {
03275 json j_nonarray(json::value_t::number_unsigned);
03276 const json j_nonarray_const(j_nonarray);
03277 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03278 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03279
03280 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
03281 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
03282 }
03283
03284 SECTION("number (floating-point)")
03285 {
03286 json j_nonarray(json::value_t::number_float);
03287 const json j_nonarray_const(j_nonarray);
03288 CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
03289 CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
03290
03291 CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
03292 CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
03293 }
03294 }
03295 }
03296
03297 SECTION("front and back")
03298 {
03299 CHECK(j.front() == json(1));
03300 CHECK(j_const.front() == json(1));
03301 CHECK(j.back() == json({1, 2, 3}));
03302 CHECK(j_const.back() == json({1, 2, 3}));
03303 }
03304
03305 SECTION("access specified element")
03306 {
03307 SECTION("access within bounds")
03308 {
03309 CHECK(j[0] == json(1));
03310 CHECK(j[1] == json(1u));
03311 CHECK(j[2] == json(true));
03312 CHECK(j[3] == json(nullptr));
03313 CHECK(j[4] == json("string"));
03314 CHECK(j[5] == json(42.23));
03315 CHECK(j[6] == json(json::object()));
03316 CHECK(j[7] == json({1, 2, 3}));
03317
03318 CHECK(j_const[0] == json(1));
03319 CHECK(j_const[1] == json(1u));
03320 CHECK(j_const[2] == json(true));
03321 CHECK(j_const[3] == json(nullptr));
03322 CHECK(j_const[4] == json("string"));
03323 CHECK(j_const[5] == json(42.23));
03324 CHECK(j_const[6] == json(json::object()));
03325 CHECK(j_const[7] == json({1, 2, 3}));
03326 }
03327
03328 SECTION("access on non-array type")
03329 {
03330 SECTION("null")
03331 {
03332 SECTION("standard tests")
03333 {
03334 json j_nonarray(json::value_t::null);
03335 const json j_nonarray_const(j_nonarray);
03336 CHECK_NOTHROW(j_nonarray[0]);
03337 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03338 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with null");
03339 }
03340
03341 SECTION("implicit transformation to properly filled array")
03342 {
03343 json j_nonarray;
03344 j_nonarray[3] = 42;
03345 CHECK(j_nonarray == json({nullptr, nullptr, nullptr, 42}));
03346 }
03347 }
03348
03349 SECTION("boolean")
03350 {
03351 json j_nonarray(json::value_t::boolean);
03352 const json j_nonarray_const(j_nonarray);
03353 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03354 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03355 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with boolean");
03356 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with boolean");
03357 }
03358
03359 SECTION("string")
03360 {
03361 json j_nonarray(json::value_t::string);
03362 const json j_nonarray_const(j_nonarray);
03363 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03364 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03365 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with string");
03366 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with string");
03367 }
03368
03369 SECTION("object")
03370 {
03371 json j_nonarray(json::value_t::object);
03372 const json j_nonarray_const(j_nonarray);
03373 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03374 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03375 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with object");
03376 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with object");
03377 }
03378
03379 SECTION("number (integer)")
03380 {
03381 json j_nonarray(json::value_t::number_integer);
03382 const json j_nonarray_const(j_nonarray);
03383 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03384 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03385 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
03386 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
03387 }
03388
03389 SECTION("number (unsigned)")
03390 {
03391 json j_nonarray(json::value_t::number_unsigned);
03392 const json j_nonarray_const(j_nonarray);
03393 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03394 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03395 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
03396 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
03397 }
03398
03399 SECTION("number (floating-point)")
03400 {
03401 json j_nonarray(json::value_t::number_float);
03402 const json j_nonarray_const(j_nonarray);
03403 CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
03404 CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
03405 CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
03406 CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
03407 }
03408 }
03409 }
03410
03411 SECTION("remove specified element")
03412 {
03413 SECTION("remove element by index")
03414 {
03415 {
03416 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03417 jarray.erase(0);
03418 CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03419 }
03420 {
03421 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03422 jarray.erase(1);
03423 CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03424 }
03425 {
03426 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03427 jarray.erase(2);
03428 CHECK(jarray == json({1, 1u, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03429 }
03430 {
03431 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03432 jarray.erase(3);
03433 CHECK(jarray == json({1, 1u, true, "string", 42.23, json::object(), {1, 2, 3}}));
03434 }
03435 {
03436 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03437 jarray.erase(4);
03438 CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
03439 }
03440 {
03441 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03442 jarray.erase(5);
03443 CHECK(jarray == json({1, 1u, true, nullptr, "string", json::object(), {1, 2, 3}}));
03444 }
03445 {
03446 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03447 jarray.erase(6);
03448 CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, {1, 2, 3}}));
03449 }
03450 {
03451 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03452 jarray.erase(7);
03453 CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object()}));
03454 }
03455 {
03456 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03457 CHECK_THROWS_AS(jarray.erase(8), std::out_of_range);
03458 CHECK_THROWS_WITH(jarray.erase(8), "array index 8 is out of range");
03459 }
03460 }
03461
03462 SECTION("remove element by iterator")
03463 {
03464 SECTION("erase(begin())")
03465 {
03466 {
03467 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03468 json::iterator it2 = jarray.erase(jarray.begin());
03469 CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03470 CHECK(*it2 == json(1u));
03471 }
03472 {
03473 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03474 json::const_iterator it2 = jarray.erase(jarray.cbegin());
03475 CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03476 CHECK(*it2 == json(1u));
03477 }
03478 }
03479
03480 SECTION("erase(begin(), end())")
03481 {
03482 {
03483 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03484 json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());
03485 CHECK(jarray == json::array());
03486 CHECK(it2 == jarray.end());
03487 }
03488 {
03489 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03490 json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());
03491 CHECK(jarray == json::array());
03492 CHECK(it2 == jarray.cend());
03493 }
03494 }
03495
03496 SECTION("erase(begin(), begin())")
03497 {
03498 {
03499 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03500 json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());
03501 CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03502 CHECK(*it2 == json(1));
03503 }
03504 {
03505 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03506 json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());
03507 CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
03508 CHECK(*it2 == json(1));
03509 }
03510 }
03511
03512 SECTION("erase at offset")
03513 {
03514 {
03515 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03516 json::iterator it = jarray.begin() + 4;
03517 json::iterator it2 = jarray.erase(it);
03518 CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
03519 CHECK(*it2 == json(42.23));
03520 }
03521 {
03522 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03523 json::const_iterator it = jarray.cbegin() + 4;
03524 json::const_iterator it2 = jarray.erase(it);
03525 CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
03526 CHECK(*it2 == json(42.23));
03527 }
03528 }
03529
03530 SECTION("erase subrange")
03531 {
03532 {
03533 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03534 json::iterator it2 = jarray.erase(jarray.begin() + 3, jarray.begin() + 6);
03535 CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
03536 CHECK(*it2 == json::object());
03537 }
03538 {
03539 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03540 json::const_iterator it2 = jarray.erase(jarray.cbegin() + 3, jarray.cbegin() + 6);
03541 CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
03542 CHECK(*it2 == json::object());
03543 }
03544 }
03545
03546 SECTION("different arrays")
03547 {
03548 {
03549 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03550 json jarray2 = {"foo", "bar"};
03551 CHECK_THROWS_AS(jarray.erase(jarray2.begin()), std::domain_error);
03552 CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error);
03553 CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error);
03554 CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error);
03555
03556 CHECK_THROWS_WITH(jarray.erase(jarray2.begin()), "iterator does not fit current value");
03557 CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()),
03558 "iterators do not fit current value");
03559 CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),
03560 "iterators do not fit current value");
03561 CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),
03562 "iterators do not fit current value");
03563 }
03564 {
03565 json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
03566 json jarray2 = {"foo", "bar"};
03567 CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), std::domain_error);
03568 CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error);
03569 CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error);
03570 CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error);
03571
03572 CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()), "iterator does not fit current value");
03573 CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()),
03574 "iterators do not fit current value");
03575 CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),
03576 "iterators do not fit current value");
03577 CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),
03578 "iterators do not fit current value");
03579 }
03580 }
03581 }
03582
03583 SECTION("remove element by index in non-array type")
03584 {
03585 SECTION("null")
03586 {
03587 json j_nonobject(json::value_t::null);
03588 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03589 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with null");
03590 }
03591
03592 SECTION("boolean")
03593 {
03594 json j_nonobject(json::value_t::boolean);
03595 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03596 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with boolean");
03597 }
03598
03599 SECTION("string")
03600 {
03601 json j_nonobject(json::value_t::string);
03602 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03603 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with string");
03604 }
03605
03606 SECTION("object")
03607 {
03608 json j_nonobject(json::value_t::object);
03609 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03610 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with object");
03611 }
03612
03613 SECTION("number (integer)")
03614 {
03615 json j_nonobject(json::value_t::number_integer);
03616 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03617 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
03618 }
03619
03620 SECTION("number (unsigned)")
03621 {
03622 json j_nonobject(json::value_t::number_unsigned);
03623 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03624 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
03625 }
03626
03627 SECTION("number (floating-point)")
03628 {
03629 json j_nonobject(json::value_t::number_float);
03630 CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
03631 CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
03632 }
03633 }
03634 }
03635 }
03636
03637 SECTION("object")
03638 {
03639 json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
03640 const json j_const = j;
03641
03642 SECTION("access specified element with bounds checking")
03643 {
03644 SECTION("access within bounds")
03645 {
03646 CHECK(j.at("integer") == json(1));
03647 CHECK(j.at("unsigned") == json(1u));
03648 CHECK(j.at("boolean") == json(true));
03649 CHECK(j.at("null") == json(nullptr));
03650 CHECK(j.at("string") == json("hello world"));
03651 CHECK(j.at("floating") == json(42.23));
03652 CHECK(j.at("object") == json(json::object()));
03653 CHECK(j.at("array") == json({1, 2, 3}));
03654
03655 CHECK(j_const.at("integer") == json(1));
03656 CHECK(j_const.at("unsigned") == json(1u));
03657 CHECK(j_const.at("boolean") == json(true));
03658 CHECK(j_const.at("null") == json(nullptr));
03659 CHECK(j_const.at("string") == json("hello world"));
03660 CHECK(j_const.at("floating") == json(42.23));
03661 CHECK(j_const.at("object") == json(json::object()));
03662 CHECK(j_const.at("array") == json({1, 2, 3}));
03663 }
03664
03665 SECTION("access outside bounds")
03666 {
03667 CHECK_THROWS_AS(j.at("foo"), std::out_of_range);
03668 CHECK_THROWS_AS(j_const.at("foo"), std::out_of_range);
03669 CHECK_THROWS_WITH(j.at("foo"), "key 'foo' not found");
03670 CHECK_THROWS_WITH(j_const.at("foo"), "key 'foo' not found");
03671 }
03672
03673 SECTION("access on non-object type")
03674 {
03675 SECTION("null")
03676 {
03677 json j_nonobject(json::value_t::null);
03678 const json j_nonobject_const(j_nonobject);
03679 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03680 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03681 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with null");
03682 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with null");
03683 }
03684
03685 SECTION("boolean")
03686 {
03687 json j_nonobject(json::value_t::boolean);
03688 const json j_nonobject_const(j_nonobject);
03689 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03690 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03691 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with boolean");
03692 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with boolean");
03693 }
03694
03695 SECTION("string")
03696 {
03697 json j_nonobject(json::value_t::string);
03698 const json j_nonobject_const(j_nonobject);
03699 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03700 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03701 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with string");
03702 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with string");
03703 }
03704
03705 SECTION("array")
03706 {
03707 json j_nonobject(json::value_t::array);
03708 const json j_nonobject_const(j_nonobject);
03709 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03710 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03711 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with array");
03712 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with array");
03713 }
03714
03715 SECTION("number (integer)")
03716 {
03717 json j_nonobject(json::value_t::number_integer);
03718 const json j_nonobject_const(j_nonobject);
03719 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03720 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03721 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number");
03722 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number");
03723 }
03724
03725 SECTION("number (unsigned)")
03726 {
03727 json j_nonobject(json::value_t::number_unsigned);
03728 const json j_nonobject_const(j_nonobject);
03729 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03730 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03731 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number");
03732 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number");
03733 }
03734
03735 SECTION("number (floating-point)")
03736 {
03737 json j_nonobject(json::value_t::number_float);
03738 const json j_nonobject_const(j_nonobject);
03739 CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
03740 CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
03741 CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number");
03742 CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number");
03743 }
03744 }
03745 }
03746
03747 SECTION("access specified element with default value")
03748 {
03749 SECTION("access existing value")
03750 {
03751 CHECK(j.value("integer", 2) == 1);
03752 CHECK(j.value("integer", 1.0) == Approx(1));
03753 CHECK(j.value("unsigned", 2) == 1u);
03754 CHECK(j.value("unsigned", 1.0) == Approx(1u));
03755 CHECK(j.value("null", json(1)) == json());
03756 CHECK(j.value("boolean", false) == true);
03757 CHECK(j.value("string", "bar") == "hello world");
03758 CHECK(j.value("string", std::string("bar")) == "hello world");
03759 CHECK(j.value("floating", 12.34) == Approx(42.23));
03760 CHECK(j.value("floating", 12) == 42);
03761 CHECK(j.value("object", json({{"foo", "bar"}})) == json(json::object()));
03762 CHECK(j.value("array", json({10, 100})) == json({1, 2, 3}));
03763
03764 CHECK(j_const.value("integer", 2) == 1);
03765 CHECK(j_const.value("integer", 1.0) == Approx(1));
03766 CHECK(j_const.value("unsigned", 2) == 1u);
03767 CHECK(j_const.value("unsigned", 1.0) == Approx(1u));
03768 CHECK(j_const.value("boolean", false) == true);
03769 CHECK(j_const.value("string", "bar") == "hello world");
03770 CHECK(j_const.value("string", std::string("bar")) == "hello world");
03771 CHECK(j_const.value("floating", 12.34) == Approx(42.23));
03772 CHECK(j_const.value("floating", 12) == 42);
03773 CHECK(j_const.value("object", json({{"foo", "bar"}})) == json(json::object()));
03774 CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3}));
03775 }
03776
03777 SECTION("access non-existing value")
03778 {
03779 CHECK(j.value("_", 2) == 2);
03780 CHECK(j.value("_", 2u) == 2u);
03781 CHECK(j.value("_", false) == false);
03782 CHECK(j.value("_", "bar") == "bar");
03783 CHECK(j.value("_", 12.34) == Approx(12.34));
03784 CHECK(j.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
03785 CHECK(j.value("_", json({10, 100})) == json({10, 100}));
03786
03787 CHECK(j_const.value("_", 2) == 2);
03788 CHECK(j_const.value("_", 2u) == 2u);
03789 CHECK(j_const.value("_", false) == false);
03790 CHECK(j_const.value("_", "bar") == "bar");
03791 CHECK(j_const.value("_", 12.34) == Approx(12.34));
03792 CHECK(j_const.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
03793 CHECK(j_const.value("_", json({10, 100})) == json({10, 100}));
03794 }
03795
03796 SECTION("access on non-object type")
03797 {
03798 SECTION("null")
03799 {
03800 json j_nonobject(json::value_t::null);
03801 const json j_nonobject_const(j_nonobject);
03802 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03803 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03804 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with null");
03805 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with null");
03806 }
03807
03808 SECTION("boolean")
03809 {
03810 json j_nonobject(json::value_t::boolean);
03811 const json j_nonobject_const(j_nonobject);
03812 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03813 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03814 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with boolean");
03815 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with boolean");
03816 }
03817
03818 SECTION("string")
03819 {
03820 json j_nonobject(json::value_t::string);
03821 const json j_nonobject_const(j_nonobject);
03822 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03823 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03824 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with string");
03825 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with string");
03826 }
03827
03828 SECTION("array")
03829 {
03830 json j_nonobject(json::value_t::array);
03831 const json j_nonobject_const(j_nonobject);
03832 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03833 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03834 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with array");
03835 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with array");
03836 }
03837
03838 SECTION("number (integer)")
03839 {
03840 json j_nonobject(json::value_t::number_integer);
03841 const json j_nonobject_const(j_nonobject);
03842 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03843 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03844 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number");
03845 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number");
03846 }
03847
03848 SECTION("number (unsigned)")
03849 {
03850 json j_nonobject(json::value_t::number_unsigned);
03851 const json j_nonobject_const(j_nonobject);
03852 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03853 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03854 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number");
03855 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number");
03856 }
03857
03858 SECTION("number (floating-point)")
03859 {
03860 json j_nonobject(json::value_t::number_float);
03861 const json j_nonobject_const(j_nonobject);
03862 CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
03863 CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
03864 CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number");
03865 CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number");
03866 }
03867 }
03868 }
03869
03870 SECTION("front and back")
03871 {
03872
03873 CHECK(j.front() == json({1, 2, 3}));
03874 CHECK(j_const.front() == json({1, 2, 3}));
03875
03876 CHECK(j.back() == json(1u));
03877 CHECK(j_const.back() == json(1u));
03878 }
03879
03880 SECTION("access specified element")
03881 {
03882 SECTION("access within bounds")
03883 {
03884 CHECK(j["integer"] == json(1));
03885 CHECK(j[json::object_t::key_type("integer")] == j["integer"]);
03886
03887 CHECK(j["unsigned"] == json(1u));
03888 CHECK(j[json::object_t::key_type("unsigned")] == j["unsigned"]);
03889
03890 CHECK(j["boolean"] == json(true));
03891 CHECK(j[json::object_t::key_type("boolean")] == j["boolean"]);
03892
03893 CHECK(j["null"] == json(nullptr));
03894 CHECK(j[json::object_t::key_type("null")] == j["null"]);
03895
03896 CHECK(j["string"] == json("hello world"));
03897 CHECK(j[json::object_t::key_type("string")] == j["string"]);
03898
03899 CHECK(j["floating"] == json(42.23));
03900 CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
03901
03902 CHECK(j["object"] == json(json::object()));
03903 CHECK(j[json::object_t::key_type("object")] == j["object"]);
03904
03905 CHECK(j["array"] == json({1, 2, 3}));
03906 CHECK(j[json::object_t::key_type("array")] == j["array"]);
03907
03908 CHECK(j_const["integer"] == json(1));
03909 CHECK(j_const[json::object_t::key_type("integer")] == j["integer"]);
03910
03911 CHECK(j_const["boolean"] == json(true));
03912 CHECK(j_const[json::object_t::key_type("boolean")] == j["boolean"]);
03913
03914 CHECK(j_const["null"] == json(nullptr));
03915 CHECK(j_const[json::object_t::key_type("null")] == j["null"]);
03916
03917 CHECK(j_const["string"] == json("hello world"));
03918 CHECK(j_const[json::object_t::key_type("string")] == j["string"]);
03919
03920 CHECK(j_const["floating"] == json(42.23));
03921 CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]);
03922
03923 CHECK(j_const["object"] == json(json::object()));
03924 CHECK(j_const[json::object_t::key_type("object")] == j["object"]);
03925
03926 CHECK(j_const["array"] == json({1, 2, 3}));
03927 CHECK(j_const[json::object_t::key_type("array")] == j["array"]);
03928 }
03929
03930 SECTION("access on non-object type")
03931 {
03932 SECTION("null")
03933 {
03934 json j_nonobject(json::value_t::null);
03935 json j_nonobject2(json::value_t::null);
03936 const json j_const_nonobject(j_nonobject);
03937 CHECK_NOTHROW(j_nonobject["foo"]);
03938 CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
03939 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
03940 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
03941 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with null");
03942 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
03943 "cannot use operator[] with null");
03944 }
03945
03946 SECTION("boolean")
03947 {
03948 json j_nonobject(json::value_t::boolean);
03949 const json j_const_nonobject(j_nonobject);
03950 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
03951 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
03952 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
03953 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
03954 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with boolean");
03955 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
03956 "cannot use operator[] with boolean");
03957 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with boolean");
03958 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
03959 "cannot use operator[] with boolean");
03960 }
03961
03962 SECTION("string")
03963 {
03964 json j_nonobject(json::value_t::string);
03965 const json j_const_nonobject(j_nonobject);
03966 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
03967 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
03968 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
03969 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
03970 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with string");
03971 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
03972 "cannot use operator[] with string");
03973 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with string");
03974 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
03975 "cannot use operator[] with string");
03976 }
03977
03978 SECTION("array")
03979 {
03980 json j_nonobject(json::value_t::array);
03981 const json j_const_nonobject(j_nonobject);
03982 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
03983 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
03984 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
03985 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
03986 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with array");
03987 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "cannot use operator[] with array");
03988 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with array");
03989 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
03990 "cannot use operator[] with array");
03991 }
03992
03993 SECTION("number (integer)")
03994 {
03995 json j_nonobject(json::value_t::number_integer);
03996 const json j_const_nonobject(j_nonobject);
03997 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
03998 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
03999 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
04000 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
04001 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number");
04002 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
04003 "cannot use operator[] with number");
04004 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number");
04005 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
04006 "cannot use operator[] with number");
04007 }
04008
04009 SECTION("number (unsigned)")
04010 {
04011 json j_nonobject(json::value_t::number_unsigned);
04012 const json j_const_nonobject(j_nonobject);
04013 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
04014 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
04015 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
04016 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
04017 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number");
04018 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
04019 "cannot use operator[] with number");
04020 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number");
04021 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
04022 "cannot use operator[] with number");
04023 }
04024
04025 SECTION("number (floating-point)")
04026 {
04027 json j_nonobject(json::value_t::number_float);
04028 const json j_const_nonobject(j_nonobject);
04029 CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
04030 CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
04031 CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
04032 CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
04033 CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number");
04034 CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
04035 "cannot use operator[] with number");
04036 CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number");
04037 CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
04038 "cannot use operator[] with number");
04039 }
04040 }
04041 }
04042
04043 SECTION("remove specified element")
04044 {
04045 SECTION("remove element by key")
04046 {
04047 CHECK(j.find("integer") != j.end());
04048 CHECK(j.erase("integer") == 1);
04049 CHECK(j.find("integer") == j.end());
04050 CHECK(j.erase("integer") == 0);
04051
04052 CHECK(j.find("unsigned") != j.end());
04053 CHECK(j.erase("unsigned") == 1);
04054 CHECK(j.find("unsigned") == j.end());
04055 CHECK(j.erase("unsigned") == 0);
04056
04057 CHECK(j.find("boolean") != j.end());
04058 CHECK(j.erase("boolean") == 1);
04059 CHECK(j.find("boolean") == j.end());
04060 CHECK(j.erase("boolean") == 0);
04061
04062 CHECK(j.find("null") != j.end());
04063 CHECK(j.erase("null") == 1);
04064 CHECK(j.find("null") == j.end());
04065 CHECK(j.erase("null") == 0);
04066
04067 CHECK(j.find("string") != j.end());
04068 CHECK(j.erase("string") == 1);
04069 CHECK(j.find("string") == j.end());
04070 CHECK(j.erase("string") == 0);
04071
04072 CHECK(j.find("floating") != j.end());
04073 CHECK(j.erase("floating") == 1);
04074 CHECK(j.find("floating") == j.end());
04075 CHECK(j.erase("floating") == 0);
04076
04077 CHECK(j.find("object") != j.end());
04078 CHECK(j.erase("object") == 1);
04079 CHECK(j.find("object") == j.end());
04080 CHECK(j.erase("object") == 0);
04081
04082 CHECK(j.find("array") != j.end());
04083 CHECK(j.erase("array") == 1);
04084 CHECK(j.find("array") == j.end());
04085 CHECK(j.erase("array") == 0);
04086 }
04087
04088 SECTION("remove element by iterator")
04089 {
04090 SECTION("erase(begin())")
04091 {
04092 {
04093 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04094 json::iterator it2 = jobject.erase(jobject.begin());
04095 CHECK(jobject == json({{"b", 1}, {"c", 17u}}));
04096 CHECK(*it2 == json(1));
04097 }
04098 {
04099 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04100 json::const_iterator it2 = jobject.erase(jobject.cbegin());
04101 CHECK(jobject == json({{"b", 1}, {"c", 17u}}));
04102 CHECK(*it2 == json(1));
04103 }
04104 }
04105
04106 SECTION("erase(begin(), end())")
04107 {
04108 {
04109 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04110 json::iterator it2 = jobject.erase(jobject.begin(), jobject.end());
04111 CHECK(jobject == json::object());
04112 CHECK(it2 == jobject.end());
04113 }
04114 {
04115 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04116 json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend());
04117 CHECK(jobject == json::object());
04118 CHECK(it2 == jobject.cend());
04119 }
04120 }
04121
04122 SECTION("erase(begin(), begin())")
04123 {
04124 {
04125 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04126 json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin());
04127 CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
04128 CHECK(*it2 == json("a"));
04129 }
04130 {
04131 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04132 json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin());
04133 CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
04134 CHECK(*it2 == json("a"));
04135 }
04136 }
04137
04138 SECTION("erase at offset")
04139 {
04140 {
04141 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04142 json::iterator it = jobject.find("b");
04143 json::iterator it2 = jobject.erase(it);
04144 CHECK(jobject == json({{"a", "a"}, {"c", 17u}}));
04145 CHECK(*it2 == json(17));
04146 }
04147 {
04148 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04149 json::const_iterator it = jobject.find("b");
04150 json::const_iterator it2 = jobject.erase(it);
04151 CHECK(jobject == json({{"a", "a"}, {"c", 17u}}));
04152 CHECK(*it2 == json(17));
04153 }
04154 }
04155
04156 SECTION("erase subrange")
04157 {
04158 {
04159 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
04160 json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
04161 CHECK(jobject == json({{"a", "a"}, {"e", true}}));
04162 CHECK(*it2 == json(true));
04163 }
04164 {
04165 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
04166 json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
04167 CHECK(jobject == json({{"a", "a"}, {"e", true}}));
04168 CHECK(*it2 == json(true));
04169 }
04170 }
04171
04172 SECTION("different objects")
04173 {
04174 {
04175 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
04176 json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04177 CHECK_THROWS_AS(jobject.erase(jobject2.begin()), std::domain_error);
04178 CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error);
04179 CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error);
04180 CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error);
04181 CHECK_THROWS_WITH(jobject.erase(jobject2.begin()), "iterator does not fit current value");
04182 CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()),
04183 "iterators do not fit current value");
04184 CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()),
04185 "iterators do not fit current value");
04186 CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()),
04187 "iterators do not fit current value");
04188 }
04189 {
04190 json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
04191 json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
04192 CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), std::domain_error);
04193 CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error);
04194 CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error);
04195 CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error);
04196 CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()), "iterator does not fit current value");
04197 CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()),
04198 "iterators do not fit current value");
04199 CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()),
04200 "iterators do not fit current value");
04201 CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()),
04202 "iterators do not fit current value");
04203 }
04204 }
04205 }
04206
04207 SECTION("remove element by key in non-object type")
04208 {
04209 SECTION("null")
04210 {
04211 json j_nonobject(json::value_t::null);
04212 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04213 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with null");
04214 }
04215
04216 SECTION("boolean")
04217 {
04218 json j_nonobject(json::value_t::boolean);
04219 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04220 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with boolean");
04221 }
04222
04223 SECTION("string")
04224 {
04225 json j_nonobject(json::value_t::string);
04226 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04227 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with string");
04228 }
04229
04230 SECTION("array")
04231 {
04232 json j_nonobject(json::value_t::array);
04233 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04234 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with array");
04235 }
04236
04237 SECTION("number (integer)")
04238 {
04239 json j_nonobject(json::value_t::number_integer);
04240 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04241 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number");
04242 }
04243
04244 SECTION("number (floating-point)")
04245 {
04246 json j_nonobject(json::value_t::number_float);
04247 CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
04248 CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number");
04249 }
04250 }
04251 }
04252
04253 SECTION("find an element in an object")
04254 {
04255 SECTION("existing element")
04256 {
04257 for (auto key :
04258 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
04259 })
04260 {
04261 CHECK(j.find(key) != j.end());
04262 CHECK(*j.find(key) == j.at(key));
04263 CHECK(j_const.find(key) != j_const.end());
04264 CHECK(*j_const.find(key) == j_const.at(key));
04265 }
04266 }
04267
04268 SECTION("nonexisting element")
04269 {
04270 CHECK(j.find("foo") == j.end());
04271 CHECK(j_const.find("foo") == j_const.end());
04272 }
04273
04274 SECTION("all types")
04275 {
04276 SECTION("null")
04277 {
04278 json j_nonarray(json::value_t::null);
04279 const json j_nonarray_const(j_nonarray);
04280 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04281 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04282 }
04283
04284 SECTION("string")
04285 {
04286 json j_nonarray(json::value_t::string);
04287 const json j_nonarray_const(j_nonarray);
04288 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04289 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04290 }
04291
04292 SECTION("object")
04293 {
04294 json j_nonarray(json::value_t::object);
04295 const json j_nonarray_const(j_nonarray);
04296 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04297 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04298 }
04299
04300 SECTION("array")
04301 {
04302 json j_nonarray(json::value_t::array);
04303 const json j_nonarray_const(j_nonarray);
04304 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04305 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04306 }
04307
04308 SECTION("boolean")
04309 {
04310 json j_nonarray(json::value_t::boolean);
04311 const json j_nonarray_const(j_nonarray);
04312 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04313 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04314 }
04315
04316 SECTION("number (integer)")
04317 {
04318 json j_nonarray(json::value_t::number_integer);
04319 const json j_nonarray_const(j_nonarray);
04320 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04321 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04322 }
04323
04324 SECTION("number (unsigned)")
04325 {
04326 json j_nonarray(json::value_t::number_unsigned);
04327 const json j_nonarray_const(j_nonarray);
04328 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04329 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04330 }
04331
04332 SECTION("number (floating-point)")
04333 {
04334 json j_nonarray(json::value_t::number_float);
04335 const json j_nonarray_const(j_nonarray);
04336 CHECK(j_nonarray.find("foo") == j_nonarray.end());
04337 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
04338 }
04339 }
04340 }
04341
04342 SECTION("count keys in an object")
04343 {
04344 SECTION("existing element")
04345 {
04346 for (auto key :
04347 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
04348 })
04349 {
04350 CHECK(j.count(key) == 1);
04351 CHECK(j_const.count(key) == 1);
04352 }
04353 }
04354
04355 SECTION("nonexisting element")
04356 {
04357 CHECK(j.count("foo") == 0);
04358 CHECK(j_const.count("foo") == 0);
04359 }
04360
04361 SECTION("all types")
04362 {
04363 SECTION("null")
04364 {
04365 json j_nonobject(json::value_t::null);
04366 const json j_nonobject_const(j_nonobject);
04367 CHECK(j_nonobject.count("foo") == 0);
04368 CHECK(j_nonobject_const.count("foo") == 0);
04369 }
04370
04371 SECTION("string")
04372 {
04373 json j_nonobject(json::value_t::string);
04374 const json j_nonobject_const(j_nonobject);
04375 CHECK(j_nonobject.count("foo") == 0);
04376 CHECK(j_nonobject_const.count("foo") == 0);
04377 }
04378
04379 SECTION("object")
04380 {
04381 json j_nonobject(json::value_t::object);
04382 const json j_nonobject_const(j_nonobject);
04383 CHECK(j_nonobject.count("foo") == 0);
04384 CHECK(j_nonobject_const.count("foo") == 0);
04385 }
04386
04387 SECTION("array")
04388 {
04389 json j_nonobject(json::value_t::array);
04390 const json j_nonobject_const(j_nonobject);
04391 CHECK(j_nonobject.count("foo") == 0);
04392 CHECK(j_nonobject_const.count("foo") == 0);
04393 }
04394
04395 SECTION("boolean")
04396 {
04397 json j_nonobject(json::value_t::boolean);
04398 const json j_nonobject_const(j_nonobject);
04399 CHECK(j_nonobject.count("foo") == 0);
04400 CHECK(j_nonobject_const.count("foo") == 0);
04401 }
04402
04403 SECTION("number (integer)")
04404 {
04405 json j_nonobject(json::value_t::number_integer);
04406 const json j_nonobject_const(j_nonobject);
04407 CHECK(j_nonobject.count("foo") == 0);
04408 CHECK(j_nonobject_const.count("foo") == 0);
04409 }
04410
04411 SECTION("number (unsigned)")
04412 {
04413 json j_nonobject(json::value_t::number_unsigned);
04414 const json j_nonobject_const(j_nonobject);
04415 CHECK(j_nonobject.count("foo") == 0);
04416 CHECK(j_nonobject_const.count("foo") == 0);
04417 }
04418
04419 SECTION("number (floating-point)")
04420 {
04421 json j_nonobject(json::value_t::number_float);
04422 const json j_nonobject_const(j_nonobject);
04423 CHECK(j_nonobject.count("foo") == 0);
04424 CHECK(j_nonobject_const.count("foo") == 0);
04425 }
04426 }
04427 }
04428 }
04429
04430 SECTION("other values")
04431 {
04432 SECTION("front and back")
04433 {
04434 SECTION("null")
04435 {
04436 {
04437 json j;
04438 CHECK_THROWS_AS(j.front(), std::out_of_range);
04439 CHECK_THROWS_AS(j.back(), std::out_of_range);
04440 CHECK_THROWS_WITH(j.front(), "cannot get value");
04441 CHECK_THROWS_WITH(j.back(), "cannot get value");
04442 }
04443 {
04444 const json j{};
04445 CHECK_THROWS_AS(j.front(), std::out_of_range);
04446 CHECK_THROWS_AS(j.back(), std::out_of_range);
04447 CHECK_THROWS_WITH(j.front(), "cannot get value");
04448 CHECK_THROWS_WITH(j.back(), "cannot get value");
04449 }
04450 }
04451
04452 SECTION("string")
04453 {
04454 {
04455 json j = "foo";
04456 CHECK(j.front() == j);
04457 CHECK(j.back() == j);
04458 }
04459 {
04460 const json j = "bar";
04461 CHECK(j.front() == j);
04462 CHECK(j.back() == j);
04463 }
04464 }
04465
04466 SECTION("number (boolean)")
04467 {
04468 {
04469 json j = false;
04470 CHECK(j.front() == j);
04471 CHECK(j.back() == j);
04472 }
04473 {
04474 const json j = true;
04475 CHECK(j.front() == j);
04476 CHECK(j.back() == j);
04477 }
04478 }
04479
04480 SECTION("number (integer)")
04481 {
04482 {
04483 json j = 17;
04484 CHECK(j.front() == j);
04485 CHECK(j.back() == j);
04486 }
04487 {
04488 const json j = 17;
04489 CHECK(j.front() == j);
04490 CHECK(j.back() == j);
04491 }
04492 }
04493
04494 SECTION("number (unsigned)")
04495 {
04496 {
04497 json j = 17u;
04498 CHECK(j.front() == j);
04499 CHECK(j.back() == j);
04500 }
04501 {
04502 const json j = 17u;
04503 CHECK(j.front() == j);
04504 CHECK(j.back() == j);
04505 }
04506 }
04507
04508 SECTION("number (floating point)")
04509 {
04510 {
04511 json j = 23.42;
04512 CHECK(j.front() == j);
04513 CHECK(j.back() == j);
04514 }
04515 {
04516 const json j = 23.42;
04517 CHECK(j.front() == j);
04518 CHECK(j.back() == j);
04519 }
04520 }
04521 }
04522
04523 SECTION("erase with one valid iterator")
04524 {
04525 SECTION("null")
04526 {
04527 {
04528 json j;
04529 CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error);
04530 CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
04531 }
04532 {
04533 json j;
04534 CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error);
04535 CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
04536 }
04537 }
04538
04539 SECTION("string")
04540 {
04541 {
04542 json j = "foo";
04543 json::iterator it = j.erase(j.begin());
04544 CHECK(j.type() == json::value_t::null);
04545 CHECK(it == j.end());
04546 }
04547 {
04548 json j = "bar";
04549 json::const_iterator it = j.erase(j.cbegin());
04550 CHECK(j.type() == json::value_t::null);
04551 CHECK(it == j.end());
04552 }
04553 }
04554
04555 SECTION("number (boolean)")
04556 {
04557 {
04558 json j = false;
04559 json::iterator it = j.erase(j.begin());
04560 CHECK(j.type() == json::value_t::null);
04561 CHECK(it == j.end());
04562 }
04563 {
04564 json j = true;
04565 json::const_iterator it = j.erase(j.cbegin());
04566 CHECK(j.type() == json::value_t::null);
04567 CHECK(it == j.end());
04568 }
04569 }
04570
04571 SECTION("number (integer)")
04572 {
04573 {
04574 json j = 17;
04575 json::iterator it = j.erase(j.begin());
04576 CHECK(j.type() == json::value_t::null);
04577 CHECK(it == j.end());
04578 }
04579 {
04580 json j = 17;
04581 json::const_iterator it = j.erase(j.cbegin());
04582 CHECK(j.type() == json::value_t::null);
04583 CHECK(it == j.end());
04584 }
04585 }
04586
04587 SECTION("number (unsigned)")
04588 {
04589 {
04590 json j = 17u;
04591 json::iterator it = j.erase(j.begin());
04592 CHECK(j.type() == json::value_t::null);
04593 CHECK(it == j.end());
04594 }
04595 {
04596 json j = 17u;
04597 json::const_iterator it = j.erase(j.cbegin());
04598 CHECK(j.type() == json::value_t::null);
04599 CHECK(it == j.end());
04600 }
04601 }
04602
04603 SECTION("number (floating point)")
04604 {
04605 {
04606 json j = 23.42;
04607 json::iterator it = j.erase(j.begin());
04608 CHECK(j.type() == json::value_t::null);
04609 CHECK(it == j.end());
04610 }
04611 {
04612 json j = 23.42;
04613 json::const_iterator it = j.erase(j.cbegin());
04614 CHECK(j.type() == json::value_t::null);
04615 CHECK(it == j.end());
04616 }
04617 }
04618 }
04619
04620 SECTION("erase with one invalid iterator")
04621 {
04622 SECTION("string")
04623 {
04624 {
04625 json j = "foo";
04626 CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
04627 CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
04628 }
04629 {
04630 json j = "bar";
04631 CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
04632 CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
04633 }
04634 }
04635
04636 SECTION("number (boolean)")
04637 {
04638 {
04639 json j = false;
04640 CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
04641 CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
04642 }
04643 {
04644 json j = true;
04645 CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
04646 CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
04647 }
04648 }
04649
04650 SECTION("number (integer)")
04651 {
04652 {
04653 json j = 17;
04654 CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
04655 CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
04656 }
04657 {
04658 json j = 17;
04659 CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
04660 CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
04661 }
04662 }
04663
04664 SECTION("number (unsigned)")
04665 {
04666 {
04667 json j = 17u;
04668 CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
04669 CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
04670 }
04671 {
04672 json j = 17u;
04673 CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
04674 CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
04675 }
04676 }
04677
04678 SECTION("number (floating point)")
04679 {
04680 {
04681 json j = 23.42;
04682 CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
04683 CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
04684 }
04685 {
04686 json j = 23.42;
04687 CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
04688 CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
04689 }
04690 }
04691 }
04692
04693 SECTION("erase with two valid iterators")
04694 {
04695 SECTION("null")
04696 {
04697 {
04698 json j;
04699 CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error);
04700 CHECK_THROWS_WITH(j.erase(j.begin(), j.end()), "cannot use erase() with null");
04701 }
04702 {
04703 json j;
04704 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error);
04705 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()), "cannot use erase() with null");
04706 }
04707 }
04708
04709 SECTION("string")
04710 {
04711 {
04712 json j = "foo";
04713 json::iterator it = j.erase(j.begin(), j.end());
04714 CHECK(j.type() == json::value_t::null);
04715 CHECK(it == j.end());
04716 }
04717 {
04718 json j = "bar";
04719 json::const_iterator it = j.erase(j.cbegin(), j.cend());
04720 CHECK(j.type() == json::value_t::null);
04721 CHECK(it == j.end());
04722 }
04723 }
04724
04725 SECTION("number (boolean)")
04726 {
04727 {
04728 json j = false;
04729 json::iterator it = j.erase(j.begin(), j.end());
04730 CHECK(j.type() == json::value_t::null);
04731 CHECK(it == j.end());
04732 }
04733 {
04734 json j = true;
04735 json::const_iterator it = j.erase(j.cbegin(), j.cend());
04736 CHECK(j.type() == json::value_t::null);
04737 CHECK(it == j.end());
04738 }
04739 }
04740
04741 SECTION("number (integer)")
04742 {
04743 {
04744 json j = 17;
04745 json::iterator it = j.erase(j.begin(), j.end());
04746 CHECK(j.type() == json::value_t::null);
04747 CHECK(it == j.end());
04748 }
04749 {
04750 json j = 17;
04751 json::const_iterator it = j.erase(j.cbegin(), j.cend());
04752 CHECK(j.type() == json::value_t::null);
04753 CHECK(it == j.end());
04754 }
04755 }
04756
04757 SECTION("number (unsigned)")
04758 {
04759 {
04760 json j = 17u;
04761 json::iterator it = j.erase(j.begin(), j.end());
04762 CHECK(j.type() == json::value_t::null);
04763 CHECK(it == j.end());
04764 }
04765 {
04766 json j = 17u;
04767 json::const_iterator it = j.erase(j.cbegin(), j.cend());
04768 CHECK(j.type() == json::value_t::null);
04769 CHECK(it == j.end());
04770 }
04771 }
04772
04773 SECTION("number (floating point)")
04774 {
04775 {
04776 json j = 23.42;
04777 json::iterator it = j.erase(j.begin(), j.end());
04778 CHECK(j.type() == json::value_t::null);
04779 CHECK(it == j.end());
04780 }
04781 {
04782 json j = 23.42;
04783 json::const_iterator it = j.erase(j.cbegin(), j.cend());
04784 CHECK(j.type() == json::value_t::null);
04785 CHECK(it == j.end());
04786 }
04787 }
04788 }
04789
04790 SECTION("erase with two invalid iterators")
04791 {
04792 SECTION("string")
04793 {
04794 {
04795 json j = "foo";
04796 CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
04797 CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
04798 CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
04799 CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
04800 }
04801 {
04802 json j = "bar";
04803 CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
04804 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
04805 CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
04806 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
04807 }
04808 }
04809
04810 SECTION("number (boolean)")
04811 {
04812 {
04813 json j = false;
04814 CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
04815 CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
04816 CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
04817 CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
04818 }
04819 {
04820 json j = true;
04821 CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
04822 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
04823 CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
04824 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
04825 }
04826 }
04827
04828 SECTION("number (integer)")
04829 {
04830 {
04831 json j = 17;
04832 CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
04833 CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
04834 CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
04835 CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
04836 }
04837 {
04838 json j = 17;
04839 CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
04840 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
04841 CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
04842 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
04843 }
04844 }
04845
04846 SECTION("number (unsigned)")
04847 {
04848 {
04849 json j = 17u;
04850 CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
04851 CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
04852 CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
04853 CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
04854 }
04855 {
04856 json j = 17u;
04857 CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
04858 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
04859 CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
04860 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
04861 }
04862 }
04863
04864 SECTION("number (floating point)")
04865 {
04866 {
04867 json j = 23.42;
04868 CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
04869 CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
04870 CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
04871 CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
04872 }
04873 {
04874 json j = 23.42;
04875 CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
04876 CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
04877 CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
04878 CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
04879 }
04880 }
04881 }
04882 }
04883 }
04884
04885 TEST_CASE("iterators")
04886 {
04887 SECTION("basic behavior")
04888 {
04889 SECTION("uninitialized")
04890 {
04891 json::iterator it;
04892 CHECK(it.m_object == nullptr);
04893
04894 json::const_iterator cit;
04895 CHECK(cit.m_object == nullptr);
04896 }
04897
04898 SECTION("boolean")
04899 {
04900 json j = true;
04901 json j_const(j);
04902
04903 SECTION("json + begin/end")
04904 {
04905 json::iterator it = j.begin();
04906 CHECK(it != j.end());
04907 CHECK(*it == j);
04908
04909 it++;
04910 CHECK(it != j.begin());
04911 CHECK(it == j.end());
04912
04913 it--;
04914 CHECK(it == j.begin());
04915 CHECK(it != j.end());
04916 CHECK(*it == j);
04917
04918 ++it;
04919 CHECK(it != j.begin());
04920 CHECK(it == j.end());
04921
04922 --it;
04923 CHECK(it == j.begin());
04924 CHECK(it != j.end());
04925 CHECK(*it == j);
04926 }
04927
04928 SECTION("const json + begin/end")
04929 {
04930 json::const_iterator it = j_const.begin();
04931 CHECK(it != j_const.end());
04932 CHECK(*it == j_const);
04933
04934 it++;
04935 CHECK(it != j_const.begin());
04936 CHECK(it == j_const.end());
04937
04938 it--;
04939 CHECK(it == j_const.begin());
04940 CHECK(it != j_const.end());
04941 CHECK(*it == j_const);
04942
04943 ++it;
04944 CHECK(it != j_const.begin());
04945 CHECK(it == j_const.end());
04946
04947 --it;
04948 CHECK(it == j_const.begin());
04949 CHECK(it != j_const.end());
04950 CHECK(*it == j_const);
04951 }
04952
04953 SECTION("json + cbegin/cend")
04954 {
04955 json::const_iterator it = j.cbegin();
04956 CHECK(it != j.cend());
04957 CHECK(*it == j);
04958
04959 it++;
04960 CHECK(it != j.cbegin());
04961 CHECK(it == j.cend());
04962
04963 it--;
04964 CHECK(it == j.cbegin());
04965 CHECK(it != j.cend());
04966 CHECK(*it == j);
04967
04968 ++it;
04969 CHECK(it != j.cbegin());
04970 CHECK(it == j.cend());
04971
04972 --it;
04973 CHECK(it == j.cbegin());
04974 CHECK(it != j.cend());
04975 CHECK(*it == j);
04976 }
04977
04978 SECTION("const json + cbegin/cend")
04979 {
04980 json::const_iterator it = j_const.cbegin();
04981 CHECK(it != j_const.cend());
04982 CHECK(*it == j_const);
04983
04984 it++;
04985 CHECK(it != j_const.cbegin());
04986 CHECK(it == j_const.cend());
04987
04988 it--;
04989 CHECK(it == j_const.cbegin());
04990 CHECK(it != j_const.cend());
04991 CHECK(*it == j_const);
04992
04993 ++it;
04994 CHECK(it != j_const.cbegin());
04995 CHECK(it == j_const.cend());
04996
04997 --it;
04998 CHECK(it == j_const.cbegin());
04999 CHECK(it != j_const.cend());
05000 CHECK(*it == j_const);
05001 }
05002
05003 SECTION("json + rbegin/rend")
05004 {
05005 json::reverse_iterator it = j.rbegin();
05006 CHECK(it != j.rend());
05007 CHECK(*it == j);
05008
05009 it++;
05010 CHECK(it != j.rbegin());
05011 CHECK(it == j.rend());
05012
05013 it--;
05014 CHECK(it == j.rbegin());
05015 CHECK(it != j.rend());
05016 CHECK(*it == j);
05017
05018 ++it;
05019 CHECK(it != j.rbegin());
05020 CHECK(it == j.rend());
05021
05022 --it;
05023 CHECK(it == j.rbegin());
05024 CHECK(it != j.rend());
05025 CHECK(*it == j);
05026 }
05027
05028 SECTION("json + crbegin/crend")
05029 {
05030 json::const_reverse_iterator it = j.crbegin();
05031 CHECK(it != j.crend());
05032 CHECK(*it == j);
05033
05034 it++;
05035 CHECK(it != j.crbegin());
05036 CHECK(it == j.crend());
05037
05038 it--;
05039 CHECK(it == j.crbegin());
05040 CHECK(it != j.crend());
05041 CHECK(*it == j);
05042
05043 ++it;
05044 CHECK(it != j.crbegin());
05045 CHECK(it == j.crend());
05046
05047 --it;
05048 CHECK(it == j.crbegin());
05049 CHECK(it != j.crend());
05050 CHECK(*it == j);
05051 }
05052
05053 SECTION("const json + crbegin/crend")
05054 {
05055 json::const_reverse_iterator it = j_const.crbegin();
05056 CHECK(it != j_const.crend());
05057 CHECK(*it == j_const);
05058
05059 it++;
05060 CHECK(it != j_const.crbegin());
05061 CHECK(it == j_const.crend());
05062
05063 it--;
05064 CHECK(it == j_const.crbegin());
05065 CHECK(it != j_const.crend());
05066 CHECK(*it == j_const);
05067
05068 ++it;
05069 CHECK(it != j_const.crbegin());
05070 CHECK(it == j_const.crend());
05071
05072 --it;
05073 CHECK(it == j_const.crbegin());
05074 CHECK(it != j_const.crend());
05075 CHECK(*it == j_const);
05076 }
05077
05078 SECTION("key/value")
05079 {
05080 auto it = j.begin();
05081 auto cit = j_const.cbegin();
05082 CHECK_THROWS_AS(it.key(), std::domain_error);
05083 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
05084 CHECK(it.value() == json(true));
05085 CHECK_THROWS_AS(cit.key(), std::domain_error);
05086 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
05087 CHECK(cit.value() == json(true));
05088
05089 auto rit = j.rend();
05090 auto crit = j.crend();
05091 CHECK_THROWS_AS(rit.key(), std::domain_error);
05092 CHECK_THROWS_AS(rit.value(), std::out_of_range);
05093 CHECK_THROWS_AS(crit.key(), std::domain_error);
05094 CHECK_THROWS_AS(crit.value(), std::out_of_range);
05095 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
05096 CHECK_THROWS_WITH(rit.value(), "cannot get value");
05097 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
05098 CHECK_THROWS_WITH(crit.value(), "cannot get value");
05099 }
05100 }
05101
05102 SECTION("string")
05103 {
05104 json j = "hello world";
05105 json j_const(j);
05106
05107 SECTION("json + begin/end")
05108 {
05109 json::iterator it = j.begin();
05110 CHECK(it != j.end());
05111 CHECK(*it == j);
05112
05113 it++;
05114 CHECK(it != j.begin());
05115 CHECK(it == j.end());
05116
05117 it--;
05118 CHECK(it == j.begin());
05119 CHECK(it != j.end());
05120 CHECK(*it == j);
05121
05122 ++it;
05123 CHECK(it != j.begin());
05124 CHECK(it == j.end());
05125
05126 --it;
05127 CHECK(it == j.begin());
05128 CHECK(it != j.end());
05129 CHECK(*it == j);
05130 }
05131
05132 SECTION("const json + begin/end")
05133 {
05134 json::const_iterator it = j_const.begin();
05135 CHECK(it != j_const.end());
05136 CHECK(*it == j_const);
05137
05138 it++;
05139 CHECK(it != j_const.begin());
05140 CHECK(it == j_const.end());
05141
05142 it--;
05143 CHECK(it == j_const.begin());
05144 CHECK(it != j_const.end());
05145 CHECK(*it == j_const);
05146
05147 ++it;
05148 CHECK(it != j_const.begin());
05149 CHECK(it == j_const.end());
05150
05151 --it;
05152 CHECK(it == j_const.begin());
05153 CHECK(it != j_const.end());
05154 CHECK(*it == j_const);
05155 }
05156
05157 SECTION("json + cbegin/cend")
05158 {
05159 json::const_iterator it = j.cbegin();
05160 CHECK(it != j.cend());
05161 CHECK(*it == j);
05162
05163 it++;
05164 CHECK(it != j.cbegin());
05165 CHECK(it == j.cend());
05166
05167 it--;
05168 CHECK(it == j.cbegin());
05169 CHECK(it != j.cend());
05170 CHECK(*it == j);
05171
05172 ++it;
05173 CHECK(it != j.cbegin());
05174 CHECK(it == j.cend());
05175
05176 --it;
05177 CHECK(it == j.cbegin());
05178 CHECK(it != j.cend());
05179 CHECK(*it == j);
05180 }
05181
05182 SECTION("const json + cbegin/cend")
05183 {
05184 json::const_iterator it = j_const.cbegin();
05185 CHECK(it != j_const.cend());
05186 CHECK(*it == j_const);
05187
05188 it++;
05189 CHECK(it != j_const.cbegin());
05190 CHECK(it == j_const.cend());
05191
05192 it--;
05193 CHECK(it == j_const.cbegin());
05194 CHECK(it != j_const.cend());
05195 CHECK(*it == j_const);
05196
05197 ++it;
05198 CHECK(it != j_const.cbegin());
05199 CHECK(it == j_const.cend());
05200
05201 --it;
05202 CHECK(it == j_const.cbegin());
05203 CHECK(it != j_const.cend());
05204 CHECK(*it == j_const);
05205 }
05206
05207 SECTION("json + rbegin/rend")
05208 {
05209 json::reverse_iterator it = j.rbegin();
05210 CHECK(it != j.rend());
05211 CHECK(*it == j);
05212
05213 it++;
05214 CHECK(it != j.rbegin());
05215 CHECK(it == j.rend());
05216
05217 it--;
05218 CHECK(it == j.rbegin());
05219 CHECK(it != j.rend());
05220 CHECK(*it == j);
05221
05222 ++it;
05223 CHECK(it != j.rbegin());
05224 CHECK(it == j.rend());
05225
05226 --it;
05227 CHECK(it == j.rbegin());
05228 CHECK(it != j.rend());
05229 CHECK(*it == j);
05230 }
05231
05232 SECTION("json + crbegin/crend")
05233 {
05234 json::const_reverse_iterator it = j.crbegin();
05235 CHECK(it != j.crend());
05236 CHECK(*it == j);
05237
05238 it++;
05239 CHECK(it != j.crbegin());
05240 CHECK(it == j.crend());
05241
05242 it--;
05243 CHECK(it == j.crbegin());
05244 CHECK(it != j.crend());
05245 CHECK(*it == j);
05246
05247 ++it;
05248 CHECK(it != j.crbegin());
05249 CHECK(it == j.crend());
05250
05251 --it;
05252 CHECK(it == j.crbegin());
05253 CHECK(it != j.crend());
05254 CHECK(*it == j);
05255 }
05256
05257 SECTION("const json + crbegin/crend")
05258 {
05259 json::const_reverse_iterator it = j_const.crbegin();
05260 CHECK(it != j_const.crend());
05261 CHECK(*it == j_const);
05262
05263 it++;
05264 CHECK(it != j_const.crbegin());
05265 CHECK(it == j_const.crend());
05266
05267 it--;
05268 CHECK(it == j_const.crbegin());
05269 CHECK(it != j_const.crend());
05270 CHECK(*it == j_const);
05271
05272 ++it;
05273 CHECK(it != j_const.crbegin());
05274 CHECK(it == j_const.crend());
05275
05276 --it;
05277 CHECK(it == j_const.crbegin());
05278 CHECK(it != j_const.crend());
05279 CHECK(*it == j_const);
05280 }
05281
05282 SECTION("key/value")
05283 {
05284 auto it = j.begin();
05285 auto cit = j_const.cbegin();
05286 CHECK_THROWS_AS(it.key(), std::domain_error);
05287 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
05288 CHECK(it.value() == json("hello world"));
05289 CHECK_THROWS_AS(cit.key(), std::domain_error);
05290 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
05291 CHECK(cit.value() == json("hello world"));
05292
05293 auto rit = j.rend();
05294 auto crit = j.crend();
05295 CHECK_THROWS_AS(rit.key(), std::domain_error);
05296 CHECK_THROWS_AS(rit.value(), std::out_of_range);
05297 CHECK_THROWS_AS(crit.key(), std::domain_error);
05298 CHECK_THROWS_AS(crit.value(), std::out_of_range);
05299 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
05300 CHECK_THROWS_WITH(rit.value(), "cannot get value");
05301 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
05302 CHECK_THROWS_WITH(crit.value(), "cannot get value");
05303 }
05304 }
05305
05306 SECTION("array")
05307 {
05308 json j = {1, 2, 3};
05309 json j_const(j);
05310
05311 SECTION("json + begin/end")
05312 {
05313 json::iterator it_begin = j.begin();
05314 json::iterator it_end = j.end();
05315
05316 auto it = it_begin;
05317 CHECK(it != it_end);
05318 CHECK(*it == j[0]);
05319
05320 it++;
05321 CHECK(it != it_begin);
05322 CHECK(it != it_end);
05323 CHECK(*it == j[1]);
05324
05325 ++it;
05326 CHECK(it != it_begin);
05327 CHECK(it != it_end);
05328 CHECK(*it == j[2]);
05329
05330 ++it;
05331 CHECK(it != it_begin);
05332 CHECK(it == it_end);
05333 }
05334
05335 SECTION("const json + begin/end")
05336 {
05337 json::const_iterator it_begin = j_const.begin();
05338 json::const_iterator it_end = j_const.end();
05339
05340 auto it = it_begin;
05341 CHECK(it != it_end);
05342 CHECK(*it == j_const[0]);
05343
05344 it++;
05345 CHECK(it != it_begin);
05346 CHECK(it != it_end);
05347 CHECK(*it == j_const[1]);
05348
05349 ++it;
05350 CHECK(it != it_begin);
05351 CHECK(it != it_end);
05352 CHECK(*it == j_const[2]);
05353
05354 ++it;
05355 CHECK(it != it_begin);
05356 CHECK(it == it_end);
05357 }
05358
05359 SECTION("json + cbegin/cend")
05360 {
05361 json::const_iterator it_begin = j.cbegin();
05362 json::const_iterator it_end = j.cend();
05363
05364 auto it = it_begin;
05365 CHECK(it != it_end);
05366 CHECK(*it == j[0]);
05367
05368 it++;
05369 CHECK(it != it_begin);
05370 CHECK(it != it_end);
05371 CHECK(*it == j[1]);
05372
05373 ++it;
05374 CHECK(it != it_begin);
05375 CHECK(it != it_end);
05376 CHECK(*it == j[2]);
05377
05378 ++it;
05379 CHECK(it != it_begin);
05380 CHECK(it == it_end);
05381 }
05382
05383 SECTION("const json + cbegin/cend")
05384 {
05385 json::const_iterator it_begin = j_const.cbegin();
05386 json::const_iterator it_end = j_const.cend();
05387
05388 auto it = it_begin;
05389 CHECK(it != it_end);
05390 CHECK(*it == j[0]);
05391
05392 it++;
05393 CHECK(it != it_begin);
05394 CHECK(it != it_end);
05395 CHECK(*it == j[1]);
05396
05397 ++it;
05398 CHECK(it != it_begin);
05399 CHECK(it != it_end);
05400 CHECK(*it == j[2]);
05401
05402 ++it;
05403 CHECK(it != it_begin);
05404 CHECK(it == it_end);
05405 }
05406
05407 SECTION("json + rbegin/rend")
05408 {
05409 json::reverse_iterator it_begin = j.rbegin();
05410 json::reverse_iterator it_end = j.rend();
05411
05412 auto it = it_begin;
05413 CHECK(it != it_end);
05414 CHECK(*it == j[2]);
05415
05416 it++;
05417 CHECK(it != it_begin);
05418 CHECK(it != it_end);
05419 CHECK(*it == j[1]);
05420
05421 ++it;
05422 CHECK(it != it_begin);
05423 CHECK(it != it_end);
05424 CHECK(*it == j[0]);
05425
05426 ++it;
05427 CHECK(it != it_begin);
05428 CHECK(it == it_end);
05429 }
05430
05431 SECTION("json + crbegin/crend")
05432 {
05433 json::const_reverse_iterator it_begin = j.crbegin();
05434 json::const_reverse_iterator it_end = j.crend();
05435
05436 auto it = it_begin;
05437 CHECK(it != it_end);
05438 CHECK(*it == j[2]);
05439
05440 it++;
05441 CHECK(it != it_begin);
05442 CHECK(it != it_end);
05443 CHECK(*it == j[1]);
05444
05445 ++it;
05446 CHECK(it != it_begin);
05447 CHECK(it != it_end);
05448 CHECK(*it == j[0]);
05449
05450 ++it;
05451 CHECK(it != it_begin);
05452 CHECK(it == it_end);
05453 }
05454
05455 SECTION("const json + crbegin/crend")
05456 {
05457 json::const_reverse_iterator it_begin = j_const.crbegin();
05458 json::const_reverse_iterator it_end = j_const.crend();
05459
05460 auto it = it_begin;
05461 CHECK(it != it_end);
05462 CHECK(*it == j[2]);
05463
05464 it++;
05465 CHECK(it != it_begin);
05466 CHECK(it != it_end);
05467 CHECK(*it == j[1]);
05468
05469 ++it;
05470 CHECK(it != it_begin);
05471 CHECK(it != it_end);
05472 CHECK(*it == j[0]);
05473
05474 ++it;
05475 CHECK(it != it_begin);
05476 CHECK(it == it_end);
05477 }
05478
05479 SECTION("key/value")
05480 {
05481 auto it = j.begin();
05482 auto cit = j_const.cbegin();
05483 CHECK_THROWS_AS(it.key(), std::domain_error);
05484 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
05485 CHECK(it.value() == json(1));
05486 CHECK_THROWS_AS(cit.key(), std::domain_error);
05487 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
05488 CHECK(cit.value() == json(1));
05489 }
05490 }
05491
05492 SECTION("object")
05493 {
05494 json j = {{"A", 1}, {"B", 2}, {"C", 3}};
05495 json j_const(j);
05496
05497 SECTION("json + begin/end")
05498 {
05499 json::iterator it_begin = j.begin();
05500 json::iterator it_end = j.end();
05501
05502 auto it = it_begin;
05503 CHECK(it != it_end);
05504 CHECK(*it == j["A"]);
05505
05506 it++;
05507 CHECK(it != it_begin);
05508 CHECK(it != it_end);
05509 CHECK(*it == j["B"]);
05510
05511 ++it;
05512 CHECK(it != it_begin);
05513 CHECK(it != it_end);
05514 CHECK(*it == j["C"]);
05515
05516 ++it;
05517 CHECK(it != it_begin);
05518 CHECK(it == it_end);
05519 }
05520
05521 SECTION("const json + begin/end")
05522 {
05523 json::const_iterator it_begin = j_const.begin();
05524 json::const_iterator it_end = j_const.end();
05525
05526 auto it = it_begin;
05527 CHECK(it != it_end);
05528 CHECK(*it == j_const["A"]);
05529
05530 it++;
05531 CHECK(it != it_begin);
05532 CHECK(it != it_end);
05533 CHECK(*it == j_const["B"]);
05534
05535 ++it;
05536 CHECK(it != it_begin);
05537 CHECK(it != it_end);
05538 CHECK(*it == j_const["C"]);
05539
05540 ++it;
05541 CHECK(it != it_begin);
05542 CHECK(it == it_end);
05543 }
05544
05545 SECTION("json + cbegin/cend")
05546 {
05547 json::const_iterator it_begin = j.cbegin();
05548 json::const_iterator it_end = j.cend();
05549
05550 auto it = it_begin;
05551 CHECK(it != it_end);
05552 CHECK(*it == j["A"]);
05553
05554 it++;
05555 CHECK(it != it_begin);
05556 CHECK(it != it_end);
05557 CHECK(*it == j["B"]);
05558
05559 ++it;
05560 CHECK(it != it_begin);
05561 CHECK(it != it_end);
05562 CHECK(*it == j["C"]);
05563
05564 ++it;
05565 CHECK(it != it_begin);
05566 CHECK(it == it_end);
05567 }
05568
05569 SECTION("const json + cbegin/cend")
05570 {
05571 json::const_iterator it_begin = j_const.cbegin();
05572 json::const_iterator it_end = j_const.cend();
05573
05574 auto it = it_begin;
05575 CHECK(it != it_end);
05576 CHECK(*it == j_const["A"]);
05577
05578 it++;
05579 CHECK(it != it_begin);
05580 CHECK(it != it_end);
05581 CHECK(*it == j_const["B"]);
05582
05583 ++it;
05584 CHECK(it != it_begin);
05585 CHECK(it != it_end);
05586 CHECK(*it == j_const["C"]);
05587
05588 ++it;
05589 CHECK(it != it_begin);
05590 CHECK(it == it_end);
05591 }
05592
05593 SECTION("json + rbegin/rend")
05594 {
05595 json::reverse_iterator it_begin = j.rbegin();
05596 json::reverse_iterator it_end = j.rend();
05597
05598 auto it = it_begin;
05599 CHECK(it != it_end);
05600 CHECK(*it == j["C"]);
05601
05602 it++;
05603 CHECK(it != it_begin);
05604 CHECK(it != it_end);
05605 CHECK(*it == j["B"]);
05606
05607 ++it;
05608 CHECK(it != it_begin);
05609 CHECK(it != it_end);
05610 CHECK(*it == j["A"]);
05611
05612 ++it;
05613 CHECK(it != it_begin);
05614 CHECK(it == it_end);
05615 }
05616
05617 SECTION("json + crbegin/crend")
05618 {
05619 json::const_reverse_iterator it_begin = j.crbegin();
05620 json::const_reverse_iterator it_end = j.crend();
05621
05622 auto it = it_begin;
05623 CHECK(it != it_end);
05624 CHECK(*it == j["C"]);
05625
05626 it++;
05627 CHECK(it != it_begin);
05628 CHECK(it != it_end);
05629 CHECK(*it == j["B"]);
05630
05631 ++it;
05632 CHECK(it != it_begin);
05633 CHECK(it != it_end);
05634 CHECK(*it == j["A"]);
05635
05636 ++it;
05637 CHECK(it != it_begin);
05638 CHECK(it == it_end);
05639 }
05640
05641 SECTION("const json + crbegin/crend")
05642 {
05643 json::const_reverse_iterator it_begin = j_const.crbegin();
05644 json::const_reverse_iterator it_end = j_const.crend();
05645
05646 auto it = it_begin;
05647 CHECK(it != it_end);
05648 CHECK(*it == j["C"]);
05649
05650 it++;
05651 CHECK(it != it_begin);
05652 CHECK(it != it_end);
05653 CHECK(*it == j["B"]);
05654
05655 ++it;
05656 CHECK(it != it_begin);
05657 CHECK(it != it_end);
05658 CHECK(*it == j["A"]);
05659
05660 ++it;
05661 CHECK(it != it_begin);
05662 CHECK(it == it_end);
05663 }
05664
05665 SECTION("key/value")
05666 {
05667 auto it = j.begin();
05668 auto cit = j_const.cbegin();
05669 CHECK(it.key() == "A");
05670 CHECK(it.value() == json(1));
05671 CHECK(cit.key() == "A");
05672 CHECK(cit.value() == json(1));
05673 }
05674 }
05675
05676 SECTION("number (integer)")
05677 {
05678 json j = 23;
05679 json j_const(j);
05680
05681 SECTION("json + begin/end")
05682 {
05683 json::iterator it = j.begin();
05684 CHECK(it != j.end());
05685 CHECK(*it == j);
05686
05687 it++;
05688 CHECK(it != j.begin());
05689 CHECK(it == j.end());
05690
05691 it--;
05692 CHECK(it == j.begin());
05693 CHECK(it != j.end());
05694 CHECK(*it == j);
05695
05696 ++it;
05697 CHECK(it != j.begin());
05698 CHECK(it == j.end());
05699
05700 --it;
05701 CHECK(it == j.begin());
05702 CHECK(it != j.end());
05703 CHECK(*it == j);
05704 }
05705
05706 SECTION("const json + begin/end")
05707 {
05708 json::const_iterator it = j_const.begin();
05709 CHECK(it != j_const.end());
05710 CHECK(*it == j_const);
05711
05712 it++;
05713 CHECK(it != j_const.begin());
05714 CHECK(it == j_const.end());
05715
05716 it--;
05717 CHECK(it == j_const.begin());
05718 CHECK(it != j_const.end());
05719 CHECK(*it == j_const);
05720
05721 ++it;
05722 CHECK(it != j_const.begin());
05723 CHECK(it == j_const.end());
05724
05725 --it;
05726 CHECK(it == j_const.begin());
05727 CHECK(it != j_const.end());
05728 CHECK(*it == j_const);
05729 }
05730
05731 SECTION("json + cbegin/cend")
05732 {
05733 json::const_iterator it = j.cbegin();
05734 CHECK(it != j.cend());
05735 CHECK(*it == j);
05736
05737 it++;
05738 CHECK(it != j.cbegin());
05739 CHECK(it == j.cend());
05740
05741 it--;
05742 CHECK(it == j.cbegin());
05743 CHECK(it != j.cend());
05744 CHECK(*it == j);
05745
05746 ++it;
05747 CHECK(it != j.cbegin());
05748 CHECK(it == j.cend());
05749
05750 --it;
05751 CHECK(it == j.cbegin());
05752 CHECK(it != j.cend());
05753 CHECK(*it == j);
05754 }
05755
05756 SECTION("const json + cbegin/cend")
05757 {
05758 json::const_iterator it = j_const.cbegin();
05759 CHECK(it != j_const.cend());
05760 CHECK(*it == j_const);
05761
05762 it++;
05763 CHECK(it != j_const.cbegin());
05764 CHECK(it == j_const.cend());
05765
05766 it--;
05767 CHECK(it == j_const.cbegin());
05768 CHECK(it != j_const.cend());
05769 CHECK(*it == j_const);
05770
05771 ++it;
05772 CHECK(it != j_const.cbegin());
05773 CHECK(it == j_const.cend());
05774
05775 --it;
05776 CHECK(it == j_const.cbegin());
05777 CHECK(it != j_const.cend());
05778 CHECK(*it == j_const);
05779 }
05780
05781 SECTION("json + rbegin/rend")
05782 {
05783 json::reverse_iterator it = j.rbegin();
05784 CHECK(it != j.rend());
05785 CHECK(*it == j);
05786
05787 it++;
05788 CHECK(it != j.rbegin());
05789 CHECK(it == j.rend());
05790
05791 it--;
05792 CHECK(it == j.rbegin());
05793 CHECK(it != j.rend());
05794 CHECK(*it == j);
05795
05796 ++it;
05797 CHECK(it != j.rbegin());
05798 CHECK(it == j.rend());
05799
05800 --it;
05801 CHECK(it == j.rbegin());
05802 CHECK(it != j.rend());
05803 CHECK(*it == j);
05804 }
05805
05806 SECTION("json + crbegin/crend")
05807 {
05808 json::const_reverse_iterator it = j.crbegin();
05809 CHECK(it != j.crend());
05810 CHECK(*it == j);
05811
05812 it++;
05813 CHECK(it != j.crbegin());
05814 CHECK(it == j.crend());
05815
05816 it--;
05817 CHECK(it == j.crbegin());
05818 CHECK(it != j.crend());
05819 CHECK(*it == j);
05820
05821 ++it;
05822 CHECK(it != j.crbegin());
05823 CHECK(it == j.crend());
05824
05825 --it;
05826 CHECK(it == j.crbegin());
05827 CHECK(it != j.crend());
05828 CHECK(*it == j);
05829 }
05830
05831 SECTION("const json + crbegin/crend")
05832 {
05833 json::const_reverse_iterator it = j_const.crbegin();
05834 CHECK(it != j_const.crend());
05835 CHECK(*it == j_const);
05836
05837 it++;
05838 CHECK(it != j_const.crbegin());
05839 CHECK(it == j_const.crend());
05840
05841 it--;
05842 CHECK(it == j_const.crbegin());
05843 CHECK(it != j_const.crend());
05844 CHECK(*it == j_const);
05845
05846 ++it;
05847 CHECK(it != j_const.crbegin());
05848 CHECK(it == j_const.crend());
05849
05850 --it;
05851 CHECK(it == j_const.crbegin());
05852 CHECK(it != j_const.crend());
05853 CHECK(*it == j_const);
05854 }
05855
05856 SECTION("key/value")
05857 {
05858 auto it = j.begin();
05859 auto cit = j_const.cbegin();
05860 CHECK_THROWS_AS(it.key(), std::domain_error);
05861 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
05862 CHECK(it.value() == json(23));
05863 CHECK_THROWS_AS(cit.key(), std::domain_error);
05864 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
05865 CHECK(cit.value() == json(23));
05866
05867 auto rit = j.rend();
05868 auto crit = j.crend();
05869 CHECK_THROWS_AS(rit.key(), std::domain_error);
05870 CHECK_THROWS_AS(rit.value(), std::out_of_range);
05871 CHECK_THROWS_AS(crit.key(), std::domain_error);
05872 CHECK_THROWS_AS(crit.value(), std::out_of_range);
05873 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
05874 CHECK_THROWS_WITH(rit.value(), "cannot get value");
05875 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
05876 CHECK_THROWS_WITH(crit.value(), "cannot get value");
05877 }
05878 }
05879
05880 SECTION("number (unsigned)")
05881 {
05882 json j = 23u;
05883 json j_const(j);
05884
05885 SECTION("json + begin/end")
05886 {
05887 json::iterator it = j.begin();
05888 CHECK(it != j.end());
05889 CHECK(*it == j);
05890
05891 it++;
05892 CHECK(it != j.begin());
05893 CHECK(it == j.end());
05894
05895 it--;
05896 CHECK(it == j.begin());
05897 CHECK(it != j.end());
05898 CHECK(*it == j);
05899
05900 ++it;
05901 CHECK(it != j.begin());
05902 CHECK(it == j.end());
05903
05904 --it;
05905 CHECK(it == j.begin());
05906 CHECK(it != j.end());
05907 CHECK(*it == j);
05908 }
05909
05910 SECTION("const json + begin/end")
05911 {
05912 json::const_iterator it = j_const.begin();
05913 CHECK(it != j_const.end());
05914 CHECK(*it == j_const);
05915
05916 it++;
05917 CHECK(it != j_const.begin());
05918 CHECK(it == j_const.end());
05919
05920 it--;
05921 CHECK(it == j_const.begin());
05922 CHECK(it != j_const.end());
05923 CHECK(*it == j_const);
05924
05925 ++it;
05926 CHECK(it != j_const.begin());
05927 CHECK(it == j_const.end());
05928
05929 --it;
05930 CHECK(it == j_const.begin());
05931 CHECK(it != j_const.end());
05932 CHECK(*it == j_const);
05933 }
05934
05935 SECTION("json + cbegin/cend")
05936 {
05937 json::const_iterator it = j.cbegin();
05938 CHECK(it != j.cend());
05939 CHECK(*it == j);
05940
05941 it++;
05942 CHECK(it != j.cbegin());
05943 CHECK(it == j.cend());
05944
05945 it--;
05946 CHECK(it == j.cbegin());
05947 CHECK(it != j.cend());
05948 CHECK(*it == j);
05949
05950 ++it;
05951 CHECK(it != j.cbegin());
05952 CHECK(it == j.cend());
05953
05954 --it;
05955 CHECK(it == j.cbegin());
05956 CHECK(it != j.cend());
05957 CHECK(*it == j);
05958 }
05959
05960 SECTION("const json + cbegin/cend")
05961 {
05962 json::const_iterator it = j_const.cbegin();
05963 CHECK(it != j_const.cend());
05964 CHECK(*it == j_const);
05965
05966 it++;
05967 CHECK(it != j_const.cbegin());
05968 CHECK(it == j_const.cend());
05969
05970 it--;
05971 CHECK(it == j_const.cbegin());
05972 CHECK(it != j_const.cend());
05973 CHECK(*it == j_const);
05974
05975 ++it;
05976 CHECK(it != j_const.cbegin());
05977 CHECK(it == j_const.cend());
05978
05979 --it;
05980 CHECK(it == j_const.cbegin());
05981 CHECK(it != j_const.cend());
05982 CHECK(*it == j_const);
05983 }
05984
05985 SECTION("json + rbegin/rend")
05986 {
05987 json::reverse_iterator it = j.rbegin();
05988 CHECK(it != j.rend());
05989 CHECK(*it == j);
05990
05991 it++;
05992 CHECK(it != j.rbegin());
05993 CHECK(it == j.rend());
05994
05995 it--;
05996 CHECK(it == j.rbegin());
05997 CHECK(it != j.rend());
05998 CHECK(*it == j);
05999
06000 ++it;
06001 CHECK(it != j.rbegin());
06002 CHECK(it == j.rend());
06003
06004 --it;
06005 CHECK(it == j.rbegin());
06006 CHECK(it != j.rend());
06007 CHECK(*it == j);
06008 }
06009
06010 SECTION("json + crbegin/crend")
06011 {
06012 json::const_reverse_iterator it = j.crbegin();
06013 CHECK(it != j.crend());
06014 CHECK(*it == j);
06015
06016 it++;
06017 CHECK(it != j.crbegin());
06018 CHECK(it == j.crend());
06019
06020 it--;
06021 CHECK(it == j.crbegin());
06022 CHECK(it != j.crend());
06023 CHECK(*it == j);
06024
06025 ++it;
06026 CHECK(it != j.crbegin());
06027 CHECK(it == j.crend());
06028
06029 --it;
06030 CHECK(it == j.crbegin());
06031 CHECK(it != j.crend());
06032 CHECK(*it == j);
06033 }
06034
06035 SECTION("const json + crbegin/crend")
06036 {
06037 json::const_reverse_iterator it = j_const.crbegin();
06038 CHECK(it != j_const.crend());
06039 CHECK(*it == j_const);
06040
06041 it++;
06042 CHECK(it != j_const.crbegin());
06043 CHECK(it == j_const.crend());
06044
06045 it--;
06046 CHECK(it == j_const.crbegin());
06047 CHECK(it != j_const.crend());
06048 CHECK(*it == j_const);
06049
06050 ++it;
06051 CHECK(it != j_const.crbegin());
06052 CHECK(it == j_const.crend());
06053
06054 --it;
06055 CHECK(it == j_const.crbegin());
06056 CHECK(it != j_const.crend());
06057 CHECK(*it == j_const);
06058 }
06059
06060 SECTION("key/value")
06061 {
06062 auto it = j.begin();
06063 auto cit = j_const.cbegin();
06064 CHECK_THROWS_AS(it.key(), std::domain_error);
06065 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
06066 CHECK(it.value() == json(23));
06067 CHECK_THROWS_AS(cit.key(), std::domain_error);
06068 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
06069 CHECK(cit.value() == json(23));
06070
06071 auto rit = j.rend();
06072 auto crit = j.crend();
06073 CHECK_THROWS_AS(rit.key(), std::domain_error);
06074 CHECK_THROWS_AS(rit.value(), std::out_of_range);
06075 CHECK_THROWS_AS(crit.key(), std::domain_error);
06076 CHECK_THROWS_AS(crit.value(), std::out_of_range);
06077 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
06078 CHECK_THROWS_WITH(rit.value(), "cannot get value");
06079 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
06080 CHECK_THROWS_WITH(crit.value(), "cannot get value");
06081 }
06082 }
06083
06084 SECTION("number (float)")
06085 {
06086 json j = 23.42;
06087 json j_const(j);
06088
06089 SECTION("json + begin/end")
06090 {
06091 json::iterator it = j.begin();
06092 CHECK(it != j.end());
06093 CHECK(*it == j);
06094
06095 it++;
06096 CHECK(it != j.begin());
06097 CHECK(it == j.end());
06098
06099 it--;
06100 CHECK(it == j.begin());
06101 CHECK(it != j.end());
06102 CHECK(*it == j);
06103
06104 ++it;
06105 CHECK(it != j.begin());
06106 CHECK(it == j.end());
06107
06108 --it;
06109 CHECK(it == j.begin());
06110 CHECK(it != j.end());
06111 CHECK(*it == j);
06112 }
06113
06114 SECTION("const json + begin/end")
06115 {
06116 json::const_iterator it = j_const.begin();
06117 CHECK(it != j_const.end());
06118 CHECK(*it == j_const);
06119
06120 it++;
06121 CHECK(it != j_const.begin());
06122 CHECK(it == j_const.end());
06123
06124 it--;
06125 CHECK(it == j_const.begin());
06126 CHECK(it != j_const.end());
06127 CHECK(*it == j_const);
06128
06129 ++it;
06130 CHECK(it != j_const.begin());
06131 CHECK(it == j_const.end());
06132
06133 --it;
06134 CHECK(it == j_const.begin());
06135 CHECK(it != j_const.end());
06136 CHECK(*it == j_const);
06137 }
06138
06139 SECTION("json + cbegin/cend")
06140 {
06141 json::const_iterator it = j.cbegin();
06142 CHECK(it != j.cend());
06143 CHECK(*it == j);
06144
06145 it++;
06146 CHECK(it != j.cbegin());
06147 CHECK(it == j.cend());
06148
06149 it--;
06150 CHECK(it == j.cbegin());
06151 CHECK(it != j.cend());
06152 CHECK(*it == j);
06153
06154 ++it;
06155 CHECK(it != j.cbegin());
06156 CHECK(it == j.cend());
06157
06158 --it;
06159 CHECK(it == j.cbegin());
06160 CHECK(it != j.cend());
06161 CHECK(*it == j);
06162 }
06163
06164 SECTION("const json + cbegin/cend")
06165 {
06166 json::const_iterator it = j_const.cbegin();
06167 CHECK(it != j_const.cend());
06168 CHECK(*it == j_const);
06169
06170 it++;
06171 CHECK(it != j_const.cbegin());
06172 CHECK(it == j_const.cend());
06173
06174 it--;
06175 CHECK(it == j_const.cbegin());
06176 CHECK(it != j_const.cend());
06177 CHECK(*it == j_const);
06178
06179 ++it;
06180 CHECK(it != j_const.cbegin());
06181 CHECK(it == j_const.cend());
06182
06183 --it;
06184 CHECK(it == j_const.cbegin());
06185 CHECK(it != j_const.cend());
06186 CHECK(*it == j_const);
06187 }
06188
06189 SECTION("json + rbegin/rend")
06190 {
06191 json::reverse_iterator it = j.rbegin();
06192 CHECK(it != j.rend());
06193 CHECK(*it == j);
06194
06195 it++;
06196 CHECK(it != j.rbegin());
06197 CHECK(it == j.rend());
06198
06199 it--;
06200 CHECK(it == j.rbegin());
06201 CHECK(it != j.rend());
06202 CHECK(*it == j);
06203
06204 ++it;
06205 CHECK(it != j.rbegin());
06206 CHECK(it == j.rend());
06207
06208 --it;
06209 CHECK(it == j.rbegin());
06210 CHECK(it != j.rend());
06211 CHECK(*it == j);
06212 }
06213
06214 SECTION("json + crbegin/crend")
06215 {
06216 json::const_reverse_iterator it = j.crbegin();
06217 CHECK(it != j.crend());
06218 CHECK(*it == j);
06219
06220 it++;
06221 CHECK(it != j.crbegin());
06222 CHECK(it == j.crend());
06223
06224 it--;
06225 CHECK(it == j.crbegin());
06226 CHECK(it != j.crend());
06227 CHECK(*it == j);
06228
06229 ++it;
06230 CHECK(it != j.crbegin());
06231 CHECK(it == j.crend());
06232
06233 --it;
06234 CHECK(it == j.crbegin());
06235 CHECK(it != j.crend());
06236 CHECK(*it == j);
06237 }
06238
06239 SECTION("const json + crbegin/crend")
06240 {
06241 json::const_reverse_iterator it = j_const.crbegin();
06242 CHECK(it != j_const.crend());
06243 CHECK(*it == j_const);
06244
06245 it++;
06246 CHECK(it != j_const.crbegin());
06247 CHECK(it == j_const.crend());
06248
06249 it--;
06250 CHECK(it == j_const.crbegin());
06251 CHECK(it != j_const.crend());
06252 CHECK(*it == j_const);
06253
06254 ++it;
06255 CHECK(it != j_const.crbegin());
06256 CHECK(it == j_const.crend());
06257
06258 --it;
06259 CHECK(it == j_const.crbegin());
06260 CHECK(it != j_const.crend());
06261 CHECK(*it == j_const);
06262 }
06263
06264 SECTION("key/value")
06265 {
06266 auto it = j.begin();
06267 auto cit = j_const.cbegin();
06268 CHECK_THROWS_AS(it.key(), std::domain_error);
06269 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
06270 CHECK(it.value() == json(23.42));
06271 CHECK_THROWS_AS(cit.key(), std::domain_error);
06272 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
06273 CHECK(cit.value() == json(23.42));
06274
06275 auto rit = j.rend();
06276 auto crit = j.crend();
06277 CHECK_THROWS_AS(rit.key(), std::domain_error);
06278 CHECK_THROWS_AS(rit.value(), std::out_of_range);
06279 CHECK_THROWS_AS(crit.key(), std::domain_error);
06280 CHECK_THROWS_AS(crit.value(), std::out_of_range);
06281 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
06282 CHECK_THROWS_WITH(rit.value(), "cannot get value");
06283 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
06284 CHECK_THROWS_WITH(crit.value(), "cannot get value");
06285 }
06286 }
06287
06288 SECTION("null")
06289 {
06290 json j = nullptr;
06291 json j_const(j);
06292
06293 SECTION("json + begin/end")
06294 {
06295 json::iterator it = j.begin();
06296 CHECK(it == j.end());
06297 }
06298
06299 SECTION("const json + begin/end")
06300 {
06301 json::const_iterator it_begin = j_const.begin();
06302 json::const_iterator it_end = j_const.end();
06303 CHECK(it_begin == it_end);
06304 }
06305
06306 SECTION("json + cbegin/cend")
06307 {
06308 json::const_iterator it_begin = j.cbegin();
06309 json::const_iterator it_end = j.cend();
06310 CHECK(it_begin == it_end);
06311 }
06312
06313 SECTION("const json + cbegin/cend")
06314 {
06315 json::const_iterator it_begin = j_const.cbegin();
06316 json::const_iterator it_end = j_const.cend();
06317 CHECK(it_begin == it_end);
06318 }
06319
06320 SECTION("json + rbegin/rend")
06321 {
06322 json::reverse_iterator it = j.rbegin();
06323 CHECK(it == j.rend());
06324 }
06325
06326 SECTION("json + crbegin/crend")
06327 {
06328 json::const_reverse_iterator it = j.crbegin();
06329 CHECK(it == j.crend());
06330 }
06331
06332 SECTION("const json + crbegin/crend")
06333 {
06334 json::const_reverse_iterator it = j_const.crbegin();
06335 CHECK(it == j_const.crend());
06336 }
06337
06338 SECTION("key/value")
06339 {
06340 auto it = j.begin();
06341 auto cit = j_const.cbegin();
06342 CHECK_THROWS_AS(it.key(), std::domain_error);
06343 CHECK_THROWS_AS(it.value(), std::out_of_range);
06344 CHECK_THROWS_AS(cit.key(), std::domain_error);
06345 CHECK_THROWS_AS(cit.value(), std::out_of_range);
06346 CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
06347 CHECK_THROWS_WITH(it.value(), "cannot get value");
06348 CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
06349 CHECK_THROWS_WITH(cit.value(), "cannot get value");
06350
06351 auto rit = j.rend();
06352 auto crit = j.crend();
06353 CHECK_THROWS_AS(rit.key(), std::domain_error);
06354 CHECK_THROWS_AS(rit.value(), std::out_of_range);
06355 CHECK_THROWS_AS(crit.key(), std::domain_error);
06356 CHECK_THROWS_AS(crit.value(), std::out_of_range);
06357 CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
06358 CHECK_THROWS_WITH(rit.value(), "cannot get value");
06359 CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
06360 CHECK_THROWS_WITH(crit.value(), "cannot get value");
06361 }
06362 }
06363 }
06364
06365 SECTION("iterator comparisons")
06366 {
06367 json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
06368
06369 for (json& j : j_values)
06370 {
06371 auto it1 = j.begin();
06372 auto it2 = j.begin();
06373 auto it3 = j.begin();
06374 ++it2;
06375 ++it3;
06376 ++it3;
06377 auto it1_c = j.cbegin();
06378 auto it2_c = j.cbegin();
06379 auto it3_c = j.cbegin();
06380 ++it2_c;
06381 ++it3_c;
06382 ++it3_c;
06383
06384
06385 {
06386 CHECK(it1 == it1);
06387 CHECK(not (it1 == it2));
06388 CHECK(not (it1 == it3));
06389 CHECK(not (it2 == it3));
06390 CHECK(it1_c == it1_c);
06391 CHECK(not (it1_c == it2_c));
06392 CHECK(not (it1_c == it3_c));
06393 CHECK(not (it2_c == it3_c));
06394 }
06395
06396
06397 {
06398
06399 CHECK( (it1 != it1) == not(it1 == it1) );
06400 CHECK( (it1 != it2) == not(it1 == it2) );
06401 CHECK( (it1 != it3) == not(it1 == it3) );
06402 CHECK( (it2 != it3) == not(it2 == it3) );
06403 CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
06404 CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
06405 CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
06406 CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
06407 }
06408
06409
06410 {
06411 if (j.type() == json::value_t::object)
06412 {
06413 CHECK_THROWS_AS(it1 < it1, std::domain_error);
06414 CHECK_THROWS_AS(it1 < it2, std::domain_error);
06415 CHECK_THROWS_AS(it2 < it3, std::domain_error);
06416 CHECK_THROWS_AS(it1 < it3, std::domain_error);
06417 CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
06418 CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
06419 CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
06420 CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
06421 CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
06422 CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
06423 CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
06424 CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
06425 CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
06426 CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
06427 CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
06428 CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
06429 }
06430 else
06431 {
06432 CHECK(not (it1 < it1));
06433 CHECK(it1 < it2);
06434 CHECK(it1 < it3);
06435 CHECK(it2 < it3);
06436 CHECK(not (it1_c < it1_c));
06437 CHECK(it1_c < it2_c);
06438 CHECK(it1_c < it3_c);
06439 CHECK(it2_c < it3_c);
06440 }
06441 }
06442
06443
06444 {
06445 if (j.type() == json::value_t::object)
06446 {
06447 CHECK_THROWS_AS(it1 <= it1, std::domain_error);
06448 CHECK_THROWS_AS(it1 <= it2, std::domain_error);
06449 CHECK_THROWS_AS(it2 <= it3, std::domain_error);
06450 CHECK_THROWS_AS(it1 <= it3, std::domain_error);
06451 CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
06452 CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
06453 CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
06454 CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
06455 CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
06456 CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
06457 CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
06458 CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
06459 CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
06460 CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
06461 CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
06462 CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
06463 }
06464 else
06465 {
06466
06467 CHECK( (it1 <= it1) == not(it1 < it1) );
06468 CHECK( (it1 <= it2) == not(it2 < it1) );
06469 CHECK( (it1 <= it3) == not(it3 < it1) );
06470 CHECK( (it2 <= it3) == not(it3 < it2) );
06471 CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
06472 CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
06473 CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
06474 CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
06475 }
06476 }
06477
06478
06479 {
06480 if (j.type() == json::value_t::object)
06481 {
06482 CHECK_THROWS_AS(it1 > it1, std::domain_error);
06483 CHECK_THROWS_AS(it1 > it2, std::domain_error);
06484 CHECK_THROWS_AS(it2 > it3, std::domain_error);
06485 CHECK_THROWS_AS(it1 > it3, std::domain_error);
06486 CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
06487 CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
06488 CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
06489 CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
06490 CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
06491 CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
06492 CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
06493 CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
06494 CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
06495 CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
06496 CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
06497 CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
06498 }
06499 else
06500 {
06501
06502 CHECK( (it1 > it1) == (it1 < it1) );
06503 CHECK( (it1 > it2) == (it2 < it1) );
06504 CHECK( (it1 > it3) == (it3 < it1) );
06505 CHECK( (it2 > it3) == (it3 < it2) );
06506 CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
06507 CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
06508 CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
06509 CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
06510 }
06511 }
06512
06513
06514 {
06515 if (j.type() == json::value_t::object)
06516 {
06517 CHECK_THROWS_AS(it1 >= it1, std::domain_error);
06518 CHECK_THROWS_AS(it1 >= it2, std::domain_error);
06519 CHECK_THROWS_AS(it2 >= it3, std::domain_error);
06520 CHECK_THROWS_AS(it1 >= it3, std::domain_error);
06521 CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
06522 CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
06523 CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
06524 CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
06525 CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
06526 CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
06527 CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
06528 CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
06529 CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
06530 CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
06531 CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
06532 CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
06533 }
06534 else
06535 {
06536
06537 CHECK( (it1 >= it1) == not(it1 < it1) );
06538 CHECK( (it1 >= it2) == not(it1 < it2) );
06539 CHECK( (it1 >= it3) == not(it1 < it3) );
06540 CHECK( (it2 >= it3) == not(it2 < it3) );
06541 CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
06542 CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
06543 CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
06544 CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
06545 }
06546 }
06547 }
06548
06549
06550 for (auto j : j_values)
06551 {
06552 for (auto k : j_values)
06553 {
06554 if (j != k)
06555 {
06556 CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error);
06557 CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error);
06558 CHECK_THROWS_WITH(j.begin() == k.begin(), "cannot compare iterators of different containers");
06559 CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "cannot compare iterators of different containers");
06560
06561 CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error);
06562 CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error);
06563 CHECK_THROWS_WITH(j.begin() < k.begin(), "cannot compare iterators of different containers");
06564 CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "cannot compare iterators of different containers");
06565 }
06566 }
06567 }
06568 }
06569
06570 SECTION("iterator arithmetic")
06571 {
06572 json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
06573 json j_array = {1, 2, 3, 4, 5, 6};
06574 json j_null = nullptr;
06575 json j_value = 42;
06576
06577 SECTION("addition and subtraction")
06578 {
06579 SECTION("object")
06580 {
06581 {
06582 auto it = j_object.begin();
06583 CHECK_THROWS_AS(it += 1, std::domain_error);
06584 CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
06585 }
06586 {
06587 auto it = j_object.cbegin();
06588 CHECK_THROWS_AS(it += 1, std::domain_error);
06589 CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
06590 }
06591 {
06592 auto it = j_object.begin();
06593 CHECK_THROWS_AS(it + 1, std::domain_error);
06594 CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
06595 }
06596 {
06597 auto it = j_object.cbegin();
06598 CHECK_THROWS_AS(it + 1, std::domain_error);
06599 CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
06600 }
06601 {
06602 auto it = j_object.begin();
06603 CHECK_THROWS_AS(it -= 1, std::domain_error);
06604 CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
06605 }
06606 {
06607 auto it = j_object.cbegin();
06608 CHECK_THROWS_AS(it -= 1, std::domain_error);
06609 CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
06610 }
06611 {
06612 auto it = j_object.begin();
06613 CHECK_THROWS_AS(it - 1, std::domain_error);
06614 CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
06615 }
06616 {
06617 auto it = j_object.cbegin();
06618 CHECK_THROWS_AS(it - 1, std::domain_error);
06619 CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
06620 }
06621 {
06622 auto it = j_object.begin();
06623 CHECK_THROWS_AS(it - it, std::domain_error);
06624 CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
06625 }
06626 {
06627 auto it = j_object.cbegin();
06628 CHECK_THROWS_AS(it - it, std::domain_error);
06629 CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
06630 }
06631 }
06632
06633 SECTION("array")
06634 {
06635 {
06636 auto it = j_array.begin();
06637 it += 3;
06638 CHECK((j_array.begin() + 3) == it);
06639 CHECK((it - 3) == j_array.begin());
06640 CHECK((it - j_array.begin()) == 3);
06641 CHECK(*it == json(4));
06642 it -= 2;
06643 CHECK(*it == json(2));
06644 }
06645 {
06646 auto it = j_array.cbegin();
06647 it += 3;
06648 CHECK((j_array.cbegin() + 3) == it);
06649 CHECK((it - 3) == j_array.cbegin());
06650 CHECK((it - j_array.cbegin()) == 3);
06651 CHECK(*it == json(4));
06652 it -= 2;
06653 CHECK(*it == json(2));
06654 }
06655 }
06656
06657 SECTION("null")
06658 {
06659 {
06660 auto it = j_null.begin();
06661 it += 3;
06662 CHECK((j_null.begin() + 3) == it);
06663 CHECK((it - 3) == j_null.begin());
06664 CHECK((it - j_null.begin()) == 3);
06665 CHECK(it != j_null.end());
06666 it -= 3;
06667 CHECK(it == j_null.end());
06668 }
06669 {
06670 auto it = j_null.cbegin();
06671 it += 3;
06672 CHECK((j_null.cbegin() + 3) == it);
06673 CHECK((it - 3) == j_null.cbegin());
06674 CHECK((it - j_null.cbegin()) == 3);
06675 CHECK(it != j_null.cend());
06676 it -= 3;
06677 CHECK(it == j_null.cend());
06678 }
06679 }
06680
06681 SECTION("value")
06682 {
06683 {
06684 auto it = j_value.begin();
06685 it += 3;
06686 CHECK((j_value.begin() + 3) == it);
06687 CHECK((it - 3) == j_value.begin());
06688 CHECK((it - j_value.begin()) == 3);
06689 CHECK(it != j_value.end());
06690 it -= 3;
06691 CHECK(*it == json(42));
06692 }
06693 {
06694 auto it = j_value.cbegin();
06695 it += 3;
06696 CHECK((j_value.cbegin() + 3) == it);
06697 CHECK((it - 3) == j_value.cbegin());
06698 CHECK((it - j_value.cbegin()) == 3);
06699 CHECK(it != j_value.cend());
06700 it -= 3;
06701 CHECK(*it == json(42));
06702 }
06703 }
06704 }
06705
06706 SECTION("subscript operator")
06707 {
06708 SECTION("object")
06709 {
06710 {
06711 auto it = j_object.begin();
06712 CHECK_THROWS_AS(it[0], std::domain_error);
06713 CHECK_THROWS_AS(it[1], std::domain_error);
06714 CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
06715 CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
06716 }
06717 {
06718 auto it = j_object.cbegin();
06719 CHECK_THROWS_AS(it[0], std::domain_error);
06720 CHECK_THROWS_AS(it[1], std::domain_error);
06721 CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
06722 CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
06723 }
06724 }
06725
06726 SECTION("array")
06727 {
06728 {
06729 auto it = j_array.begin();
06730 CHECK(it[0] == json(1));
06731 CHECK(it[1] == json(2));
06732 CHECK(it[2] == json(3));
06733 CHECK(it[3] == json(4));
06734 CHECK(it[4] == json(5));
06735 CHECK(it[5] == json(6));
06736 }
06737 {
06738 auto it = j_array.cbegin();
06739 CHECK(it[0] == json(1));
06740 CHECK(it[1] == json(2));
06741 CHECK(it[2] == json(3));
06742 CHECK(it[3] == json(4));
06743 CHECK(it[4] == json(5));
06744 CHECK(it[5] == json(6));
06745 }
06746 }
06747
06748 SECTION("null")
06749 {
06750 {
06751 auto it = j_null.begin();
06752 CHECK_THROWS_AS(it[0], std::out_of_range);
06753 CHECK_THROWS_AS(it[1], std::out_of_range);
06754 CHECK_THROWS_WITH(it[0], "cannot get value");
06755 CHECK_THROWS_WITH(it[1], "cannot get value");
06756 }
06757 {
06758 auto it = j_null.cbegin();
06759 CHECK_THROWS_AS(it[0], std::out_of_range);
06760 CHECK_THROWS_AS(it[1], std::out_of_range);
06761 CHECK_THROWS_WITH(it[0], "cannot get value");
06762 CHECK_THROWS_WITH(it[1], "cannot get value");
06763 }
06764 }
06765
06766 SECTION("value")
06767 {
06768 {
06769 auto it = j_value.begin();
06770 CHECK(it[0] == json(42));
06771 CHECK_THROWS_AS(it[1], std::out_of_range);
06772 CHECK_THROWS_WITH(it[1], "cannot get value");
06773 }
06774 {
06775 auto it = j_value.cbegin();
06776 CHECK(it[0] == json(42));
06777 CHECK_THROWS_AS(it[1], std::out_of_range);
06778 CHECK_THROWS_WITH(it[1], "cannot get value");
06779 }
06780 }
06781 }
06782 }
06783
06784 SECTION("reverse iterator comparisons")
06785 {
06786 json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
06787
06788 for (json& j : j_values)
06789 {
06790 auto it1 = j.rbegin();
06791 auto it2 = j.rbegin();
06792 auto it3 = j.rbegin();
06793 ++it2;
06794 ++it3;
06795 ++it3;
06796 auto it1_c = j.crbegin();
06797 auto it2_c = j.crbegin();
06798 auto it3_c = j.crbegin();
06799 ++it2_c;
06800 ++it3_c;
06801 ++it3_c;
06802
06803
06804 {
06805 CHECK(it1 == it1);
06806 CHECK(not (it1 == it2));
06807 CHECK(not (it1 == it3));
06808 CHECK(not (it2 == it3));
06809 CHECK(it1_c == it1_c);
06810 CHECK(not (it1_c == it2_c));
06811 CHECK(not (it1_c == it3_c));
06812 CHECK(not (it2_c == it3_c));
06813 }
06814
06815
06816 {
06817
06818 CHECK( (it1 != it1) == not(it1 == it1) );
06819 CHECK( (it1 != it2) == not(it1 == it2) );
06820 CHECK( (it1 != it3) == not(it1 == it3) );
06821 CHECK( (it2 != it3) == not(it2 == it3) );
06822 CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
06823 CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
06824 CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
06825 CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
06826 }
06827
06828
06829 {
06830 if (j.type() == json::value_t::object)
06831 {
06832 CHECK_THROWS_AS(it1 < it1, std::domain_error);
06833 CHECK_THROWS_AS(it1 < it2, std::domain_error);
06834 CHECK_THROWS_AS(it2 < it3, std::domain_error);
06835 CHECK_THROWS_AS(it1 < it3, std::domain_error);
06836 CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
06837 CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
06838 CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
06839 CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
06840 CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
06841 CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
06842 CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
06843 CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
06844 CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
06845 CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
06846 CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
06847 CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
06848 }
06849 else
06850 {
06851 CHECK(not (it1 < it1));
06852 CHECK(it1 < it2);
06853 CHECK(it1 < it3);
06854 CHECK(it2 < it3);
06855 CHECK(not (it1_c < it1_c));
06856 CHECK(it1_c < it2_c);
06857 CHECK(it1_c < it3_c);
06858 CHECK(it2_c < it3_c);
06859 }
06860 }
06861
06862
06863 {
06864 if (j.type() == json::value_t::object)
06865 {
06866 CHECK_THROWS_AS(it1 <= it1, std::domain_error);
06867 CHECK_THROWS_AS(it1 <= it2, std::domain_error);
06868 CHECK_THROWS_AS(it2 <= it3, std::domain_error);
06869 CHECK_THROWS_AS(it1 <= it3, std::domain_error);
06870 CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
06871 CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
06872 CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
06873 CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
06874 CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
06875 CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
06876 CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
06877 CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
06878 CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
06879 CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
06880 CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
06881 CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
06882 }
06883 else
06884 {
06885
06886 CHECK( (it1 <= it1) == not(it1 < it1) );
06887 CHECK( (it1 <= it2) == not(it2 < it1) );
06888 CHECK( (it1 <= it3) == not(it3 < it1) );
06889 CHECK( (it2 <= it3) == not(it3 < it2) );
06890 CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
06891 CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
06892 CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
06893 CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
06894 }
06895 }
06896
06897
06898 {
06899 if (j.type() == json::value_t::object)
06900 {
06901 CHECK_THROWS_AS(it1 > it1, std::domain_error);
06902 CHECK_THROWS_AS(it1 > it2, std::domain_error);
06903 CHECK_THROWS_AS(it2 > it3, std::domain_error);
06904 CHECK_THROWS_AS(it1 > it3, std::domain_error);
06905 CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
06906 CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
06907 CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
06908 CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
06909 CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
06910 CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
06911 CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
06912 CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
06913 CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
06914 CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
06915 CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
06916 CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
06917 }
06918 else
06919 {
06920
06921 CHECK( (it1 > it1) == (it1 < it1) );
06922 CHECK( (it1 > it2) == (it2 < it1) );
06923 CHECK( (it1 > it3) == (it3 < it1) );
06924 CHECK( (it2 > it3) == (it3 < it2) );
06925 CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
06926 CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
06927 CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
06928 CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
06929 }
06930 }
06931
06932
06933 {
06934 if (j.type() == json::value_t::object)
06935 {
06936 CHECK_THROWS_AS(it1 >= it1, std::domain_error);
06937 CHECK_THROWS_AS(it1 >= it2, std::domain_error);
06938 CHECK_THROWS_AS(it2 >= it3, std::domain_error);
06939 CHECK_THROWS_AS(it1 >= it3, std::domain_error);
06940 CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
06941 CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
06942 CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
06943 CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
06944 CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
06945 CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
06946 CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
06947 CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
06948 CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
06949 CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
06950 CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
06951 CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
06952 }
06953 else
06954 {
06955
06956 CHECK( (it1 >= it1) == not(it1 < it1) );
06957 CHECK( (it1 >= it2) == not(it1 < it2) );
06958 CHECK( (it1 >= it3) == not(it1 < it3) );
06959 CHECK( (it2 >= it3) == not(it2 < it3) );
06960 CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
06961 CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
06962 CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
06963 CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
06964 }
06965 }
06966 }
06967
06968
06969 for (auto j : j_values)
06970 {
06971 for (auto k : j_values)
06972 {
06973 if (j != k)
06974 {
06975 CHECK_THROWS_AS(j.rbegin() == k.rbegin(), std::domain_error);
06976 CHECK_THROWS_AS(j.crbegin() == k.crbegin(), std::domain_error);
06977 CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "cannot compare iterators of different containers");
06978 CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "cannot compare iterators of different containers");
06979
06980 CHECK_THROWS_AS(j.rbegin() < k.rbegin(), std::domain_error);
06981 CHECK_THROWS_AS(j.crbegin() < k.crbegin(), std::domain_error);
06982 CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "cannot compare iterators of different containers");
06983 CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "cannot compare iterators of different containers");
06984 }
06985 }
06986 }
06987 }
06988
06989 SECTION("reverse iterator arithmetic")
06990 {
06991 json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
06992 json j_array = {1, 2, 3, 4, 5, 6};
06993 json j_null = nullptr;
06994 json j_value = 42;
06995
06996 SECTION("addition and subtraction")
06997 {
06998 SECTION("object")
06999 {
07000 {
07001 auto it = j_object.rbegin();
07002 CHECK_THROWS_AS(it += 1, std::domain_error);
07003 CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
07004 }
07005 {
07006 auto it = j_object.crbegin();
07007 CHECK_THROWS_AS(it += 1, std::domain_error);
07008 CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
07009 }
07010 {
07011 auto it = j_object.rbegin();
07012 CHECK_THROWS_AS(it + 1, std::domain_error);
07013 CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
07014 }
07015 {
07016 auto it = j_object.crbegin();
07017 CHECK_THROWS_AS(it + 1, std::domain_error);
07018 CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
07019 }
07020 {
07021 auto it = j_object.rbegin();
07022 CHECK_THROWS_AS(it -= 1, std::domain_error);
07023 CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
07024 }
07025 {
07026 auto it = j_object.crbegin();
07027 CHECK_THROWS_AS(it -= 1, std::domain_error);
07028 CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
07029 }
07030 {
07031 auto it = j_object.rbegin();
07032 CHECK_THROWS_AS(it - 1, std::domain_error);
07033 CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
07034 }
07035 {
07036 auto it = j_object.crbegin();
07037 CHECK_THROWS_AS(it - 1, std::domain_error);
07038 CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
07039 }
07040 {
07041 auto it = j_object.rbegin();
07042 CHECK_THROWS_AS(it - it, std::domain_error);
07043 CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
07044 }
07045 {
07046 auto it = j_object.crbegin();
07047 CHECK_THROWS_AS(it - it, std::domain_error);
07048 CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
07049 }
07050 }
07051
07052 SECTION("array")
07053 {
07054 {
07055 auto it = j_array.rbegin();
07056 it += 3;
07057 CHECK((j_array.rbegin() + 3) == it);
07058 CHECK((it - 3) == j_array.rbegin());
07059 CHECK((j_array.rbegin() - it) == 3);
07060 CHECK(*it == json(3));
07061 it -= 2;
07062 CHECK(*it == json(5));
07063 }
07064 {
07065 auto it = j_array.crbegin();
07066 it += 3;
07067 CHECK((j_array.crbegin() + 3) == it);
07068 CHECK((it - 3) == j_array.crbegin());
07069 CHECK((j_array.crbegin() - it) == 3);
07070 CHECK(*it == json(3));
07071 it -= 2;
07072 CHECK(*it == json(5));
07073 }
07074 }
07075
07076 SECTION("null")
07077 {
07078 {
07079 auto it = j_null.rbegin();
07080 it += 3;
07081 CHECK((j_null.rbegin() + 3) == it);
07082 CHECK((it - 3) == j_null.rbegin());
07083 CHECK((j_null.rbegin() - it) == 3);
07084 CHECK(it != j_null.rend());
07085 it -= 3;
07086 CHECK(it == j_null.rend());
07087 }
07088 {
07089 auto it = j_null.crbegin();
07090 it += 3;
07091 CHECK((j_null.crbegin() + 3) == it);
07092 CHECK((it - 3) == j_null.crbegin());
07093 CHECK((j_null.crbegin() - it) == 3);
07094 CHECK(it != j_null.crend());
07095 it -= 3;
07096 CHECK(it == j_null.crend());
07097 }
07098 }
07099
07100 SECTION("value")
07101 {
07102 {
07103 auto it = j_value.rbegin();
07104 it += 3;
07105 CHECK((j_value.rbegin() + 3) == it);
07106 CHECK((it - 3) == j_value.rbegin());
07107 CHECK((j_value.rbegin() - it) == 3);
07108 CHECK(it != j_value.rend());
07109 it -= 3;
07110 CHECK(*it == json(42));
07111 }
07112 {
07113 auto it = j_value.crbegin();
07114 it += 3;
07115 CHECK((j_value.crbegin() + 3) == it);
07116 CHECK((it - 3) == j_value.crbegin());
07117 CHECK((j_value.crbegin() - it) == 3);
07118 CHECK(it != j_value.crend());
07119 it -= 3;
07120 CHECK(*it == json(42));
07121 }
07122 }
07123 }
07124
07125 SECTION("subscript operator")
07126 {
07127 SECTION("object")
07128 {
07129 {
07130 auto it = j_object.rbegin();
07131 CHECK_THROWS_AS(it[0], std::domain_error);
07132 CHECK_THROWS_AS(it[1], std::domain_error);
07133 CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
07134 CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
07135 }
07136 {
07137 auto it = j_object.crbegin();
07138 CHECK_THROWS_AS(it[0], std::domain_error);
07139 CHECK_THROWS_AS(it[1], std::domain_error);
07140 CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
07141 CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
07142 }
07143 }
07144
07145 SECTION("array")
07146 {
07147 {
07148 auto it = j_array.rbegin();
07149 CHECK(it[0] == json(6));
07150 CHECK(it[1] == json(5));
07151 CHECK(it[2] == json(4));
07152 CHECK(it[3] == json(3));
07153 CHECK(it[4] == json(2));
07154 CHECK(it[5] == json(1));
07155 }
07156 {
07157 auto it = j_array.crbegin();
07158 CHECK(it[0] == json(6));
07159 CHECK(it[1] == json(5));
07160 CHECK(it[2] == json(4));
07161 CHECK(it[3] == json(3));
07162 CHECK(it[4] == json(2));
07163 CHECK(it[5] == json(1));
07164 }
07165 }
07166
07167 SECTION("null")
07168 {
07169 {
07170 auto it = j_null.rbegin();
07171 CHECK_THROWS_AS(it[0], std::out_of_range);
07172 CHECK_THROWS_AS(it[1], std::out_of_range);
07173 CHECK_THROWS_WITH(it[0], "cannot get value");
07174 CHECK_THROWS_WITH(it[1], "cannot get value");
07175 }
07176 {
07177 auto it = j_null.crbegin();
07178 CHECK_THROWS_AS(it[0], std::out_of_range);
07179 CHECK_THROWS_AS(it[1], std::out_of_range);
07180 CHECK_THROWS_WITH(it[0], "cannot get value");
07181 CHECK_THROWS_WITH(it[1], "cannot get value");
07182 }
07183 }
07184
07185 SECTION("value")
07186 {
07187 {
07188 auto it = j_value.rbegin();
07189 CHECK(it[0] == json(42));
07190 CHECK_THROWS_AS(it[1], std::out_of_range);
07191 CHECK_THROWS_WITH(it[1], "cannot get value");
07192 }
07193 {
07194 auto it = j_value.crbegin();
07195 CHECK(it[0] == json(42));
07196 CHECK_THROWS_AS(it[1], std::out_of_range);
07197 CHECK_THROWS_WITH(it[1], "cannot get value");
07198 }
07199 }
07200 }
07201 }
07202 }
07203
07204 TEST_CASE("capacity")
07205 {
07206 SECTION("empty()")
07207 {
07208 SECTION("boolean")
07209 {
07210 json j = true;
07211 json j_const(j);
07212
07213 SECTION("result of empty")
07214 {
07215 CHECK(j.empty() == false);
07216 CHECK(j_const.empty() == false);
07217 }
07218
07219 SECTION("definition of empty")
07220 {
07221 CHECK(j.begin() != j.end());
07222 CHECK(j_const.begin() != j_const.end());
07223 }
07224 }
07225
07226 SECTION("string")
07227 {
07228 json j = "hello world";
07229 json j_const(j);
07230
07231 SECTION("result of empty")
07232 {
07233 CHECK(j.empty() == false);
07234 CHECK(j_const.empty() == false);
07235 }
07236
07237 SECTION("definition of empty")
07238 {
07239 CHECK(j.begin() != j.end());
07240 CHECK(j_const.begin() != j_const.end());
07241 }
07242 }
07243
07244 SECTION("array")
07245 {
07246 SECTION("empty array")
07247 {
07248 json j = json::array();
07249 json j_const(j);
07250
07251 SECTION("result of empty")
07252 {
07253 CHECK(j.empty() == true);
07254 CHECK(j_const.empty() == true);
07255 }
07256
07257 SECTION("definition of empty")
07258 {
07259 CHECK(j.begin() == j.end());
07260 CHECK(j_const.begin() == j_const.end());
07261 }
07262 }
07263
07264 SECTION("filled array")
07265 {
07266 json j = {1, 2, 3};
07267 json j_const(j);
07268
07269 SECTION("result of empty")
07270 {
07271 CHECK(j.empty() == false);
07272 CHECK(j_const.empty() == false);
07273 }
07274
07275 SECTION("definition of empty")
07276 {
07277 CHECK(j.begin() != j.end());
07278 CHECK(j_const.begin() != j_const.end());
07279 }
07280 }
07281 }
07282
07283 SECTION("object")
07284 {
07285 SECTION("empty object")
07286 {
07287 json j = json::object();
07288 json j_const(j);
07289
07290 SECTION("result of empty")
07291 {
07292 CHECK(j.empty() == true);
07293 CHECK(j_const.empty() == true);
07294 }
07295
07296 SECTION("definition of empty")
07297 {
07298 CHECK(j.begin() == j.end());
07299 CHECK(j_const.begin() == j_const.end());
07300 }
07301 }
07302
07303 SECTION("filled object")
07304 {
07305 json j = {{"one", 1}, {"two", 2}, {"three", 3}};
07306 json j_const(j);
07307
07308 SECTION("result of empty")
07309 {
07310 CHECK(j.empty() == false);
07311 CHECK(j_const.empty() == false);
07312 }
07313
07314 SECTION("definition of empty")
07315 {
07316 CHECK(j.begin() != j.end());
07317 CHECK(j_const.begin() != j_const.end());
07318 }
07319 }
07320 }
07321
07322 SECTION("number (integer)")
07323 {
07324 json j = 23;
07325 json j_const(j);
07326
07327 SECTION("result of empty")
07328 {
07329 CHECK(j.empty() == false);
07330 CHECK(j_const.empty() == false);
07331 }
07332
07333 SECTION("definition of empty")
07334 {
07335 CHECK(j.begin() != j.end());
07336 CHECK(j_const.begin() != j_const.end());
07337 }
07338 }
07339
07340 SECTION("number (unsigned)")
07341 {
07342 json j = 23u;
07343 json j_const(j);
07344
07345 SECTION("result of empty")
07346 {
07347 CHECK(j.empty() == false);
07348 CHECK(j_const.empty() == false);
07349 }
07350
07351 SECTION("definition of empty")
07352 {
07353 CHECK(j.begin() != j.end());
07354 CHECK(j_const.begin() != j_const.end());
07355 }
07356 }
07357
07358 SECTION("number (float)")
07359 {
07360 json j = 23.42;
07361 json j_const(j);
07362
07363 SECTION("result of empty")
07364 {
07365 CHECK(j.empty() == false);
07366 CHECK(j_const.empty() == false);
07367 }
07368
07369 SECTION("definition of empty")
07370 {
07371 CHECK(j.begin() != j.end());
07372 CHECK(j_const.begin() != j_const.end());
07373 }
07374 }
07375
07376 SECTION("null")
07377 {
07378 json j = nullptr;
07379 json j_const(j);
07380
07381 SECTION("result of empty")
07382 {
07383 CHECK(j.empty() == true);
07384 CHECK(j_const.empty() == true);
07385 }
07386
07387 SECTION("definition of empty")
07388 {
07389 CHECK(j.begin() == j.end());
07390 CHECK(j_const.begin() == j_const.end());
07391 }
07392 }
07393 }
07394
07395 SECTION("size()")
07396 {
07397 SECTION("boolean")
07398 {
07399 json j = true;
07400 json j_const(j);
07401
07402 SECTION("result of size")
07403 {
07404 CHECK(j.size() == 1);
07405 CHECK(j_const.size() == 1);
07406 }
07407
07408 SECTION("definition of size")
07409 {
07410 CHECK(std::distance(j.begin(), j.end()) == j.size());
07411 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07412 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07413 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07414 }
07415 }
07416
07417 SECTION("string")
07418 {
07419 json j = "hello world";
07420 json j_const(j);
07421
07422 SECTION("result of size")
07423 {
07424 CHECK(j.size() == 1);
07425 CHECK(j_const.size() == 1);
07426 }
07427
07428 SECTION("definition of size")
07429 {
07430 CHECK(std::distance(j.begin(), j.end()) == j.size());
07431 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07432 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07433 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07434 }
07435 }
07436
07437 SECTION("array")
07438 {
07439 SECTION("empty array")
07440 {
07441 json j = json::array();
07442 json j_const(j);
07443
07444 SECTION("result of size")
07445 {
07446 CHECK(j.size() == 0);
07447 CHECK(j_const.size() == 0);
07448 }
07449
07450 SECTION("definition of size")
07451 {
07452 CHECK(std::distance(j.begin(), j.end()) == j.size());
07453 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07454 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07455 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07456 }
07457 }
07458
07459 SECTION("filled array")
07460 {
07461 json j = {1, 2, 3};
07462 json j_const(j);
07463
07464 SECTION("result of size")
07465 {
07466 CHECK(j.size() == 3);
07467 CHECK(j_const.size() == 3);
07468 }
07469
07470 SECTION("definition of size")
07471 {
07472 CHECK(std::distance(j.begin(), j.end()) == j.size());
07473 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07474 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07475 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07476 }
07477 }
07478 }
07479
07480 SECTION("object")
07481 {
07482 SECTION("empty object")
07483 {
07484 json j = json::object();
07485 json j_const(j);
07486
07487 SECTION("result of size")
07488 {
07489 CHECK(j.size() == 0);
07490 CHECK(j_const.size() == 0);
07491 }
07492
07493 SECTION("definition of size")
07494 {
07495 CHECK(std::distance(j.begin(), j.end()) == j.size());
07496 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07497 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07498 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07499 }
07500 }
07501
07502 SECTION("filled object")
07503 {
07504 json j = {{"one", 1}, {"two", 2}, {"three", 3}};
07505 json j_const(j);
07506
07507 SECTION("result of size")
07508 {
07509 CHECK(j.size() == 3);
07510 CHECK(j_const.size() == 3);
07511 }
07512
07513 SECTION("definition of size")
07514 {
07515 CHECK(std::distance(j.begin(), j.end()) == j.size());
07516 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07517 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07518 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07519 }
07520 }
07521 }
07522
07523 SECTION("number (integer)")
07524 {
07525 json j = 23;
07526 json j_const(j);
07527
07528 SECTION("result of size")
07529 {
07530 CHECK(j.size() == 1);
07531 CHECK(j_const.size() == 1);
07532 }
07533
07534 SECTION("definition of size")
07535 {
07536 CHECK(std::distance(j.begin(), j.end()) == j.size());
07537 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07538 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07539 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07540 }
07541 }
07542
07543 SECTION("number (unsigned)")
07544 {
07545 json j = 23u;
07546 json j_const(j);
07547
07548 SECTION("result of size")
07549 {
07550 CHECK(j.size() == 1);
07551 CHECK(j_const.size() == 1);
07552 }
07553
07554 SECTION("definition of size")
07555 {
07556 CHECK(std::distance(j.begin(), j.end()) == j.size());
07557 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07558 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07559 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07560 }
07561 }
07562
07563 SECTION("number (float)")
07564 {
07565 json j = 23.42;
07566 json j_const(j);
07567
07568 SECTION("result of size")
07569 {
07570 CHECK(j.size() == 1);
07571 CHECK(j_const.size() == 1);
07572 }
07573
07574 SECTION("definition of size")
07575 {
07576 CHECK(std::distance(j.begin(), j.end()) == j.size());
07577 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07578 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07579 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07580 }
07581 }
07582
07583 SECTION("null")
07584 {
07585 json j = nullptr;
07586 json j_const(j);
07587
07588 SECTION("result of size")
07589 {
07590 CHECK(j.size() == 0);
07591 CHECK(j_const.size() == 0);
07592 }
07593
07594 SECTION("definition of size")
07595 {
07596 CHECK(std::distance(j.begin(), j.end()) == j.size());
07597 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
07598 CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
07599 CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
07600 }
07601 }
07602 }
07603
07604 SECTION("max_size()")
07605 {
07606 SECTION("boolean")
07607 {
07608 json j = true;
07609 json j_const(j);
07610
07611 SECTION("result of max_size")
07612 {
07613 CHECK(j.max_size() == 1);
07614 CHECK(j_const.max_size() == 1);
07615 }
07616 }
07617
07618 SECTION("string")
07619 {
07620 json j = "hello world";
07621 json j_const(j);
07622
07623 SECTION("result of max_size")
07624 {
07625 CHECK(j.max_size() == 1);
07626 CHECK(j_const.max_size() == 1);
07627 }
07628 }
07629
07630 SECTION("array")
07631 {
07632 SECTION("empty array")
07633 {
07634 json j = json::array();
07635 json j_const(j);
07636
07637 SECTION("result of max_size")
07638 {
07639 CHECK(j.max_size() >= j.size());
07640 CHECK(j_const.max_size() >= j_const.size());
07641 }
07642 }
07643
07644 SECTION("filled array")
07645 {
07646 json j = {1, 2, 3};
07647 json j_const(j);
07648
07649 SECTION("result of max_size")
07650 {
07651 CHECK(j.max_size() >= j.size());
07652 CHECK(j_const.max_size() >= j_const.size());
07653 }
07654 }
07655 }
07656
07657 SECTION("object")
07658 {
07659 SECTION("empty object")
07660 {
07661 json j = json::object();
07662 json j_const(j);
07663
07664 SECTION("result of max_size")
07665 {
07666 CHECK(j.max_size() >= j.size());
07667 CHECK(j_const.max_size() >= j_const.size());
07668 }
07669 }
07670
07671 SECTION("filled object")
07672 {
07673 json j = {{"one", 1}, {"two", 2}, {"three", 3}};
07674 json j_const(j);
07675
07676 SECTION("result of max_size")
07677 {
07678 CHECK(j.max_size() >= j.size());
07679 CHECK(j_const.max_size() >= j_const.size());
07680 }
07681 }
07682 }
07683
07684 SECTION("number (integer)")
07685 {
07686 json j = 23;
07687 json j_const(j);
07688
07689 SECTION("result of max_size")
07690 {
07691 CHECK(j.max_size() == 1);
07692 CHECK(j_const.max_size() == 1);
07693 }
07694 }
07695
07696 SECTION("number (unsigned)")
07697 {
07698 json j = 23u;
07699 json j_const(j);
07700
07701 SECTION("result of max_size")
07702 {
07703 CHECK(j.max_size() == 1);
07704 CHECK(j_const.max_size() == 1);
07705 }
07706 }
07707
07708 SECTION("number (float)")
07709 {
07710 json j = 23.42;
07711 json j_const(j);
07712
07713 SECTION("result of max_size")
07714 {
07715 CHECK(j.max_size() == 1);
07716 CHECK(j_const.max_size() == 1);
07717 }
07718 }
07719
07720 SECTION("null")
07721 {
07722 json j = nullptr;
07723 json j_const(j);
07724
07725 SECTION("result of max_size")
07726 {
07727 CHECK(j.max_size() == 0);
07728 CHECK(j_const.max_size() == 0);
07729 }
07730 }
07731 }
07732 }
07733
07734 TEST_CASE("modifiers")
07735 {
07736 SECTION("clear()")
07737 {
07738 SECTION("boolean")
07739 {
07740 json j = true;
07741
07742 j.clear();
07743 CHECK(j == json(json::value_t::boolean));
07744 }
07745
07746 SECTION("string")
07747 {
07748 json j = "hello world";
07749
07750 j.clear();
07751 CHECK(j == json(json::value_t::string));
07752 }
07753
07754 SECTION("array")
07755 {
07756 SECTION("empty array")
07757 {
07758 json j = json::array();
07759
07760 j.clear();
07761 CHECK(j.empty());
07762 CHECK(j == json(json::value_t::array));
07763 }
07764
07765 SECTION("filled array")
07766 {
07767 json j = {1, 2, 3};
07768
07769 j.clear();
07770 CHECK(j.empty());
07771 CHECK(j == json(json::value_t::array));
07772 }
07773 }
07774
07775 SECTION("object")
07776 {
07777 SECTION("empty object")
07778 {
07779 json j = json::object();
07780
07781 j.clear();
07782 CHECK(j.empty());
07783 CHECK(j == json(json::value_t::object));
07784 }
07785
07786 SECTION("filled object")
07787 {
07788 json j = {{"one", 1}, {"two", 2}, {"three", 3}};
07789
07790 j.clear();
07791 CHECK(j.empty());
07792 CHECK(j == json(json::value_t::object));
07793 }
07794 }
07795
07796 SECTION("number (integer)")
07797 {
07798 json j = 23;
07799
07800 j.clear();
07801 CHECK(j == json(json::value_t::number_integer));
07802 }
07803
07804 SECTION("number (unsigned)")
07805 {
07806 json j = 23u;
07807
07808 j.clear();
07809 CHECK(j == json(json::value_t::number_integer));
07810 }
07811
07812 SECTION("number (float)")
07813 {
07814 json j = 23.42;
07815
07816 j.clear();
07817 CHECK(j == json(json::value_t::number_float));
07818 }
07819
07820 SECTION("null")
07821 {
07822 json j = nullptr;
07823
07824 j.clear();
07825 CHECK(j == json(json::value_t::null));
07826 }
07827 }
07828
07829 SECTION("push_back()")
07830 {
07831 SECTION("to array")
07832 {
07833 SECTION("json&&")
07834 {
07835 SECTION("null")
07836 {
07837 json j;
07838 j.push_back(1);
07839 j.push_back(2);
07840 CHECK(j.type() == json::value_t::array);
07841 CHECK(j == json({1, 2}));
07842 }
07843
07844 SECTION("array")
07845 {
07846 json j = {1, 2, 3};
07847 j.push_back("Hello");
07848 CHECK(j.type() == json::value_t::array);
07849 CHECK(j == json({1, 2, 3, "Hello"}));
07850 }
07851
07852 SECTION("other type")
07853 {
07854 json j = 1;
07855 CHECK_THROWS_AS(j.push_back("Hello"), std::domain_error);
07856 CHECK_THROWS_WITH(j.push_back("Hello"), "cannot use push_back() with number");
07857 }
07858 }
07859
07860 SECTION("const json&")
07861 {
07862 SECTION("null")
07863 {
07864 json j;
07865 json k(1);
07866 j.push_back(k);
07867 j.push_back(k);
07868 CHECK(j.type() == json::value_t::array);
07869 CHECK(j == json({1, 1}));
07870 }
07871
07872 SECTION("array")
07873 {
07874 json j = {1, 2, 3};
07875 json k("Hello");
07876 j.push_back(k);
07877 CHECK(j.type() == json::value_t::array);
07878 CHECK(j == json({1, 2, 3, "Hello"}));
07879 }
07880
07881 SECTION("other type")
07882 {
07883 json j = 1;
07884 json k("Hello");
07885 CHECK_THROWS_AS(j.push_back(k), std::domain_error);
07886 CHECK_THROWS_WITH(j.push_back(k), "cannot use push_back() with number");
07887 }
07888 }
07889 }
07890
07891 SECTION("to object")
07892 {
07893 SECTION("null")
07894 {
07895 json j;
07896 j.push_back(json::object_t::value_type({"one", 1}));
07897 j.push_back(json::object_t::value_type({"two", 2}));
07898 CHECK(j.type() == json::value_t::object);
07899 CHECK(j.size() == 2);
07900 CHECK(j["one"] == json(1));
07901 CHECK(j["two"] == json(2));
07902 }
07903
07904 SECTION("object")
07905 {
07906 json j(json::value_t::object);
07907 j.push_back(json::object_t::value_type({"one", 1}));
07908 j.push_back(json::object_t::value_type({"two", 2}));
07909 CHECK(j.size() == 2);
07910 CHECK(j["one"] == json(1));
07911 CHECK(j["two"] == json(2));
07912 }
07913
07914 SECTION("other type")
07915 {
07916 json j = 1;
07917 json k("Hello");
07918 CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error);
07919 CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({"one", 1})),
07920 "cannot use push_back() with number");
07921 }
07922 }
07923
07924 SECTION("with initializer_list")
07925 {
07926 SECTION("null")
07927 {
07928 json j;
07929 j.push_back({"foo", "bar"});
07930 CHECK(j == json::array({{"foo", "bar"}}));
07931
07932 json k;
07933 k.push_back({1, 2, 3});
07934 CHECK(k == json::array({{1, 2, 3}}));
07935 }
07936
07937 SECTION("array")
07938 {
07939 json j = {1, 2, 3};
07940 j.push_back({"foo", "bar"});
07941 CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
07942
07943 json k = {1, 2, 3};
07944 k.push_back({1, 2, 3});
07945 CHECK(k == json({1, 2, 3, {1, 2, 3}}));
07946 }
07947
07948 SECTION("object")
07949 {
07950 json j = {{"key1", 1}};
07951 j.push_back({"key2", "bar"});
07952 CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
07953
07954 json k = {{"key1", 1}};
07955 CHECK_THROWS_AS(k.push_back({1, 2, 3, 4}), std::domain_error);
07956 CHECK_THROWS_WITH(k.push_back({1, 2, 3, 4}), "cannot use push_back() with object");
07957 }
07958 }
07959 }
07960
07961 SECTION("operator+=")
07962 {
07963 SECTION("to array")
07964 {
07965 SECTION("json&&")
07966 {
07967 SECTION("null")
07968 {
07969 json j;
07970 j += 1;
07971 j += 2;
07972 CHECK(j.type() == json::value_t::array);
07973 CHECK(j == json({1, 2}));
07974 }
07975
07976 SECTION("array")
07977 {
07978 json j = {1, 2, 3};
07979 j += "Hello";
07980 CHECK(j.type() == json::value_t::array);
07981 CHECK(j == json({1, 2, 3, "Hello"}));
07982 }
07983
07984 SECTION("other type")
07985 {
07986 json j = 1;
07987 CHECK_THROWS_AS(j += "Hello", std::domain_error);
07988 CHECK_THROWS_WITH(j += "Hello", "cannot use push_back() with number");
07989 }
07990 }
07991
07992 SECTION("const json&")
07993 {
07994 SECTION("null")
07995 {
07996 json j;
07997 json k(1);
07998 j += k;
07999 j += k;
08000 CHECK(j.type() == json::value_t::array);
08001 CHECK(j == json({1, 1}));
08002 }
08003
08004 SECTION("array")
08005 {
08006 json j = {1, 2, 3};
08007 json k("Hello");
08008 j += k;
08009 CHECK(j.type() == json::value_t::array);
08010 CHECK(j == json({1, 2, 3, "Hello"}));
08011 }
08012
08013 SECTION("other type")
08014 {
08015 json j = 1;
08016 json k("Hello");
08017 CHECK_THROWS_AS(j += k, std::domain_error);
08018 CHECK_THROWS_WITH(j += k, "cannot use push_back() with number");
08019 }
08020 }
08021 }
08022
08023 SECTION("to object")
08024 {
08025 SECTION("null")
08026 {
08027 json j;
08028 j += json::object_t::value_type({"one", 1});
08029 j += json::object_t::value_type({"two", 2});
08030 CHECK(j.type() == json::value_t::object);
08031 CHECK(j.size() == 2);
08032 CHECK(j["one"] == json(1));
08033 CHECK(j["two"] == json(2));
08034 }
08035
08036 SECTION("object")
08037 {
08038 json j(json::value_t::object);
08039 j += json::object_t::value_type({"one", 1});
08040 j += json::object_t::value_type({"two", 2});
08041 CHECK(j.size() == 2);
08042 CHECK(j["one"] == json(1));
08043 CHECK(j["two"] == json(2));
08044 }
08045
08046 SECTION("other type")
08047 {
08048 json j = 1;
08049 json k("Hello");
08050 CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), std::domain_error);
08051 CHECK_THROWS_WITH(j += json::object_t::value_type({"one", 1}),
08052 "cannot use push_back() with number");
08053 }
08054 }
08055
08056 SECTION("with initializer_list")
08057 {
08058 SECTION("null")
08059 {
08060 json j;
08061 j += {"foo", "bar"};
08062 CHECK(j == json::array({{"foo", "bar"}}));
08063
08064 json k;
08065 k += {1, 2, 3};
08066 CHECK(k == json::array({{1, 2, 3}}));
08067 }
08068
08069 SECTION("array")
08070 {
08071 json j = {1, 2, 3};
08072 j += {"foo", "bar"};
08073 CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
08074
08075 json k = {1, 2, 3};
08076 k += {1, 2, 3};
08077 CHECK(k == json({1, 2, 3, {1, 2, 3}}));
08078 }
08079
08080 SECTION("object")
08081 {
08082 json j = {{"key1", 1}};
08083 j += {"key2", "bar"};
08084 CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
08085
08086 json k = {{"key1", 1}};
08087 CHECK_THROWS_AS((k += {1, 2, 3, 4}), std::domain_error);
08088 CHECK_THROWS_WITH((k += {1, 2, 3, 4}), "cannot use push_back() with object");
08089 }
08090 }
08091 }
08092
08093 SECTION("insert")
08094 {
08095 json j_array = {1, 2, 3, 4};
08096 json j_value = 5;
08097
08098 SECTION("value at position")
08099 {
08100 SECTION("insert before begin()")
08101 {
08102 auto it = j_array.insert(j_array.begin(), j_value);
08103 CHECK(j_array.size() == 5);
08104 CHECK(*it == j_value);
08105 CHECK(j_array.begin() == it);
08106 CHECK(j_array == json({5, 1, 2, 3, 4}));
08107 }
08108
08109 SECTION("insert in the middle")
08110 {
08111 auto it = j_array.insert(j_array.begin() + 2, j_value);
08112 CHECK(j_array.size() == 5);
08113 CHECK(*it == j_value);
08114 CHECK((it - j_array.begin()) == 2);
08115 CHECK(j_array == json({1, 2, 5, 3, 4}));
08116 }
08117
08118 SECTION("insert before end()")
08119 {
08120 auto it = j_array.insert(j_array.end(), j_value);
08121 CHECK(j_array.size() == 5);
08122 CHECK(*it == j_value);
08123 CHECK((j_array.end() - it) == 1);
08124 CHECK(j_array == json({1, 2, 3, 4, 5}));
08125 }
08126 }
08127
08128 SECTION("rvalue at position")
08129 {
08130 SECTION("insert before begin()")
08131 {
08132 auto it = j_array.insert(j_array.begin(), 5);
08133 CHECK(j_array.size() == 5);
08134 CHECK(*it == j_value);
08135 CHECK(j_array.begin() == it);
08136 CHECK(j_array == json({5, 1, 2, 3, 4}));
08137 }
08138
08139 SECTION("insert in the middle")
08140 {
08141 auto it = j_array.insert(j_array.begin() + 2, 5);
08142 CHECK(j_array.size() == 5);
08143 CHECK(*it == j_value);
08144 CHECK((it - j_array.begin()) == 2);
08145 CHECK(j_array == json({1, 2, 5, 3, 4}));
08146 }
08147
08148 SECTION("insert before end()")
08149 {
08150 auto it = j_array.insert(j_array.end(), 5);
08151 CHECK(j_array.size() == 5);
08152 CHECK(*it == j_value);
08153 CHECK((j_array.end() - it) == 1);
08154 CHECK(j_array == json({1, 2, 3, 4, 5}));
08155 }
08156 }
08157
08158 SECTION("copies at position")
08159 {
08160 SECTION("insert before begin()")
08161 {
08162 auto it = j_array.insert(j_array.begin(), 3, 5);
08163 CHECK(j_array.size() == 7);
08164 CHECK(*it == j_value);
08165 CHECK(j_array.begin() == it);
08166 CHECK(j_array == json({5, 5, 5, 1, 2, 3, 4}));
08167 }
08168
08169 SECTION("insert in the middle")
08170 {
08171 auto it = j_array.insert(j_array.begin() + 2, 3, 5);
08172 CHECK(j_array.size() == 7);
08173 CHECK(*it == j_value);
08174 CHECK((it - j_array.begin()) == 2);
08175 CHECK(j_array == json({1, 2, 5, 5, 5, 3, 4}));
08176 }
08177
08178 SECTION("insert before end()")
08179 {
08180 auto it = j_array.insert(j_array.end(), 3, 5);
08181 CHECK(j_array.size() == 7);
08182 CHECK(*it == j_value);
08183 CHECK((j_array.end() - it) == 3);
08184 CHECK(j_array == json({1, 2, 3, 4, 5, 5, 5}));
08185 }
08186
08187 SECTION("insert nothing (count = 0)")
08188 {
08189 auto pos = j_array.end();
08190 auto it = j_array.insert(j_array.end(), 0, 5);
08191 CHECK(j_array.size() == 4);
08192 CHECK(it == pos);
08193 CHECK(j_array == json({1, 2, 3, 4}));
08194 }
08195 }
08196
08197 SECTION("range")
08198 {
08199 json j_other_array = {"first", "second"};
08200
08201 SECTION("proper usage")
08202 {
08203 auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());
08204 CHECK(j_array.size() == 6);
08205 CHECK(*it == *j_other_array.begin());
08206 CHECK((j_array.end() - it) == 2);
08207 CHECK(j_array == json({1, 2, 3, 4, "first", "second"}));
08208 }
08209
08210 SECTION("empty range")
08211 {
08212 auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());
08213 CHECK(j_array.size() == 4);
08214 CHECK(it == j_array.end());
08215 CHECK(j_array == json({1, 2, 3, 4}));
08216 }
08217
08218 SECTION("invalid iterators")
08219 {
08220 json j_other_array2 = {"first", "second"};
08221
08222 CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error);
08223 CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
08224 std::domain_error);
08225
08226 CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
08227 "passed iterators may not belong to container");
08228 CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
08229 "iterators do not fit");
08230 }
08231 }
08232
08233 SECTION("initializer list at position")
08234 {
08235 SECTION("insert before begin()")
08236 {
08237 auto it = j_array.insert(j_array.begin(), {7, 8, 9});
08238 CHECK(j_array.size() == 7);
08239 CHECK(*it == json(7));
08240 CHECK(j_array.begin() == it);
08241 CHECK(j_array == json({7, 8, 9, 1, 2, 3, 4}));
08242 }
08243
08244 SECTION("insert in the middle")
08245 {
08246 auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9});
08247 CHECK(j_array.size() == 7);
08248 CHECK(*it == json(7));
08249 CHECK((it - j_array.begin()) == 2);
08250 CHECK(j_array == json({1, 2, 7, 8, 9, 3, 4}));
08251 }
08252
08253 SECTION("insert before end()")
08254 {
08255 auto it = j_array.insert(j_array.end(), {7, 8, 9});
08256 CHECK(j_array.size() == 7);
08257 CHECK(*it == json(7));
08258 CHECK((j_array.end() - it) == 3);
08259 CHECK(j_array == json({1, 2, 3, 4, 7, 8, 9}));
08260 }
08261 }
08262
08263 SECTION("invalid iterator")
08264 {
08265
08266 json j_another_array = {1, 2};
08267 json j_yet_another_array = {"first", "second"};
08268 CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), std::domain_error);
08269 CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), std::domain_error);
08270 CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), std::domain_error);
08271 CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(),
08272 j_yet_another_array.end()), std::domain_error);
08273 CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), std::domain_error);
08274
08275 CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10), "iterator does not fit current value");
08276 CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value),
08277 "iterator does not fit current value");
08278 CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11),
08279 "iterator does not fit current value");
08280 CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(),
08281 j_yet_another_array.end()), "iterator does not fit current value");
08282 CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}),
08283 "iterator does not fit current value");
08284 }
08285
08286 SECTION("non-array type")
08287 {
08288
08289 json j_nonarray = 3;
08290 json j_yet_another_array = {"first", "second"};
08291 CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), std::domain_error);
08292 CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), std::domain_error);
08293 CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), std::domain_error);
08294 CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
08295 j_yet_another_array.end()), std::domain_error);
08296 CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), std::domain_error);
08297
08298 CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), "cannot use insert() with number");
08299 CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), "cannot use insert() with number");
08300 CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), "cannot use insert() with number");
08301 CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
08302 j_yet_another_array.end()), "cannot use insert() with number");
08303 CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}),
08304 "cannot use insert() with number");
08305 }
08306 }
08307
08308 SECTION("swap()")
08309 {
08310 SECTION("json")
08311 {
08312 SECTION("member swap")
08313 {
08314 json j("hello world");
08315 json k(42.23);
08316
08317 j.swap(k);
08318
08319 CHECK(j == json(42.23));
08320 CHECK(k == json("hello world"));
08321 }
08322
08323 SECTION("nonmember swap")
08324 {
08325 json j("hello world");
08326 json k(42.23);
08327
08328 std::swap(j, k);
08329
08330 CHECK(j == json(42.23));
08331 CHECK(k == json("hello world"));
08332 }
08333 }
08334
08335 SECTION("array_t")
08336 {
08337 SECTION("array_t type")
08338 {
08339 json j = {1, 2, 3, 4};
08340 json::array_t a = {"foo", "bar", "baz"};
08341
08342 j.swap(a);
08343
08344 CHECK(j == json({"foo", "bar", "baz"}));
08345
08346 j.swap(a);
08347
08348 CHECK(j == json({1, 2, 3, 4}));
08349 }
08350
08351 SECTION("non-array_t type")
08352 {
08353 json j = 17;
08354 json::array_t a = {"foo", "bar", "baz"};
08355
08356 CHECK_THROWS_AS(j.swap(a), std::domain_error);
08357 CHECK_THROWS_WITH(j.swap(a), "cannot use swap() with number");
08358 }
08359 }
08360
08361 SECTION("object_t")
08362 {
08363 SECTION("object_t type")
08364 {
08365 json j = {{"one", 1}, {"two", 2}};
08366 json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
08367
08368 j.swap(o);
08369
08370 CHECK(j == json({{"cow", "Kuh"}, {"chicken", "Huhn"}}));
08371
08372 j.swap(o);
08373
08374 CHECK(j == json({{"one", 1}, {"two", 2}}));
08375 }
08376
08377 SECTION("non-object_t type")
08378 {
08379 json j = 17;
08380 json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
08381
08382 CHECK_THROWS_AS(j.swap(o), std::domain_error);
08383 CHECK_THROWS_WITH(j.swap(o), "cannot use swap() with number");
08384 }
08385 }
08386
08387 SECTION("string_t")
08388 {
08389 SECTION("string_t type")
08390 {
08391 json j = "Hello world";
08392 json::string_t s = "Hallo Welt";
08393
08394 j.swap(s);
08395
08396 CHECK(j == json("Hallo Welt"));
08397
08398 j.swap(s);
08399
08400 CHECK(j == json("Hello world"));
08401 }
08402
08403 SECTION("non-string_t type")
08404 {
08405 json j = 17;
08406 json::string_t s = "Hallo Welt";
08407
08408 CHECK_THROWS_AS(j.swap(s), std::domain_error);
08409 CHECK_THROWS_WITH(j.swap(s), "cannot use swap() with number");
08410 }
08411 }
08412 }
08413 }
08414
08415 TEST_CASE("lexicographical comparison operators")
08416 {
08417 SECTION("types")
08418 {
08419 std::vector<json::value_t> j_types =
08420 {
08421 json::value_t::null,
08422 json::value_t::boolean,
08423 json::value_t::number_integer,
08424 json::value_t::number_unsigned,
08425 json::value_t::number_float,
08426 json::value_t::object,
08427 json::value_t::array,
08428 json::value_t::string
08429 };
08430
08431 SECTION("comparison: less")
08432 {
08433 std::vector<std::vector<bool>> expected =
08434 {
08435 {false, true, true, true, true, true, true, true},
08436 {false, false, true, true, true, true, true, true},
08437 {false, false, false, false, false, true, true, true},
08438 {false, false, false, false, false, true, true, true},
08439 {false, false, false, false, false, true, true, true},
08440 {false, false, false, false, false, false, true, true},
08441 {false, false, false, false, false, false, false, true},
08442 {false, false, false, false, false, false, false, false}
08443 };
08444
08445 for (size_t i = 0; i < j_types.size(); ++i)
08446 {
08447 for (size_t j = 0; j < j_types.size(); ++j)
08448 {
08449 CAPTURE(i);
08450 CAPTURE(j);
08451
08452 CHECK(operator<(j_types[i], j_types[j]) == expected[i][j]);
08453 }
08454 }
08455 }
08456 }
08457
08458 SECTION("values")
08459 {
08460 json j_values =
08461 {
08462 nullptr, nullptr,
08463 17, 42,
08464 8u, 13u,
08465 3.14159, 23.42,
08466 "foo", "bar",
08467 true, false,
08468 {1, 2, 3}, {"one", "two", "three"},
08469 {{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}}
08470 };
08471
08472 SECTION("comparison: equal")
08473 {
08474 std::vector<std::vector<bool>> expected =
08475 {
08476 {true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
08477 {true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
08478 {false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false},
08479 {false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false},
08480 {false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false},
08481 {false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false},
08482 {false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false},
08483 {false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false},
08484 {false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},
08485 {false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false},
08486 {false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false},
08487 {false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false},
08488 {false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false},
08489 {false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false},
08490 {false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false},
08491 {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true}
08492 };
08493
08494 for (size_t i = 0; i < j_values.size(); ++i)
08495 {
08496 for (size_t j = 0; j < j_values.size(); ++j)
08497 {
08498 CAPTURE(i);
08499 CAPTURE(j);
08500
08501 CHECK( (j_values[i] == j_values[j]) == expected[i][j] );
08502 }
08503 }
08504
08505
08506 json j_discarded(json::value_t::discarded);
08507 for (size_t i = 0; i < j_values.size(); ++i)
08508 {
08509 CHECK( (j_values[i] == j_discarded) == false);
08510 CHECK( (j_discarded == j_values[i]) == false);
08511 CHECK( (j_discarded == j_discarded) == false);
08512 }
08513
08514
08515 json j_null;
08516 CHECK(j_null == nullptr);
08517 CHECK(nullptr == j_null);
08518 }
08519
08520 SECTION("comparison: not equal")
08521 {
08522 for (size_t i = 0; i < j_values.size(); ++i)
08523 {
08524 for (size_t j = 0; j < j_values.size(); ++j)
08525 {
08526 CAPTURE(i);
08527 CAPTURE(j);
08528
08529 CHECK( (j_values[i] != j_values[j]) == not(j_values[i] == j_values[j]) );
08530 }
08531 }
08532
08533
08534 json j_null;
08535 CHECK( (j_null != nullptr) == false);
08536 CHECK( (nullptr != j_null) == false);
08537 CHECK( (j_null != nullptr) == not(j_null == nullptr));
08538 CHECK( (nullptr != j_null) == not(nullptr == j_null));
08539 }
08540
08541 SECTION("comparison: less")
08542 {
08543 std::vector<std::vector<bool>> expected =
08544 {
08545 {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
08546 {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
08547 {false, false, false, true, false, false, false, true, true, true, false, false, true, true, true, true},
08548 {false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, true},
08549 {false, false, true, true, false, true, false, true, true, true, false, false, true, true, true, true},
08550 {false, false, true, true, false, false, false, true, true, true, false, false, true, true, true, true},
08551 {false, false, true, true, true, true, false, true, true, true, false, false, true, true, true, true},
08552 {false, false, false, true, false, false, false, false, true, true, false, false, true, true, true, true},
08553 {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
08554 {false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},
08555 {false, false, true, true, true, true, true, true, true, true, false, false, true, true, true, true},
08556 {false, false, true, true, true, true, true, true, true, true, true, false, true, true, true, true},
08557 {false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false},
08558 {false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false},
08559 {false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false},
08560 {false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, false}
08561 };
08562
08563 for (size_t i = 0; i < j_values.size(); ++i)
08564 {
08565 for (size_t j = 0; j < j_values.size(); ++j)
08566 {
08567 CAPTURE(i);
08568 CAPTURE(j);
08569
08570 CHECK( (j_values[i] < j_values[j]) == expected[i][j] );
08571 }
08572 }
08573
08574
08575 json j_discarded(json::value_t::discarded);
08576 for (size_t i = 0; i < j_values.size(); ++i)
08577 {
08578 CAPTURE(i);
08579 CHECK( (j_values[i] < j_discarded) == false);
08580 CHECK( (j_discarded < j_values[i]) == false);
08581 CHECK( (j_discarded < j_discarded) == false);
08582 }
08583 }
08584
08585 SECTION("comparison: less than or equal equal")
08586 {
08587 for (size_t i = 0; i < j_values.size(); ++i)
08588 {
08589 for (size_t j = 0; j < j_values.size(); ++j)
08590 {
08591 CAPTURE(i);
08592 CAPTURE(j);
08593
08594 CHECK( (j_values[i] <= j_values[j]) == not(j_values[j] < j_values[i]) );
08595 }
08596 }
08597 }
08598
08599 SECTION("comparison: greater than")
08600 {
08601 for (size_t i = 0; i < j_values.size(); ++i)
08602 {
08603 for (size_t j = 0; j < j_values.size(); ++j)
08604 {
08605 CAPTURE(i);
08606 CAPTURE(j);
08607
08608 CHECK( (j_values[i] > j_values[j]) == (j_values[j] < j_values[i]) );
08609 }
08610 }
08611 }
08612
08613 SECTION("comparison: greater than or equal")
08614 {
08615 for (size_t i = 0; i < j_values.size(); ++i)
08616 {
08617 for (size_t j = 0; j < j_values.size(); ++j)
08618 {
08619 CAPTURE(i);
08620 CAPTURE(j);
08621
08622 CHECK( (j_values[i] >= j_values[j]) == not(j_values[i] < j_values[j]) );
08623 }
08624 }
08625 }
08626 }
08627 }
08628
08629 TEST_CASE("serialization")
08630 {
08631 SECTION("operator<<")
08632 {
08633 SECTION("no given width")
08634 {
08635 std::stringstream ss;
08636 json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
08637 ss << j;
08638 CHECK(ss.str() == "[\"foo\",1,2,3,false,{\"one\":1}]");
08639 }
08640
08641 SECTION("given width")
08642 {
08643 std::stringstream ss;
08644 json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
08645 ss << std::setw(4) << j;
08646 CHECK(ss.str() ==
08647 "[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
08648 }
08649 }
08650
08651 SECTION("operator>>")
08652 {
08653 SECTION("no given width")
08654 {
08655 std::stringstream ss;
08656 json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
08657 j >> ss;
08658 CHECK(ss.str() == "[\"foo\",1,2,3,false,{\"one\":1}]");
08659 }
08660
08661 SECTION("given width")
08662 {
08663 std::stringstream ss;
08664 json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
08665 ss.width(4);
08666 j >> ss;
08667 CHECK(ss.str() ==
08668 "[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
08669 }
08670 }
08671 }
08672
08673 TEST_CASE("deserialization")
08674 {
08675 SECTION("stream")
08676 {
08677 std::stringstream ss;
08678 ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
08679 json j = json::parse(ss);
08680 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
08681 }
08682
08683 SECTION("string")
08684 {
08685 auto s = "[\"foo\",1,2,3,false,{\"one\":1}]";
08686 json j = json::parse(s);
08687 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
08688 }
08689
08690 SECTION("operator<<")
08691 {
08692 std::stringstream ss;
08693 ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
08694 json j;
08695 j << ss;
08696 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
08697 }
08698
08699 SECTION("operator>>")
08700 {
08701 std::stringstream ss;
08702 ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
08703 json j;
08704 ss >> j;
08705 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
08706 }
08707
08708 SECTION("user-defined string literal")
08709 {
08710 CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
08711 }
08712 }
08713
08714 TEST_CASE("iterator class")
08715 {
08716 SECTION("construction")
08717 {
08718 SECTION("constructor")
08719 {
08720 SECTION("null")
08721 {
08722 json j(json::value_t::null);
08723 json::iterator it(&j);
08724 }
08725
08726 SECTION("object")
08727 {
08728 json j(json::value_t::object);
08729 json::iterator it(&j);
08730 }
08731
08732 SECTION("array")
08733 {
08734 json j(json::value_t::array);
08735 json::iterator it(&j);
08736 }
08737 }
08738
08739 SECTION("copy assignment")
08740 {
08741 json j(json::value_t::null);
08742 json::iterator it(&j);
08743 json::iterator it2(&j);
08744 it2 = it;
08745 }
08746 }
08747
08748 SECTION("initialization")
08749 {
08750 SECTION("set_begin")
08751 {
08752 SECTION("null")
08753 {
08754 json j(json::value_t::null);
08755 json::iterator it(&j);
08756 it.set_begin();
08757 CHECK(it == j.begin());
08758 }
08759
08760 SECTION("object")
08761 {
08762 json j(json::value_t::object);
08763 json::iterator it(&j);
08764 it.set_begin();
08765 CHECK(it == j.begin());
08766 }
08767
08768 SECTION("array")
08769 {
08770 json j(json::value_t::array);
08771 json::iterator it(&j);
08772 it.set_begin();
08773 CHECK(it == j.begin());
08774 }
08775 }
08776
08777 SECTION("set_end")
08778 {
08779 SECTION("null")
08780 {
08781 json j(json::value_t::null);
08782 json::iterator it(&j);
08783 it.set_end();
08784 CHECK(it == j.end());
08785 }
08786
08787 SECTION("object")
08788 {
08789 json j(json::value_t::object);
08790 json::iterator it(&j);
08791 it.set_end();
08792 CHECK(it == j.end());
08793 }
08794
08795 SECTION("array")
08796 {
08797 json j(json::value_t::array);
08798 json::iterator it(&j);
08799 it.set_end();
08800 CHECK(it == j.end());
08801 }
08802 }
08803 }
08804
08805 SECTION("element access")
08806 {
08807 SECTION("operator*")
08808 {
08809 SECTION("null")
08810 {
08811 json j(json::value_t::null);
08812 json::iterator it = j.begin();
08813 CHECK_THROWS_AS(*it, std::out_of_range);
08814 CHECK_THROWS_WITH(*it, "cannot get value");
08815 }
08816
08817 SECTION("number")
08818 {
08819 json j(17);
08820 json::iterator it = j.begin();
08821 CHECK(*it == json(17));
08822 it = j.end();
08823 CHECK_THROWS_AS(*it, std::out_of_range);
08824 CHECK_THROWS_WITH(*it, "cannot get value");
08825 }
08826
08827 SECTION("object")
08828 {
08829 json j({{"foo", "bar"}});
08830 json::iterator it = j.begin();
08831 CHECK(*it == json("bar"));
08832 }
08833
08834 SECTION("array")
08835 {
08836 json j({1, 2, 3, 4});
08837 json::iterator it = j.begin();
08838 CHECK(*it == json(1));
08839 }
08840 }
08841
08842 SECTION("operator->")
08843 {
08844 SECTION("null")
08845 {
08846 json j(json::value_t::null);
08847 json::iterator it = j.begin();
08848 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
08849 CHECK_THROWS_WITH(it->type_name(), "cannot get value");
08850 }
08851
08852 SECTION("number")
08853 {
08854 json j(17);
08855 json::iterator it = j.begin();
08856 CHECK(it->type_name() == "number");
08857 it = j.end();
08858 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
08859 CHECK_THROWS_WITH(it->type_name(), "cannot get value");
08860 }
08861
08862 SECTION("object")
08863 {
08864 json j({{"foo", "bar"}});
08865 json::iterator it = j.begin();
08866 CHECK(it->type_name() == "string");
08867 }
08868
08869 SECTION("array")
08870 {
08871 json j({1, 2, 3, 4});
08872 json::iterator it = j.begin();
08873 CHECK(it->type_name() == "number");
08874 }
08875 }
08876 }
08877
08878 SECTION("increment/decrement")
08879 {
08880 SECTION("post-increment")
08881 {
08882 SECTION("null")
08883 {
08884 json j(json::value_t::null);
08885 json::iterator it = j.begin();
08886 CHECK(it.m_it.primitive_iterator == 1);
08887 it++;
08888 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
08889 }
08890
08891 SECTION("number")
08892 {
08893 json j(17);
08894 json::iterator it = j.begin();
08895 CHECK(it.m_it.primitive_iterator == 0);
08896 it++;
08897 CHECK(it.m_it.primitive_iterator == 1);
08898 it++;
08899 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
08900 }
08901
08902 SECTION("object")
08903 {
08904 json j({{"foo", "bar"}});
08905 json::iterator it = j.begin();
08906 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
08907 it++;
08908 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
08909 }
08910
08911 SECTION("array")
08912 {
08913 json j({1, 2, 3, 4});
08914 json::iterator it = j.begin();
08915 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
08916 it++;
08917 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08918 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08919 it++;
08920 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08921 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08922 it++;
08923 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08924 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08925 it++;
08926 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08927 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
08928 }
08929 }
08930
08931 SECTION("pre-increment")
08932 {
08933 SECTION("null")
08934 {
08935 json j(json::value_t::null);
08936 json::iterator it = j.begin();
08937 CHECK(it.m_it.primitive_iterator == 1);
08938 ++it;
08939 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
08940 }
08941
08942 SECTION("number")
08943 {
08944 json j(17);
08945 json::iterator it = j.begin();
08946 CHECK(it.m_it.primitive_iterator == 0);
08947 ++it;
08948 CHECK(it.m_it.primitive_iterator == 1);
08949 ++it;
08950 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
08951 }
08952
08953 SECTION("object")
08954 {
08955 json j({{"foo", "bar"}});
08956 json::iterator it = j.begin();
08957 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
08958 ++it;
08959 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
08960 }
08961
08962 SECTION("array")
08963 {
08964 json j({1, 2, 3, 4});
08965 json::iterator it = j.begin();
08966 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
08967 ++it;
08968 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08969 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08970 ++it;
08971 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08972 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08973 ++it;
08974 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08975 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
08976 ++it;
08977 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
08978 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
08979 }
08980 }
08981
08982 SECTION("post-decrement")
08983 {
08984 SECTION("null")
08985 {
08986 json j(json::value_t::null);
08987 json::iterator it = j.end();
08988 CHECK(it.m_it.primitive_iterator == 1);
08989 }
08990
08991 SECTION("number")
08992 {
08993 json j(17);
08994 json::iterator it = j.end();
08995 CHECK(it.m_it.primitive_iterator == 1);
08996 it--;
08997 CHECK(it.m_it.primitive_iterator == 0);
08998 it--;
08999 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09000 }
09001
09002 SECTION("object")
09003 {
09004 json j({{"foo", "bar"}});
09005 json::iterator it = j.end();
09006 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09007 it--;
09008 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09009 }
09010
09011 SECTION("array")
09012 {
09013 json j({1, 2, 3, 4});
09014 json::iterator it = j.end();
09015 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09016 it--;
09017 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09018 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09019 it--;
09020 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09021 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09022 it--;
09023 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09024 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09025 it--;
09026 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09027 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09028 }
09029 }
09030
09031 SECTION("pre-decrement")
09032 {
09033 SECTION("null")
09034 {
09035 json j(json::value_t::null);
09036 json::iterator it = j.end();
09037 CHECK(it.m_it.primitive_iterator == 1);
09038 }
09039
09040 SECTION("number")
09041 {
09042 json j(17);
09043 json::iterator it = j.end();
09044 CHECK(it.m_it.primitive_iterator == 1);
09045 --it;
09046 CHECK(it.m_it.primitive_iterator == 0);
09047 --it;
09048 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09049 }
09050
09051 SECTION("object")
09052 {
09053 json j({{"foo", "bar"}});
09054 json::iterator it = j.end();
09055 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09056 --it;
09057 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09058 }
09059
09060 SECTION("array")
09061 {
09062 json j({1, 2, 3, 4});
09063 json::iterator it = j.end();
09064 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09065 --it;
09066 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09067 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09068 --it;
09069 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09070 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09071 --it;
09072 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09073 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09074 --it;
09075 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09076 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09077 }
09078 }
09079 }
09080 }
09081
09082 TEST_CASE("const_iterator class")
09083 {
09084 SECTION("construction")
09085 {
09086 SECTION("constructor")
09087 {
09088 SECTION("null")
09089 {
09090 json j(json::value_t::null);
09091 json::const_iterator it(&j);
09092 }
09093
09094 SECTION("object")
09095 {
09096 json j(json::value_t::object);
09097 json::const_iterator it(&j);
09098 }
09099
09100 SECTION("array")
09101 {
09102 json j(json::value_t::array);
09103 json::const_iterator it(&j);
09104 }
09105 }
09106
09107 SECTION("copy assignment")
09108 {
09109 json j(json::value_t::null);
09110 json::const_iterator it(&j);
09111 json::const_iterator it2(&j);
09112 it2 = it;
09113 }
09114 }
09115
09116 SECTION("initialization")
09117 {
09118 SECTION("set_begin")
09119 {
09120 SECTION("null")
09121 {
09122 json j(json::value_t::null);
09123 json::const_iterator it(&j);
09124 it.set_begin();
09125 CHECK(it == j.cbegin());
09126 }
09127
09128 SECTION("object")
09129 {
09130 json j(json::value_t::object);
09131 json::const_iterator it(&j);
09132 it.set_begin();
09133 CHECK(it == j.cbegin());
09134 }
09135
09136 SECTION("array")
09137 {
09138 json j(json::value_t::array);
09139 json::const_iterator it(&j);
09140 it.set_begin();
09141 CHECK(it == j.cbegin());
09142 }
09143 }
09144
09145 SECTION("set_end")
09146 {
09147 SECTION("null")
09148 {
09149 json j(json::value_t::null);
09150 json::const_iterator it(&j);
09151 it.set_end();
09152 CHECK(it == j.cend());
09153 }
09154
09155 SECTION("object")
09156 {
09157 json j(json::value_t::object);
09158 json::const_iterator it(&j);
09159 it.set_end();
09160 CHECK(it == j.cend());
09161 }
09162
09163 SECTION("array")
09164 {
09165 json j(json::value_t::array);
09166 json::const_iterator it(&j);
09167 it.set_end();
09168 CHECK(it == j.cend());
09169 }
09170 }
09171 }
09172
09173 SECTION("element access")
09174 {
09175 SECTION("operator*")
09176 {
09177 SECTION("null")
09178 {
09179 json j(json::value_t::null);
09180 json::const_iterator it = j.cbegin();
09181 CHECK_THROWS_AS(*it, std::out_of_range);
09182 CHECK_THROWS_WITH(*it, "cannot get value");
09183 }
09184
09185 SECTION("number")
09186 {
09187 json j(17);
09188 json::const_iterator it = j.cbegin();
09189 CHECK(*it == json(17));
09190 it = j.cend();
09191 CHECK_THROWS_AS(*it, std::out_of_range);
09192 CHECK_THROWS_WITH(*it, "cannot get value");
09193 }
09194
09195 SECTION("object")
09196 {
09197 json j({{"foo", "bar"}});
09198 json::const_iterator it = j.cbegin();
09199 CHECK(*it == json("bar"));
09200 }
09201
09202 SECTION("array")
09203 {
09204 json j({1, 2, 3, 4});
09205 json::const_iterator it = j.cbegin();
09206 CHECK(*it == json(1));
09207 }
09208 }
09209
09210 SECTION("operator->")
09211 {
09212 SECTION("null")
09213 {
09214 json j(json::value_t::null);
09215 json::const_iterator it = j.cbegin();
09216 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
09217 CHECK_THROWS_WITH(it->type_name(), "cannot get value");
09218 }
09219
09220 SECTION("number")
09221 {
09222 json j(17);
09223 json::const_iterator it = j.cbegin();
09224 CHECK(it->type_name() == "number");
09225 it = j.cend();
09226 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
09227 CHECK_THROWS_WITH(it->type_name(), "cannot get value");
09228 }
09229
09230 SECTION("object")
09231 {
09232 json j({{"foo", "bar"}});
09233 json::const_iterator it = j.cbegin();
09234 CHECK(it->type_name() == "string");
09235 }
09236
09237 SECTION("array")
09238 {
09239 json j({1, 2, 3, 4});
09240 json::const_iterator it = j.cbegin();
09241 CHECK(it->type_name() == "number");
09242 }
09243 }
09244 }
09245
09246 SECTION("increment/decrement")
09247 {
09248 SECTION("post-increment")
09249 {
09250 SECTION("null")
09251 {
09252 json j(json::value_t::null);
09253 json::const_iterator it = j.cbegin();
09254 CHECK(it.m_it.primitive_iterator == 1);
09255 it++;
09256 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09257 }
09258
09259 SECTION("number")
09260 {
09261 json j(17);
09262 json::const_iterator it = j.cbegin();
09263 CHECK(it.m_it.primitive_iterator == 0);
09264 it++;
09265 CHECK(it.m_it.primitive_iterator == 1);
09266 it++;
09267 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09268 }
09269
09270 SECTION("object")
09271 {
09272 json j({{"foo", "bar"}});
09273 json::const_iterator it = j.cbegin();
09274 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09275 it++;
09276 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09277 }
09278
09279 SECTION("array")
09280 {
09281 json j({1, 2, 3, 4});
09282 json::const_iterator it = j.cbegin();
09283 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09284 it++;
09285 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09286 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09287 it++;
09288 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09289 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09290 it++;
09291 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09292 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09293 it++;
09294 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09295 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09296 }
09297 }
09298
09299 SECTION("pre-increment")
09300 {
09301 SECTION("null")
09302 {
09303 json j(json::value_t::null);
09304 json::const_iterator it = j.cbegin();
09305 CHECK(it.m_it.primitive_iterator == 1);
09306 ++it;
09307 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09308 }
09309
09310 SECTION("number")
09311 {
09312 json j(17);
09313 json::const_iterator it = j.cbegin();
09314 CHECK(it.m_it.primitive_iterator == 0);
09315 ++it;
09316 CHECK(it.m_it.primitive_iterator == 1);
09317 ++it;
09318 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09319 }
09320
09321 SECTION("object")
09322 {
09323 json j({{"foo", "bar"}});
09324 json::const_iterator it = j.cbegin();
09325 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09326 ++it;
09327 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09328 }
09329
09330 SECTION("array")
09331 {
09332 json j({1, 2, 3, 4});
09333 json::const_iterator it = j.cbegin();
09334 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09335 ++it;
09336 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09337 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09338 ++it;
09339 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09340 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09341 ++it;
09342 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09343 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09344 ++it;
09345 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09346 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09347 }
09348 }
09349
09350 SECTION("post-decrement")
09351 {
09352 SECTION("null")
09353 {
09354 json j(json::value_t::null);
09355 json::const_iterator it = j.cend();
09356 CHECK(it.m_it.primitive_iterator == 1);
09357 }
09358
09359 SECTION("number")
09360 {
09361 json j(17);
09362 json::const_iterator it = j.cend();
09363 CHECK(it.m_it.primitive_iterator == 1);
09364 it--;
09365 CHECK(it.m_it.primitive_iterator == 0);
09366 it--;
09367 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09368 }
09369
09370 SECTION("object")
09371 {
09372 json j({{"foo", "bar"}});
09373 json::const_iterator it = j.cend();
09374 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09375 it--;
09376 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09377 }
09378
09379 SECTION("array")
09380 {
09381 json j({1, 2, 3, 4});
09382 json::const_iterator it = j.cend();
09383 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09384 it--;
09385 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09386 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09387 it--;
09388 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09389 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09390 it--;
09391 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09392 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09393 it--;
09394 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09395 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09396 }
09397 }
09398
09399 SECTION("pre-decrement")
09400 {
09401 SECTION("null")
09402 {
09403 json j(json::value_t::null);
09404 json::const_iterator it = j.cend();
09405 CHECK(it.m_it.primitive_iterator == 1);
09406 }
09407
09408 SECTION("number")
09409 {
09410 json j(17);
09411 json::const_iterator it = j.cend();
09412 CHECK(it.m_it.primitive_iterator == 1);
09413 --it;
09414 CHECK(it.m_it.primitive_iterator == 0);
09415 --it;
09416 CHECK((it.m_it.primitive_iterator != 0 and it.m_it.primitive_iterator != 1));
09417 }
09418
09419 SECTION("object")
09420 {
09421 json j({{"foo", "bar"}});
09422 json::const_iterator it = j.cend();
09423 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end());
09424 --it;
09425 CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin());
09426 }
09427
09428 SECTION("array")
09429 {
09430 json j({1, 2, 3, 4});
09431 json::const_iterator it = j.cend();
09432 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end());
09433 --it;
09434 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09435 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09436 --it;
09437 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09438 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09439 --it;
09440 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin());
09441 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09442 --it;
09443 CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin());
09444 CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end());
09445 }
09446 }
09447 }
09448 }
09449
09450 TEST_CASE("convenience functions")
09451 {
09452 SECTION("type name as string")
09453 {
09454 CHECK(json(json::value_t::null).type_name() == "null");
09455 CHECK(json(json::value_t::object).type_name() == "object");
09456 CHECK(json(json::value_t::array).type_name() == "array");
09457 CHECK(json(json::value_t::number_integer).type_name() == "number");
09458 CHECK(json(json::value_t::number_float).type_name() == "number");
09459 CHECK(json(json::value_t::boolean).type_name() == "boolean");
09460 CHECK(json(json::value_t::string).type_name() == "string");
09461 CHECK(json(json::value_t::discarded).type_name() == "discarded");
09462 }
09463
09464 SECTION("string escape")
09465 {
09466 CHECK(json::escape_string("\"") == "\\\"");
09467 CHECK(json::escape_string("\\") == "\\\\");
09468 CHECK(json::escape_string("\b") == "\\b");
09469 CHECK(json::escape_string("\f") == "\\f");
09470 CHECK(json::escape_string("\n") == "\\n");
09471 CHECK(json::escape_string("\r") == "\\r");
09472 CHECK(json::escape_string("\t") == "\\t");
09473
09474 CHECK(json::escape_string("\x01") == "\\u0001");
09475 CHECK(json::escape_string("\x02") == "\\u0002");
09476 CHECK(json::escape_string("\x03") == "\\u0003");
09477 CHECK(json::escape_string("\x04") == "\\u0004");
09478 CHECK(json::escape_string("\x05") == "\\u0005");
09479 CHECK(json::escape_string("\x06") == "\\u0006");
09480 CHECK(json::escape_string("\x07") == "\\u0007");
09481 CHECK(json::escape_string("\x08") == "\\b");
09482 CHECK(json::escape_string("\x09") == "\\t");
09483 CHECK(json::escape_string("\x0a") == "\\n");
09484 CHECK(json::escape_string("\x0b") == "\\u000b");
09485 CHECK(json::escape_string("\x0c") == "\\f");
09486 CHECK(json::escape_string("\x0d") == "\\r");
09487 CHECK(json::escape_string("\x0e") == "\\u000e");
09488 CHECK(json::escape_string("\x0f") == "\\u000f");
09489 CHECK(json::escape_string("\x10") == "\\u0010");
09490 CHECK(json::escape_string("\x11") == "\\u0011");
09491 CHECK(json::escape_string("\x12") == "\\u0012");
09492 CHECK(json::escape_string("\x13") == "\\u0013");
09493 CHECK(json::escape_string("\x14") == "\\u0014");
09494 CHECK(json::escape_string("\x15") == "\\u0015");
09495 CHECK(json::escape_string("\x16") == "\\u0016");
09496 CHECK(json::escape_string("\x17") == "\\u0017");
09497 CHECK(json::escape_string("\x18") == "\\u0018");
09498 CHECK(json::escape_string("\x19") == "\\u0019");
09499 CHECK(json::escape_string("\x1a") == "\\u001a");
09500 CHECK(json::escape_string("\x1b") == "\\u001b");
09501 CHECK(json::escape_string("\x1c") == "\\u001c");
09502 CHECK(json::escape_string("\x1d") == "\\u001d");
09503 CHECK(json::escape_string("\x1e") == "\\u001e");
09504 CHECK(json::escape_string("\x1f") == "\\u001f");
09505 }
09506 }
09507
09508 TEST_CASE("lexer class")
09509 {
09510 SECTION("scan")
09511 {
09512 SECTION("structural characters")
09513 {
09514 CHECK(json::lexer("[").scan() == json::lexer::token_type::begin_array);
09515 CHECK(json::lexer("]").scan() == json::lexer::token_type::end_array);
09516 CHECK(json::lexer("{").scan() == json::lexer::token_type::begin_object);
09517 CHECK(json::lexer("}").scan() == json::lexer::token_type::end_object);
09518 CHECK(json::lexer(",").scan() == json::lexer::token_type::value_separator);
09519 CHECK(json::lexer(":").scan() == json::lexer::token_type::name_separator);
09520 }
09521
09522 SECTION("literal names")
09523 {
09524 CHECK(json::lexer("null").scan() == json::lexer::token_type::literal_null);
09525 CHECK(json::lexer("true").scan() == json::lexer::token_type::literal_true);
09526 CHECK(json::lexer("false").scan() == json::lexer::token_type::literal_false);
09527 }
09528
09529 SECTION("numbers")
09530 {
09531 CHECK(json::lexer("0").scan() == json::lexer::token_type::value_number);
09532 CHECK(json::lexer("1").scan() == json::lexer::token_type::value_number);
09533 CHECK(json::lexer("2").scan() == json::lexer::token_type::value_number);
09534 CHECK(json::lexer("3").scan() == json::lexer::token_type::value_number);
09535 CHECK(json::lexer("4").scan() == json::lexer::token_type::value_number);
09536 CHECK(json::lexer("5").scan() == json::lexer::token_type::value_number);
09537 CHECK(json::lexer("6").scan() == json::lexer::token_type::value_number);
09538 CHECK(json::lexer("7").scan() == json::lexer::token_type::value_number);
09539 CHECK(json::lexer("8").scan() == json::lexer::token_type::value_number);
09540 CHECK(json::lexer("9").scan() == json::lexer::token_type::value_number);
09541 }
09542
09543 SECTION("whitespace")
09544 {
09545
09546 CHECK(json::lexer(" ").scan() == json::lexer::token_type::end_of_input);
09547 CHECK(json::lexer("\t").scan() == json::lexer::token_type::end_of_input);
09548 CHECK(json::lexer("\n").scan() == json::lexer::token_type::end_of_input);
09549 CHECK(json::lexer("\r").scan() == json::lexer::token_type::end_of_input);
09550 CHECK(json::lexer(" \t\n\r\n\t ").scan() == json::lexer::token_type::end_of_input);
09551 }
09552 }
09553
09554 SECTION("token_type_name")
09555 {
09556 CHECK(json::lexer::token_type_name(json::lexer::token_type::uninitialized) == "<uninitialized>");
09557 CHECK(json::lexer::token_type_name(json::lexer::token_type::literal_true) == "true literal");
09558 CHECK(json::lexer::token_type_name(json::lexer::token_type::literal_false) == "false literal");
09559 CHECK(json::lexer::token_type_name(json::lexer::token_type::literal_null) == "null literal");
09560 CHECK(json::lexer::token_type_name(json::lexer::token_type::value_string) == "string literal");
09561 CHECK(json::lexer::token_type_name(json::lexer::token_type::value_number) == "number literal");
09562 CHECK(json::lexer::token_type_name(json::lexer::token_type::begin_array) == "'['");
09563 CHECK(json::lexer::token_type_name(json::lexer::token_type::begin_object) == "'{'");
09564 CHECK(json::lexer::token_type_name(json::lexer::token_type::end_array) == "']'");
09565 CHECK(json::lexer::token_type_name(json::lexer::token_type::end_object) == "'}'");
09566 CHECK(json::lexer::token_type_name(json::lexer::token_type::name_separator) == "':'");
09567 CHECK(json::lexer::token_type_name(json::lexer::token_type::value_separator) == "','");
09568 CHECK(json::lexer::token_type_name(json::lexer::token_type::parse_error) == "<parse error>");
09569 CHECK(json::lexer::token_type_name(json::lexer::token_type::end_of_input) == "end of input");
09570 }
09571
09572 SECTION("parse errors on first character")
09573 {
09574 for (int c = 1; c < 128; ++c)
09575 {
09576 auto s = std::string(1, c);
09577
09578 switch (c)
09579 {
09580
09581 case ('['):
09582 case (']'):
09583 case ('{'):
09584 case ('}'):
09585 case (','):
09586 case (':'):
09587 case ('0'):
09588 case ('1'):
09589 case ('2'):
09590 case ('3'):
09591 case ('4'):
09592 case ('5'):
09593 case ('6'):
09594 case ('7'):
09595 case ('8'):
09596 case ('9'):
09597 {
09598 CHECK(json::lexer(s.c_str()).scan() != json::lexer::token_type::parse_error);
09599 break;
09600 }
09601
09602
09603 case (' '):
09604 case ('\t'):
09605 case ('\n'):
09606 case ('\r'):
09607 {
09608 CHECK(json::lexer(s.c_str()).scan() == json::lexer::token_type::end_of_input);
09609 break;
09610 }
09611
09612
09613 default:
09614 {
09615 CHECK(json::lexer(s.c_str()).scan() == json::lexer::token_type::parse_error);
09616 break;
09617 }
09618 }
09619 }
09620 }
09621
09622 SECTION("to_unicode")
09623 {
09624 CHECK(json::lexer::to_unicode(0x1F4A9) == "💩");
09625 CHECK_THROWS_AS(json::lexer::to_unicode(0x200000), std::out_of_range);
09626 CHECK_THROWS_WITH(json::lexer::to_unicode(0x200000), "code points above 0x10FFFF are invalid");
09627 }
09628 }
09629
09630 TEST_CASE("parser class")
09631 {
09632 SECTION("parse")
09633 {
09634 SECTION("null")
09635 {
09636 CHECK(json::parser("null").parse() == json(nullptr));
09637 }
09638
09639 SECTION("true")
09640 {
09641 CHECK(json::parser("true").parse() == json(true));
09642 }
09643
09644 SECTION("false")
09645 {
09646 CHECK(json::parser("false").parse() == json(false));
09647 }
09648
09649 SECTION("array")
09650 {
09651 SECTION("empty array")
09652 {
09653 CHECK(json::parser("[]").parse() == json(json::value_t::array));
09654 CHECK(json::parser("[ ]").parse() == json(json::value_t::array));
09655 }
09656
09657 SECTION("nonempty array")
09658 {
09659 CHECK(json::parser("[true, false, null]").parse() == json({true, false, nullptr}));
09660 }
09661 }
09662
09663 SECTION("object")
09664 {
09665 SECTION("empty object")
09666 {
09667 CHECK(json::parser("{}").parse() == json(json::value_t::object));
09668 CHECK(json::parser("{ }").parse() == json(json::value_t::object));
09669 }
09670
09671 SECTION("nonempty object")
09672 {
09673 CHECK(json::parser("{\"\": true, \"one\": 1, \"two\": null}").parse() == json({{"", true}, {"one", 1}, {"two", nullptr}}));
09674 }
09675 }
09676
09677 SECTION("string")
09678 {
09679
09680 CHECK(json::parser("\"\"").parse() == json(json::value_t::string));
09681
09682 SECTION("errors")
09683 {
09684
09685 CHECK_THROWS_AS(json::parser("\"\t\"").parse(), std::invalid_argument);
09686 CHECK_THROWS_WITH(json::parser("\"\t\"").parse(), "parse error - unexpected '\"'");
09687
09688 CHECK_THROWS_AS(json::parser("\"\n\"").parse(), std::invalid_argument);
09689 CHECK_THROWS_AS(json::parser("\"\r\"").parse(), std::invalid_argument);
09690 CHECK_THROWS_WITH(json::parser("\"\n\"").parse(), "parse error - unexpected '\"'");
09691 CHECK_THROWS_WITH(json::parser("\"\r\"").parse(), "parse error - unexpected '\"'");
09692
09693 CHECK_THROWS_AS(json::parser("\"\b\"").parse(), std::invalid_argument);
09694 CHECK_THROWS_WITH(json::parser("\"\b\"").parse(), "parse error - unexpected '\"'");
09695
09696 CHECK_THROWS_AS(json::parser("\uFF01").parse(), std::invalid_argument);
09697 }
09698
09699 SECTION("escaped")
09700 {
09701
09702 auto r1 = R"("\"")"_json;
09703 CHECK(json::parser("\"\\\"\"").parse() == r1);
09704
09705 auto r2 = R"("\\")"_json;
09706 CHECK(json::parser("\"\\\\\"").parse() == r2);
09707
09708 CHECK(json::parser("\"\\/\"").parse() == R"("/")"_json);
09709
09710 CHECK(json::parser("\"\\b\"").parse() == json("\b"));
09711
09712 CHECK(json::parser("\"\\f\"").parse() == json("\f"));
09713
09714 CHECK(json::parser("\"\\n\"").parse() == json("\n"));
09715
09716 CHECK(json::parser("\"\\r\"").parse() == json("\r"));
09717
09718 CHECK(json::parser("\"\\t\"").parse() == json("\t"));
09719
09720 CHECK(json::parser("\"\\u0001\"").parse().get<json::string_t>() == "\x01");
09721 CHECK(json::parser("\"\\u000a\"").parse().get<json::string_t>() == "\n");
09722 CHECK(json::parser("\"\\u00b0\"").parse().get<json::string_t>() == "°");
09723 CHECK(json::parser("\"\\u0c00\"").parse().get<json::string_t>() == "ఀ");
09724 CHECK(json::parser("\"\\ud000\"").parse().get<json::string_t>() == "퀀");
09725 CHECK(json::parser("\"\\u000E\"").parse().get<json::string_t>() == "\x0E");
09726 CHECK(json::parser("\"\\u00F0\"").parse().get<json::string_t>() == "ð");
09727 CHECK(json::parser("\"\\u0100\"").parse().get<json::string_t>() == "Ā");
09728 CHECK(json::parser("\"\\u2000\"").parse().get<json::string_t>() == " ");
09729 CHECK(json::parser("\"\\uFFFF\"").parse().get<json::string_t>() == "");
09730 CHECK(json::parser("\"\\u20AC\"").parse().get<json::string_t>() == "€");
09731 CHECK(json::parser("\"€\"").parse().get<json::string_t>() == "€");
09732 CHECK(json::parser("\"🎈\"").parse().get<json::string_t>() == "🎈");
09733
09734 CHECK(json::parse("\"\\ud80c\\udc60\"").get<json::string_t>() == u8"\U00013060");
09735 CHECK(json::parse("\"\\ud83c\\udf1e\"").get<json::string_t>() == "🌞");
09736 }
09737 }
09738
09739 SECTION("number")
09740 {
09741 SECTION("integers")
09742 {
09743 SECTION("without exponent")
09744 {
09745 CHECK(json::parser("-128").parse() == json(-128));
09746 CHECK(json::parser("-0").parse() == json(-0));
09747 CHECK(json::parser("0").parse() == json(0));
09748 CHECK(json::parser("128").parse() == json(128));
09749 }
09750
09751 SECTION("with exponent")
09752 {
09753 CHECK(json::parser("0e1").parse() == json(0e1));
09754 CHECK(json::parser("0E1").parse() == json(0e1));
09755
09756 CHECK(json::parser("10000E-4").parse() == json(10000e-4));
09757 CHECK(json::parser("10000E-3").parse() == json(10000e-3));
09758 CHECK(json::parser("10000E-2").parse() == json(10000e-2));
09759 CHECK(json::parser("10000E-1").parse() == json(10000e-1));
09760 CHECK(json::parser("10000E0").parse() == json(10000e0));
09761 CHECK(json::parser("10000E1").parse() == json(10000e1));
09762 CHECK(json::parser("10000E2").parse() == json(10000e2));
09763 CHECK(json::parser("10000E3").parse() == json(10000e3));
09764 CHECK(json::parser("10000E4").parse() == json(10000e4));
09765
09766 CHECK(json::parser("10000e-4").parse() == json(10000e-4));
09767 CHECK(json::parser("10000e-3").parse() == json(10000e-3));
09768 CHECK(json::parser("10000e-2").parse() == json(10000e-2));
09769 CHECK(json::parser("10000e-1").parse() == json(10000e-1));
09770 CHECK(json::parser("10000e0").parse() == json(10000e0));
09771 CHECK(json::parser("10000e1").parse() == json(10000e1));
09772 CHECK(json::parser("10000e2").parse() == json(10000e2));
09773 CHECK(json::parser("10000e3").parse() == json(10000e3));
09774 CHECK(json::parser("10000e4").parse() == json(10000e4));
09775
09776 CHECK(json::parser("-0e1").parse() == json(-0e1));
09777 CHECK(json::parser("-0E1").parse() == json(-0e1));
09778 CHECK(json::parser("-0E123").parse() == json(-0e123));
09779 }
09780
09781 SECTION("edge cases")
09782 {
09783
09784
09785
09786
09787
09788
09789
09790 CHECK(json::parser("-9007199254740991").parse().get<int64_t>() == -9007199254740991);
09791
09792 CHECK(json::parser("9007199254740991").parse().get<int64_t>() == 9007199254740991);
09793 }
09794
09795 SECTION("over the edge cases")
09796 {
09797
09798
09799
09800
09801
09802
09803
09804
09805 CHECK(json::parser("-9223372036854775808").parse().get<int64_t>() == -9223372036854775807 - 1);
09806
09807 CHECK(json::parser("9223372036854775807").parse().get<int64_t>() == 9223372036854775807);
09808
09809 CHECK(json::parser("18446744073709551615").parse().get<uint64_t>() == 18446744073709551615u);
09810 }
09811 }
09812
09813 SECTION("floating-point")
09814 {
09815 SECTION("without exponent")
09816 {
09817 CHECK(json::parser("-128.5").parse() == json(-128.5));
09818 CHECK(json::parser("0.999").parse() == json(0.999));
09819 CHECK(json::parser("128.5").parse() == json(128.5));
09820 CHECK(json::parser("-0.0").parse() == json(-0.0));
09821 }
09822
09823 SECTION("with exponent")
09824 {
09825 CHECK(json::parser("-128.5E3").parse() == json(-128.5E3));
09826 CHECK(json::parser("-128.5E-3").parse() == json(-128.5E-3));
09827 CHECK(json::parser("-0.0e1").parse() == json(-0.0e1));
09828 CHECK(json::parser("-0.0E1").parse() == json(-0.0e1));
09829 }
09830 }
09831
09832 SECTION("invalid numbers")
09833 {
09834 CHECK_THROWS_AS(json::parser("01").parse(), std::invalid_argument);
09835 CHECK_THROWS_AS(json::parser("--1").parse(), std::invalid_argument);
09836 CHECK_THROWS_AS(json::parser("1.").parse(), std::invalid_argument);
09837 CHECK_THROWS_AS(json::parser("1E").parse(), std::invalid_argument);
09838 CHECK_THROWS_AS(json::parser("1E-").parse(), std::invalid_argument);
09839 CHECK_THROWS_AS(json::parser("1.E1").parse(), std::invalid_argument);
09840 CHECK_THROWS_AS(json::parser("-1E").parse(), std::invalid_argument);
09841 CHECK_THROWS_AS(json::parser("-0E#").parse(), std::invalid_argument);
09842 CHECK_THROWS_AS(json::parser("-0E-#").parse(), std::invalid_argument);
09843 CHECK_THROWS_AS(json::parser("-0#").parse(), std::invalid_argument);
09844 CHECK_THROWS_AS(json::parser("-0.0:").parse(), std::invalid_argument);
09845 CHECK_THROWS_AS(json::parser("-0.0Z").parse(), std::invalid_argument);
09846 CHECK_THROWS_AS(json::parser("-0E123:").parse(), std::invalid_argument);
09847 CHECK_THROWS_AS(json::parser("-0e0-:").parse(), std::invalid_argument);
09848 CHECK_THROWS_AS(json::parser("-0e-:").parse(), std::invalid_argument);
09849 CHECK_THROWS_AS(json::parser("-0f").parse(), std::invalid_argument);
09850
09851
09852 CHECK_THROWS_AS(json::parser("+1").parse(), std::invalid_argument);
09853 CHECK_THROWS_AS(json::parser("+0").parse(), std::invalid_argument);
09854
09855 CHECK_THROWS_WITH(json::parser("01").parse(),
09856 "parse error - unexpected number literal; expected end of input");
09857 CHECK_THROWS_WITH(json::parser("--1").parse(), "parse error - unexpected '-'");
09858 CHECK_THROWS_WITH(json::parser("1.").parse(),
09859 "parse error - unexpected '.'; expected end of input");
09860 CHECK_THROWS_WITH(json::parser("1E").parse(),
09861 "parse error - unexpected 'E'; expected end of input");
09862 CHECK_THROWS_WITH(json::parser("1E-").parse(),
09863 "parse error - unexpected 'E'; expected end of input");
09864 CHECK_THROWS_WITH(json::parser("1.E1").parse(),
09865 "parse error - unexpected '.'; expected end of input");
09866 CHECK_THROWS_WITH(json::parser("-1E").parse(),
09867 "parse error - unexpected 'E'; expected end of input");
09868 CHECK_THROWS_WITH(json::parser("-0E#").parse(),
09869 "parse error - unexpected 'E'; expected end of input");
09870 CHECK_THROWS_WITH(json::parser("-0E-#").parse(),
09871 "parse error - unexpected 'E'; expected end of input");
09872 CHECK_THROWS_WITH(json::parser("-0#").parse(),
09873 "parse error - unexpected '#'; expected end of input");
09874 CHECK_THROWS_WITH(json::parser("-0.0:").parse(),
09875 "parse error - unexpected ':'; expected end of input");
09876 CHECK_THROWS_WITH(json::parser("-0.0Z").parse(),
09877 "parse error - unexpected 'Z'; expected end of input");
09878 CHECK_THROWS_WITH(json::parser("-0E123:").parse(),
09879 "parse error - unexpected ':'; expected end of input");
09880 CHECK_THROWS_WITH(json::parser("-0e0-:").parse(),
09881 "parse error - unexpected '-'; expected end of input");
09882 CHECK_THROWS_WITH(json::parser("-0e-:").parse(),
09883 "parse error - unexpected 'e'; expected end of input");
09884 CHECK_THROWS_WITH(json::parser("-0f").parse(),
09885 "parse error - unexpected 'f'; expected end of input");
09886 }
09887 }
09888 }
09889
09890 SECTION("parse errors")
09891 {
09892
09893 CHECK_THROWS_AS(json::parser("0.").parse(), std::invalid_argument);
09894 CHECK_THROWS_AS(json::parser("-").parse(), std::invalid_argument);
09895 CHECK_THROWS_AS(json::parser("--").parse(), std::invalid_argument);
09896 CHECK_THROWS_AS(json::parser("-0.").parse(), std::invalid_argument);
09897 CHECK_THROWS_AS(json::parser("-.").parse(), std::invalid_argument);
09898 CHECK_THROWS_AS(json::parser("-:").parse(), std::invalid_argument);
09899 CHECK_THROWS_AS(json::parser("0.:").parse(), std::invalid_argument);
09900 CHECK_THROWS_AS(json::parser("e.").parse(), std::invalid_argument);
09901 CHECK_THROWS_AS(json::parser("1e.").parse(), std::invalid_argument);
09902 CHECK_THROWS_AS(json::parser("1e/").parse(), std::invalid_argument);
09903 CHECK_THROWS_AS(json::parser("1e:").parse(), std::invalid_argument);
09904 CHECK_THROWS_AS(json::parser("1E.").parse(), std::invalid_argument);
09905 CHECK_THROWS_AS(json::parser("1E/").parse(), std::invalid_argument);
09906 CHECK_THROWS_AS(json::parser("1E:").parse(), std::invalid_argument);
09907 CHECK_THROWS_WITH(json::parser("0.").parse(),
09908 "parse error - unexpected '.'; expected end of input");
09909 CHECK_THROWS_WITH(json::parser("-").parse(), "parse error - unexpected '-'");
09910 CHECK_THROWS_WITH(json::parser("--").parse(),
09911 "parse error - unexpected '-'");
09912 CHECK_THROWS_WITH(json::parser("-0.").parse(),
09913 "parse error - unexpected '.'; expected end of input");
09914 CHECK_THROWS_WITH(json::parser("-.").parse(),
09915 "parse error - unexpected '-'");
09916 CHECK_THROWS_WITH(json::parser("-:").parse(),
09917 "parse error - unexpected '-'");
09918 CHECK_THROWS_WITH(json::parser("0.:").parse(),
09919 "parse error - unexpected '.'; expected end of input");
09920 CHECK_THROWS_WITH(json::parser("e.").parse(),
09921 "parse error - unexpected 'e'");
09922 CHECK_THROWS_WITH(json::parser("1e.").parse(),
09923 "parse error - unexpected 'e'; expected end of input");
09924 CHECK_THROWS_WITH(json::parser("1e/").parse(),
09925 "parse error - unexpected 'e'; expected end of input");
09926 CHECK_THROWS_WITH(json::parser("1e:").parse(),
09927 "parse error - unexpected 'e'; expected end of input");
09928 CHECK_THROWS_WITH(json::parser("1E.").parse(),
09929 "parse error - unexpected 'E'; expected end of input");
09930 CHECK_THROWS_WITH(json::parser("1E/").parse(),
09931 "parse error - unexpected 'E'; expected end of input");
09932 CHECK_THROWS_WITH(json::parser("1E:").parse(),
09933 "parse error - unexpected 'E'; expected end of input");
09934
09935
09936 CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument);
09937 CHECK_THROWS_AS(json::parser("nu").parse(), std::invalid_argument);
09938 CHECK_THROWS_AS(json::parser("nul").parse(), std::invalid_argument);
09939 CHECK_THROWS_WITH(json::parser("n").parse(), "parse error - unexpected 'n'");
09940 CHECK_THROWS_WITH(json::parser("nu").parse(),
09941 "parse error - unexpected 'n'");
09942 CHECK_THROWS_WITH(json::parser("nul").parse(),
09943 "parse error - unexpected 'n'");
09944
09945
09946 CHECK_THROWS_AS(json::parser("t").parse(), std::invalid_argument);
09947 CHECK_THROWS_AS(json::parser("tr").parse(), std::invalid_argument);
09948 CHECK_THROWS_AS(json::parser("tru").parse(), std::invalid_argument);
09949 CHECK_THROWS_WITH(json::parser("t").parse(), "parse error - unexpected 't'");
09950 CHECK_THROWS_WITH(json::parser("tr").parse(),
09951 "parse error - unexpected 't'");
09952 CHECK_THROWS_WITH(json::parser("tru").parse(),
09953 "parse error - unexpected 't'");
09954
09955
09956 CHECK_THROWS_AS(json::parser("f").parse(), std::invalid_argument);
09957 CHECK_THROWS_AS(json::parser("fa").parse(), std::invalid_argument);
09958 CHECK_THROWS_AS(json::parser("fal").parse(), std::invalid_argument);
09959 CHECK_THROWS_AS(json::parser("fals").parse(), std::invalid_argument);
09960 CHECK_THROWS_WITH(json::parser("f").parse(), "parse error - unexpected 'f'");
09961 CHECK_THROWS_WITH(json::parser("fa").parse(),
09962 "parse error - unexpected 'f'");
09963 CHECK_THROWS_WITH(json::parser("fal").parse(),
09964 "parse error - unexpected 'f'");
09965 CHECK_THROWS_WITH(json::parser("fals").parse(),
09966 "parse error - unexpected 'f'");
09967
09968
09969 CHECK_THROWS_AS(json::parser("[").parse(), std::invalid_argument);
09970 CHECK_THROWS_AS(json::parser("[1").parse(), std::invalid_argument);
09971 CHECK_THROWS_AS(json::parser("[1,").parse(), std::invalid_argument);
09972 CHECK_THROWS_AS(json::parser("[1,]").parse(), std::invalid_argument);
09973 CHECK_THROWS_AS(json::parser("]").parse(), std::invalid_argument);
09974 CHECK_THROWS_WITH(json::parser("[").parse(),
09975 "parse error - unexpected end of input");
09976 CHECK_THROWS_WITH(json::parser("[1").parse(),
09977 "parse error - unexpected end of input; expected ']'");
09978 CHECK_THROWS_WITH(json::parser("[1,").parse(),
09979 "parse error - unexpected end of input");
09980 CHECK_THROWS_WITH(json::parser("[1,]").parse(),
09981 "parse error - unexpected ']'");
09982 CHECK_THROWS_WITH(json::parser("]").parse(), "parse error - unexpected ']'");
09983
09984
09985 CHECK_THROWS_AS(json::parser("{").parse(), std::invalid_argument);
09986 CHECK_THROWS_AS(json::parser("{\"foo\"").parse(), std::invalid_argument);
09987 CHECK_THROWS_AS(json::parser("{\"foo\":").parse(), std::invalid_argument);
09988 CHECK_THROWS_AS(json::parser("{\"foo\":}").parse(), std::invalid_argument);
09989 CHECK_THROWS_AS(json::parser("{\"foo\":1,}").parse(), std::invalid_argument);
09990 CHECK_THROWS_AS(json::parser("}").parse(), std::invalid_argument);
09991 CHECK_THROWS_WITH(json::parser("{").parse(),
09992 "parse error - unexpected end of input; expected string literal");
09993 CHECK_THROWS_WITH(json::parser("{\"foo\"").parse(),
09994 "parse error - unexpected end of input; expected ':'");
09995 CHECK_THROWS_WITH(json::parser("{\"foo\":").parse(),
09996 "parse error - unexpected end of input");
09997 CHECK_THROWS_WITH(json::parser("{\"foo\":}").parse(),
09998 "parse error - unexpected '}'");
09999 CHECK_THROWS_WITH(json::parser("{\"foo\":1,}").parse(),
10000 "parse error - unexpected '}'; expected string literal");
10001 CHECK_THROWS_WITH(json::parser("}").parse(), "parse error - unexpected '}'");
10002
10003
10004 CHECK_THROWS_AS(json::parser("\"").parse(), std::invalid_argument);
10005 CHECK_THROWS_AS(json::parser("\"\\\"").parse(), std::invalid_argument);
10006 CHECK_THROWS_AS(json::parser("\"\\u\"").parse(), std::invalid_argument);
10007 CHECK_THROWS_AS(json::parser("\"\\u0\"").parse(), std::invalid_argument);
10008 CHECK_THROWS_AS(json::parser("\"\\u01\"").parse(), std::invalid_argument);
10009 CHECK_THROWS_AS(json::parser("\"\\u012\"").parse(), std::invalid_argument);
10010 CHECK_THROWS_WITH(json::parser("\"").parse(),
10011 "parse error - unexpected '\"'");
10012 CHECK_THROWS_WITH(json::parser("\"\\\"").parse(),
10013 "parse error - unexpected '\"'");
10014 CHECK_THROWS_WITH(json::parser("\"\\u\"").parse(),
10015 "parse error - unexpected '\"'");
10016 CHECK_THROWS_WITH(json::parser("\"\\u0\"").parse(),
10017 "parse error - unexpected '\"'");
10018 CHECK_THROWS_WITH(json::parser("\"\\u01\"").parse(),
10019 "parse error - unexpected '\"'");
10020 CHECK_THROWS_WITH(json::parser("\"\\u012\"").parse(),
10021 "parse error - unexpected '\"'");
10022
10023
10024 for (int c = 1; c < 128; ++c)
10025 {
10026 auto s = std::string("\"\\") + std::string(1, c) + "\"";
10027
10028 switch (c)
10029 {
10030
10031 case ('"'):
10032 case ('\\'):
10033 case ('/'):
10034 case ('b'):
10035 case ('f'):
10036 case ('n'):
10037 case ('r'):
10038 case ('t'):
10039 {
10040 CHECK_NOTHROW(json::parser(s).parse());
10041 break;
10042 }
10043
10044
10045 case ('u'):
10046 {
10047 break;
10048 }
10049
10050
10051 default:
10052 {
10053 CHECK_THROWS_AS(json::parser(s).parse(), std::invalid_argument);
10054 CHECK_THROWS_WITH(json::parser(s).parse(), "parse error - unexpected '\"'");
10055 break;
10056 }
10057 }
10058 }
10059
10060
10061 {
10062
10063 const auto valid = [](int c)
10064 {
10065 switch (c)
10066 {
10067 case ('0'):
10068 case ('1'):
10069 case ('2'):
10070 case ('3'):
10071 case ('4'):
10072 case ('5'):
10073 case ('6'):
10074 case ('7'):
10075 case ('8'):
10076 case ('9'):
10077 case ('a'):
10078 case ('b'):
10079 case ('c'):
10080 case ('d'):
10081 case ('e'):
10082 case ('f'):
10083 case ('A'):
10084 case ('B'):
10085 case ('C'):
10086 case ('D'):
10087 case ('E'):
10088 case ('F'):
10089 {
10090 return true;
10091 }
10092
10093 default:
10094 {
10095 return false;
10096 }
10097 }
10098 };
10099
10100 for (int c = 1; c < 128; ++c)
10101 {
10102 std::string s = "\"\\u";
10103
10104
10105 auto s1 = s + "000" + std::string(1, c) + "\"";
10106 auto s2 = s + "00" + std::string(1, c) + "0\"";
10107 auto s3 = s + "0" + std::string(1, c) + "00\"";
10108 auto s4 = s + std::string(1, c) + "000\"";
10109
10110 if (valid(c))
10111 {
10112 CHECK_NOTHROW(json::parser(s1).parse());
10113 CHECK_NOTHROW(json::parser(s2).parse());
10114 CHECK_NOTHROW(json::parser(s3).parse());
10115 CHECK_NOTHROW(json::parser(s4).parse());
10116 }
10117 else
10118 {
10119 CHECK_THROWS_AS(json::parser(s1).parse(), std::invalid_argument);
10120 CHECK_THROWS_AS(json::parser(s2).parse(), std::invalid_argument);
10121 CHECK_THROWS_AS(json::parser(s3).parse(), std::invalid_argument);
10122 CHECK_THROWS_AS(json::parser(s4).parse(), std::invalid_argument);
10123
10124 CHECK_THROWS_WITH(json::parser(s1).parse(), "parse error - unexpected '\"'");
10125 CHECK_THROWS_WITH(json::parser(s2).parse(), "parse error - unexpected '\"'");
10126 CHECK_THROWS_WITH(json::parser(s3).parse(), "parse error - unexpected '\"'");
10127 CHECK_THROWS_WITH(json::parser(s4).parse(), "parse error - unexpected '\"'");
10128 }
10129 }
10130 }
10131
10132
10133 CHECK_THROWS_AS(json::parse("\"\\uD80C\""), std::invalid_argument);
10134 CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), "missing low surrogate");
10135
10136 CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), std::invalid_argument);
10137 CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), std::invalid_argument);
10138 CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), std::invalid_argument);
10139 CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""),
10140 "missing or wrong low surrogate");
10141 CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""),
10142 "missing or wrong low surrogate");
10143 CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""),
10144 "missing or wrong low surrogate");
10145 }
10146
10147 SECTION("callback function")
10148 {
10149 auto s_object = R"(
10150 {
10151 "foo": 2,
10152 "bar": {
10153 "baz": 1
10154 }
10155 }
10156 )";
10157
10158 auto s_array = R"(
10159 [1,2,[3,4,5],4,5]
10160 )";
10161
10162 SECTION("filter nothing")
10163 {
10164 json j_object = json::parse(s_object, [](int, json::parse_event_t, const json&)
10165 {
10166 return true;
10167 });
10168
10169 CHECK (j_object == json({{"foo", 2}, {"bar", {{"baz", 1}}}}));
10170
10171 json j_array = json::parse(s_array, [](int, json::parse_event_t, const json&)
10172 {
10173 return true;
10174 });
10175
10176 CHECK (j_array == json({1, 2, {3, 4, 5}, 4, 5}));
10177 }
10178
10179 SECTION("filter everything")
10180 {
10181 json j_object = json::parse(s_object, [](int, json::parse_event_t, const json&)
10182 {
10183 return false;
10184 });
10185
10186
10187 CHECK (j_object.is_null());
10188
10189 json j_array = json::parse(s_array, [](int, json::parse_event_t, const json&)
10190 {
10191 return false;
10192 });
10193
10194
10195 CHECK (j_array.is_null());
10196 }
10197
10198 SECTION("filter specific element")
10199 {
10200 json j_object = json::parse(s_object, [](int, json::parse_event_t, const json & j)
10201 {
10202
10203 if (j == json(2))
10204 {
10205 return false;
10206 }
10207 else
10208 {
10209 return true;
10210 }
10211 });
10212
10213 CHECK (j_object == json({{"bar", {{"baz", 1}}}}));
10214
10215 json j_array = json::parse(s_array, [](int, json::parse_event_t, const json & j)
10216 {
10217 if (j == json(2))
10218 {
10219 return false;
10220 }
10221 else
10222 {
10223 return true;
10224 }
10225 });
10226
10227 CHECK (j_array == json({1, {3, 4, 5}, 4, 5}));
10228 }
10229
10230 SECTION("filter specific events")
10231 {
10232 SECTION("first closing event")
10233 {
10234 {
10235 json j_object = json::parse(s_object, [](int, json::parse_event_t e, const json&)
10236 {
10237 static bool first = true;
10238 if (e == json::parse_event_t::object_end and first)
10239 {
10240 first = false;
10241 return false;
10242 }
10243 else
10244 {
10245 return true;
10246 }
10247 });
10248
10249
10250 CHECK (j_object == json({{"foo", 2}}));
10251 }
10252
10253 {
10254 json j_array = json::parse(s_array, [](int, json::parse_event_t e, const json&)
10255 {
10256 static bool first = true;
10257 if (e == json::parse_event_t::array_end and first)
10258 {
10259 first = false;
10260 return false;
10261 }
10262 else
10263 {
10264 return true;
10265 }
10266 });
10267
10268
10269 CHECK (j_array == json({1, 2, 4, 5}));
10270 }
10271 }
10272 }
10273
10274 SECTION("special cases")
10275 {
10276
10277
10278
10279
10280 json j_empty_object = json::parse("{}", [](int, json::parse_event_t e, const json&)
10281 {
10282 if (e == json::parse_event_t::object_end)
10283 {
10284 return false;
10285 }
10286 else
10287 {
10288 return true;
10289 }
10290 });
10291 CHECK(j_empty_object == json());
10292
10293 json j_empty_array = json::parse("[]", [](int, json::parse_event_t e, const json&)
10294 {
10295 if (e == json::parse_event_t::array_end)
10296 {
10297 return false;
10298 }
10299 else
10300 {
10301 return true;
10302 }
10303 });
10304 CHECK(j_empty_array == json());
10305 }
10306 }
10307 }
10308
10309 TEST_CASE("README", "[hide]")
10310 {
10311 {
10312
10313 json j;
10314
10315
10316 j["pi"] = 3.141;
10317
10318
10319 j["happy"] = true;
10320
10321
10322 j["name"] = "Niels";
10323
10324
10325 j["nothing"] = nullptr;
10326
10327
10328 j["answer"]["everything"] = 42;
10329
10330
10331 j["list"] = { 1, 0, 2 };
10332
10333
10334 j["object"] = { {"currency", "USD"}, {"value", 42.99} };
10335
10336
10337 json j2 =
10338 {
10339 {"pi", 3.141},
10340 {"happy", true},
10341 {"name", "Niels"},
10342 {"nothing", nullptr},
10343 {
10344 "answer", {
10345 {"everything", 42}
10346 }
10347 },
10348 {"list", {1, 0, 2}},
10349 {
10350 "object", {
10351 {"currency", "USD"},
10352 {"value", 42.99}
10353 }
10354 }
10355 };
10356 }
10357
10358 {
10359
10360 json empty_array_implicit = {{}};
10361 json empty_array_explicit = json::array();
10362
10363
10364 json empty_object_explicit = json::object();
10365
10366
10367 json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) };
10368 }
10369
10370 {
10371
10372 json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
10373
10374
10375 auto j2 = R"(
10376 {
10377 "happy": true,
10378 "pi": 3.141
10379 }
10380 )"_json;
10381
10382
10383 auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
10384
10385
10386 std::string s = j.dump();
10387
10388
10389
10390 std::cout << j.dump(4) << std::endl;
10391
10392
10393
10394
10395
10396 std::cout << std::setw(2) << j << std::endl;
10397 }
10398
10399 {
10400
10401 json j;
10402 j.push_back("foo");
10403 j.push_back(1);
10404 j.push_back(true);
10405
10406
10407 for (json::iterator it = j.begin(); it != j.end(); ++it)
10408 {
10409 std::cout << *it << '\n';
10410 }
10411
10412
10413 for (auto element : j)
10414 {
10415 std::cout << element << '\n';
10416 }
10417
10418
10419 const std::string tmp = j[0];
10420 j[1] = 42;
10421 bool foo = j.at(2);
10422
10423
10424 j.size();
10425 j.empty();
10426 j.type();
10427 j.clear();
10428
10429
10430 j == "[\"foo\", 1, true]"_json;
10431
10432
10433 json o;
10434 o["foo"] = 23;
10435 o["bar"] = false;
10436 o["baz"] = 3.141;
10437
10438
10439 if (o.find("foo") != o.end())
10440 {
10441
10442 }
10443 }
10444
10445 {
10446 std::vector<int> c_vector {1, 2, 3, 4};
10447 json j_vec(c_vector);
10448
10449
10450 std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};
10451 json j_deque(c_deque);
10452
10453
10454 std::list<bool> c_list {true, true, false, true};
10455 json j_list(c_list);
10456
10457
10458 std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
10459 json j_flist(c_flist);
10460
10461
10462 std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
10463 json j_array(c_array);
10464
10465
10466 std::set<std::string> c_set {"one", "two", "three", "four", "one"};
10467 json j_set(c_set);
10468
10469
10470 std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
10471 json j_uset(c_uset);
10472
10473
10474 std::multiset<std::string> c_mset {"one", "two", "one", "four"};
10475 json j_mset(c_mset);
10476
10477
10478 std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
10479 json j_umset(c_umset);
10480
10481 }
10482
10483 {
10484 std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
10485 json j_map(c_map);
10486
10487
10488 std::unordered_map<const char*, float> c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
10489 json j_umap(c_umap);
10490
10491
10492 std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
10493 json j_mmap(c_mmap);
10494
10495
10496 std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
10497 json j_ummap(c_ummap);
10498
10499 }
10500
10501 {
10502
10503 std::string s1 = "Hello, world!";
10504 json js = s1;
10505 std::string s2 = js;
10506
10507
10508 bool b1 = true;
10509 json jb = b1;
10510 bool b2 = jb;
10511
10512
10513 int i = 42;
10514 json jn = i;
10515 double f = jn;
10516
10517
10518
10519 std::string vs = js.get<std::string>();
10520 bool vb = jb.get<bool>();
10521 int vi = jn.get<int>();
10522
10523
10524 }
10525
10526 {
10527
10528 json j_original = R"({
10529 "baz": ["one", "two", "three"],
10530 "foo": "bar"
10531 })"_json;
10532
10533
10534 j_original["/baz/2"_json_pointer];
10535
10536
10537
10538 json j_patch = R"([
10539 { "op": "replace", "path": "/baz", "value": "boo" },
10540 { "op": "add", "path": "/hello", "value": ["world"] },
10541 { "op": "remove", "path": "/foo"}
10542 ])"_json;
10543
10544
10545 json j_result = j_original.patch(j_patch);
10546
10547
10548
10549
10550
10551
10552 json::diff(j_result, j_original);
10553
10554
10555
10556
10557
10558 }
10559 }
10560
10561 TEST_CASE("algorithms")
10562 {
10563 json j_array = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz"};
10564 json j_object = {{"one", 1}, {"two", 2}};
10565
10566 SECTION("non-modifying sequence operations")
10567 {
10568 SECTION("std::all_of")
10569 {
10570 CHECK(std::all_of(j_array.begin(), j_array.end(), [](const json & value)
10571 {
10572 return value.size() > 0;
10573 }));
10574 CHECK(std::all_of(j_object.begin(), j_object.end(), [](const json & value)
10575 {
10576 return value.type() == json::value_t::number_integer;
10577 }));
10578 }
10579
10580 SECTION("std::any_of")
10581 {
10582 CHECK(std::any_of(j_array.begin(), j_array.end(), [](const json & value)
10583 {
10584 return value.is_string() and value.get<std::string>() == "foo";
10585 }));
10586 CHECK(std::any_of(j_object.begin(), j_object.end(), [](const json & value)
10587 {
10588 return value.get<int>() > 1;
10589 }));
10590 }
10591
10592 SECTION("std::none_of")
10593 {
10594 CHECK(std::none_of(j_array.begin(), j_array.end(), [](const json & value)
10595 {
10596 return value.size() == 0;
10597 }));
10598 CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json & value)
10599 {
10600 return value.get<int>() <= 0;
10601 }));
10602 }
10603
10604 SECTION("std::for_each")
10605 {
10606 SECTION("reading")
10607 {
10608 int sum = 0;
10609
10610 std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value)
10611 {
10612 if (value.is_number())
10613 {
10614 sum += static_cast<int>(value);
10615 }
10616 });
10617
10618 CHECK(sum == 45);
10619 }
10620
10621 SECTION("writing")
10622 {
10623 auto add17 = [](json & value)
10624 {
10625 if (value.is_array())
10626 {
10627 value.push_back(17);
10628 }
10629 };
10630
10631 std::for_each(j_array.begin(), j_array.end(), add17);
10632
10633 CHECK(j_array[6] == json({1, 2, 3, 17}));
10634 }
10635 }
10636
10637 SECTION("std::count")
10638 {
10639 CHECK(std::count(j_array.begin(), j_array.end(), json(true)) == 1);
10640 }
10641
10642 SECTION("std::count_if")
10643 {
10644 CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json & value)
10645 {
10646 return (value.is_number());
10647 }) == 3);
10648 CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&)
10649 {
10650 return true;
10651 }) == 9);
10652 }
10653
10654 SECTION("std::mismatch")
10655 {
10656 json j_array2 = {13, 29, 3, {{"one", 1}, {"two", 2}, {"three", 3}}, true, false, {1, 2, 3}, "foo", "baz"};
10657 auto res = std::mismatch(j_array.begin(), j_array.end(), j_array2.begin());
10658 CHECK(*res.first == json({{"one", 1}, {"two", 2}}));
10659 CHECK(*res.second == json({{"one", 1}, {"two", 2}, {"three", 3}}));
10660 }
10661
10662 SECTION("std::equal")
10663 {
10664 SECTION("using operator==")
10665 {
10666 CHECK(std::equal(j_array.begin(), j_array.end(), j_array.begin()));
10667 CHECK(std::equal(j_object.begin(), j_object.end(), j_object.begin()));
10668 CHECK(not std::equal(j_array.begin(), j_array.end(), j_object.begin()));
10669 }
10670
10671 SECTION("using user-defined comparison")
10672 {
10673
10674 json j_array2 = {13, 29, 3, {"Hello", "World"}, true, false, {{"one", 1}, {"two", 2}, {"three", 3}}, "foo", "baz"};
10675 CHECK(not std::equal(j_array.begin(), j_array.end(), j_array2.begin()));
10676 CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(),
10677 [](const json & a, const json & b)
10678 {
10679 return (a.size() == b.size());
10680 }));
10681 }
10682 }
10683
10684 SECTION("std::find")
10685 {
10686 auto it = std::find(j_array.begin(), j_array.end(), json(false));
10687 CHECK(std::distance(j_array.begin(), it) == 5);
10688 }
10689
10690 SECTION("std::find_if")
10691 {
10692 auto it = std::find_if(j_array.begin(), j_array.end(),
10693 [](const json & value)
10694 {
10695 return value.is_boolean();
10696 });
10697 CHECK(std::distance(j_array.begin(), it) == 4);
10698 }
10699
10700 SECTION("std::find_if_not")
10701 {
10702 auto it = std::find_if_not(j_array.begin(), j_array.end(),
10703 [](const json & value)
10704 {
10705 return value.is_number();
10706 });
10707 CHECK(std::distance(j_array.begin(), it) == 3);
10708 }
10709
10710 SECTION("std::adjacent_find")
10711 {
10712 CHECK(std::adjacent_find(j_array.begin(), j_array.end()) == j_array.end());
10713 CHECK(std::adjacent_find(j_array.begin(), j_array.end(),
10714 [](const json & v1, const json & v2)
10715 {
10716 return v1.type() == v2.type();
10717 }) == j_array.begin());
10718 }
10719 }
10720
10721 SECTION("modifying sequence operations")
10722 {
10723 SECTION("std::reverse")
10724 {
10725 std::reverse(j_array.begin(), j_array.end());
10726 CHECK(j_array == json({"baz", "foo", {1, 2, 3}, false, true, {{"one", 1}, {"two", 2}}, 3, 29, 13}));
10727 }
10728
10729 SECTION("std::rotate")
10730 {
10731 std::rotate(j_array.begin(), j_array.begin() + 1, j_array.end());
10732 CHECK(j_array == json({29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", 13}));
10733 }
10734
10735 SECTION("std::partition")
10736 {
10737 auto it = std::partition(j_array.begin(), j_array.end(), [](const json & v)
10738 {
10739 return v.is_string();
10740 });
10741 CHECK(std::distance(j_array.begin(), it) == 2);
10742 CHECK(not it[2].is_string());
10743 }
10744 }
10745
10746 SECTION("sorting operations")
10747 {
10748 SECTION("std::sort")
10749 {
10750 SECTION("with standard comparison")
10751 {
10752 json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
10753 std::sort(j.begin(), j.end());
10754 CHECK(j == json({nullptr, false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
10755 }
10756
10757 SECTION("with user-defined comparison")
10758 {
10759 json j = {3, {{"one", 1}, {"two", 2}}, {1, 2, 3}, nullptr};
10760 std::sort(j.begin(), j.end(), [](const json & a, const json & b)
10761 {
10762 return a.size() < b.size();
10763 });
10764 CHECK(j == json({nullptr, 3, {{"one", 1}, {"two", 2}}, {1, 2, 3}}));
10765 }
10766
10767 SECTION("sorting an object")
10768 {
10769 json j({{"one", 1}, {"two", 2}});
10770 CHECK_THROWS_AS(std::sort(j.begin(), j.end()), std::domain_error);
10771 CHECK_THROWS_WITH(std::sort(j.begin(), j.end()), "cannot use offsets with object iterators");
10772 }
10773 }
10774
10775 SECTION("std::partial_sort")
10776 {
10777 json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
10778 std::partial_sort(j.begin(), j.begin() + 4, j.end());
10779 CHECK(j == json({nullptr, false, true, 3, {{"one", 1}, {"two", 2}}, 29, {1, 2, 3}, "foo", "baz", 13}));
10780 }
10781 }
10782
10783 SECTION("set operations")
10784 {
10785 SECTION("std::merge")
10786 {
10787 {
10788 json j1 = {2, 4, 6, 8};
10789 json j2 = {1, 2, 3, 5, 7};
10790 json j3;
10791
10792 std::merge(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
10793 CHECK(j3 == json({1, 2, 2, 3, 4, 5, 6, 7, 8}));
10794 }
10795 }
10796
10797 SECTION("std::set_difference")
10798 {
10799 json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
10800 json j2 = {1, 2, 3, 5, 7};
10801 json j3;
10802
10803 std::set_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
10804 CHECK(j3 == json({4, 6, 8}));
10805 }
10806
10807 SECTION("std::set_intersection")
10808 {
10809 json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
10810 json j2 = {1, 2, 3, 5, 7};
10811 json j3;
10812
10813 std::set_intersection(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
10814 CHECK(j3 == json({1, 2, 3, 5, 7}));
10815 }
10816
10817 SECTION("std::set_union")
10818 {
10819 json j1 = {2, 4, 6, 8};
10820 json j2 = {1, 2, 3, 5, 7};
10821 json j3;
10822
10823 std::set_union(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
10824 CHECK(j3 == json({1, 2, 3, 4, 5, 6, 7, 8}));
10825 }
10826
10827 SECTION("std::set_symmetric_difference")
10828 {
10829 json j1 = {2, 4, 6, 8};
10830 json j2 = {1, 2, 3, 5, 7};
10831 json j3;
10832
10833 std::set_symmetric_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
10834 CHECK(j3 == json({1, 3, 4, 5, 6, 7, 8}));
10835 }
10836 }
10837
10838 SECTION("heap operations")
10839 {
10840 std::make_heap(j_array.begin(), j_array.end());
10841 CHECK(std::is_heap(j_array.begin(), j_array.end()));
10842 std::sort_heap(j_array.begin(), j_array.end());
10843 CHECK(j_array == json({false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
10844 }
10845 }
10846
10847 TEST_CASE("concepts")
10848 {
10849 SECTION("container requirements for json")
10850 {
10851
10852
10853
10854
10855
10856
10857
10858 CHECK((std::is_same<json::value_type, json>::value));
10859
10860
10861 CHECK((std::is_same<json::reference, json&>::value));
10862
10863
10864 CHECK((std::is_same<json::const_reference, const json&>::value));
10865
10866
10867 CHECK((std::is_same<json::iterator::value_type, json>::value));
10868
10869 CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::iterator>::iterator_category>::value));
10870
10871 CHECK((std::is_convertible<json::iterator, json::const_iterator>::value));
10872
10873
10874 CHECK((std::is_same<json::const_iterator::value_type, json>::value));
10875
10876 CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::const_iterator>::iterator_category>::value));
10877
10878
10879 CHECK((std::is_signed<json::difference_type>::value));
10880
10881 CHECK((std::is_same<json::difference_type, json::iterator::difference_type>::value));
10882
10883 CHECK((std::is_same<json::difference_type, json::const_iterator::difference_type>::value));
10884
10885
10886 CHECK((std::is_unsigned<json::size_type>::value));
10887
10888 CHECK(std::numeric_limits<json::difference_type>::max() <=
10889 std::numeric_limits<json::size_type>::max());
10890
10891
10892 {
10893 json u;
10894 CHECK(u.empty());
10895 }
10896
10897
10898 CHECK(json().empty());
10899 }
10900
10901 SECTION("class json")
10902 {
10903 SECTION("DefaultConstructible")
10904 {
10905 CHECK(std::is_nothrow_default_constructible<json>::value);
10906 }
10907
10908 SECTION("MoveConstructible")
10909 {
10910 CHECK(std::is_nothrow_move_constructible<json>::value);
10911 }
10912
10913 SECTION("CopyConstructible")
10914 {
10915 CHECK(std::is_copy_constructible<json>::value);
10916 }
10917
10918 SECTION("MoveAssignable")
10919 {
10920 CHECK(std::is_nothrow_move_assignable<json>::value);
10921 }
10922
10923 SECTION("CopyAssignable")
10924 {
10925 CHECK(std::is_copy_assignable<json>::value);
10926 }
10927
10928 SECTION("Destructible")
10929 {
10930 CHECK(std::is_nothrow_destructible<json>::value);
10931 }
10932
10933 SECTION("StandardLayoutType")
10934 {
10935 CHECK(std::is_standard_layout<json>::value);
10936 }
10937 }
10938
10939 SECTION("class iterator")
10940 {
10941 SECTION("CopyConstructible")
10942 {
10943 CHECK(std::is_nothrow_copy_constructible<json::iterator>::value);
10944 CHECK(std::is_nothrow_copy_constructible<json::const_iterator>::value);
10945 }
10946
10947 SECTION("CopyAssignable")
10948 {
10949
10950 #if !defined(_MSC_VER) || (_ITERATOR_DEBUG_LEVEL == 0)
10951 CHECK(std::is_nothrow_copy_assignable<json::iterator>::value);
10952 CHECK(std::is_nothrow_copy_assignable<json::const_iterator>::value);
10953 #endif
10954 }
10955
10956 SECTION("Destructible")
10957 {
10958 CHECK(std::is_nothrow_destructible<json::iterator>::value);
10959 CHECK(std::is_nothrow_destructible<json::const_iterator>::value);
10960 }
10961
10962 SECTION("Swappable")
10963 {
10964 {
10965 json j {1, 2, 3};
10966 json::iterator it1 = j.begin();
10967 json::iterator it2 = j.end();
10968 std::swap(it1, it2);
10969 CHECK(it1 == j.end());
10970 CHECK(it2 == j.begin());
10971 }
10972 {
10973 json j {1, 2, 3};
10974 json::const_iterator it1 = j.cbegin();
10975 json::const_iterator it2 = j.cend();
10976 std::swap(it1, it2);
10977 CHECK(it1 == j.end());
10978 CHECK(it2 == j.begin());
10979 }
10980 }
10981 }
10982 }
10983
10984 TEST_CASE("iterator_wrapper")
10985 {
10986 SECTION("object")
10987 {
10988 SECTION("value")
10989 {
10990 json j = {{"A", 1}, {"B", 2}};
10991 int counter = 1;
10992
10993 for (auto i : json::iterator_wrapper(j))
10994 {
10995 switch (counter++)
10996 {
10997 case 1:
10998 {
10999 CHECK(i.key() == "A");
11000 CHECK(i.value() == json(1));
11001 break;
11002 }
11003
11004 case 2:
11005 {
11006 CHECK(i.key() == "B");
11007 CHECK(i.value() == json(2));
11008 break;
11009 }
11010
11011 default:
11012 {
11013 break;
11014 }
11015 }
11016 }
11017
11018 CHECK(counter == 3);
11019 }
11020
11021 SECTION("reference")
11022 {
11023 json j = {{"A", 1}, {"B", 2}};
11024 int counter = 1;
11025
11026 for (auto& i : json::iterator_wrapper(j))
11027 {
11028 switch (counter++)
11029 {
11030 case 1:
11031 {
11032 CHECK(i.key() == "A");
11033 CHECK(i.value() == json(1));
11034
11035
11036 i.value() = json(11);
11037 CHECK(i.value() == json(11));
11038 break;
11039 }
11040
11041 case 2:
11042 {
11043 CHECK(i.key() == "B");
11044 CHECK(i.value() == json(2));
11045
11046
11047 i.value() = json(22);
11048 CHECK(i.value() == json(22));
11049 break;
11050 }
11051
11052 default:
11053 {
11054 break;
11055 }
11056 }
11057 }
11058
11059 CHECK(counter == 3);
11060
11061
11062 CHECK(j == json({{"A", 11}, {"B", 22}}));
11063 }
11064
11065 SECTION("const value")
11066 {
11067 json j = {{"A", 1}, {"B", 2}};
11068 int counter = 1;
11069
11070 for (const auto i : json::iterator_wrapper(j))
11071 {
11072 switch (counter++)
11073 {
11074 case 1:
11075 {
11076 CHECK(i.key() == "A");
11077 CHECK(i.value() == json(1));
11078 break;
11079 }
11080
11081 case 2:
11082 {
11083 CHECK(i.key() == "B");
11084 CHECK(i.value() == json(2));
11085 break;
11086 }
11087
11088 default:
11089 {
11090 break;
11091 }
11092 }
11093 }
11094
11095 CHECK(counter == 3);
11096 }
11097
11098 SECTION("const reference")
11099 {
11100 json j = {{"A", 1}, {"B", 2}};
11101 int counter = 1;
11102
11103 for (const auto& i : json::iterator_wrapper(j))
11104 {
11105 switch (counter++)
11106 {
11107 case 1:
11108 {
11109 CHECK(i.key() == "A");
11110 CHECK(i.value() == json(1));
11111 break;
11112 }
11113
11114 case 2:
11115 {
11116 CHECK(i.key() == "B");
11117 CHECK(i.value() == json(2));
11118 break;
11119 }
11120
11121 default:
11122 {
11123 break;
11124 }
11125 }
11126 }
11127
11128 CHECK(counter == 3);
11129 }
11130 }
11131
11132 SECTION("const object")
11133 {
11134 SECTION("value")
11135 {
11136 const json j = {{"A", 1}, {"B", 2}};
11137 int counter = 1;
11138
11139 for (auto i : json::iterator_wrapper(j))
11140 {
11141 switch (counter++)
11142 {
11143 case 1:
11144 {
11145 CHECK(i.key() == "A");
11146 CHECK(i.value() == json(1));
11147 break;
11148 }
11149
11150 case 2:
11151 {
11152 CHECK(i.key() == "B");
11153 CHECK(i.value() == json(2));
11154 break;
11155 }
11156
11157 default:
11158 {
11159 break;
11160 }
11161 }
11162 }
11163
11164 CHECK(counter == 3);
11165 }
11166
11167 SECTION("reference")
11168 {
11169 const json j = {{"A", 1}, {"B", 2}};
11170 int counter = 1;
11171
11172 for (auto& i : json::iterator_wrapper(j))
11173 {
11174 switch (counter++)
11175 {
11176 case 1:
11177 {
11178 CHECK(i.key() == "A");
11179 CHECK(i.value() == json(1));
11180 break;
11181 }
11182
11183 case 2:
11184 {
11185 CHECK(i.key() == "B");
11186 CHECK(i.value() == json(2));
11187 break;
11188 }
11189
11190 default:
11191 {
11192 break;
11193 }
11194 }
11195 }
11196
11197 CHECK(counter == 3);
11198 }
11199
11200 SECTION("const value")
11201 {
11202 const json j = {{"A", 1}, {"B", 2}};
11203 int counter = 1;
11204
11205 for (const auto i : json::iterator_wrapper(j))
11206 {
11207 switch (counter++)
11208 {
11209 case 1:
11210 {
11211 CHECK(i.key() == "A");
11212 CHECK(i.value() == json(1));
11213 break;
11214 }
11215
11216 case 2:
11217 {
11218 CHECK(i.key() == "B");
11219 CHECK(i.value() == json(2));
11220 break;
11221 }
11222
11223 default:
11224 {
11225 break;
11226 }
11227 }
11228 }
11229
11230 CHECK(counter == 3);
11231 }
11232
11233 SECTION("const reference")
11234 {
11235 const json j = {{"A", 1}, {"B", 2}};
11236 int counter = 1;
11237
11238 for (const auto& i : json::iterator_wrapper(j))
11239 {
11240 switch (counter++)
11241 {
11242 case 1:
11243 {
11244 CHECK(i.key() == "A");
11245 CHECK(i.value() == json(1));
11246 break;
11247 }
11248
11249 case 2:
11250 {
11251 CHECK(i.key() == "B");
11252 CHECK(i.value() == json(2));
11253 break;
11254 }
11255
11256 default:
11257 {
11258 break;
11259 }
11260 }
11261 }
11262
11263 CHECK(counter == 3);
11264 }
11265 }
11266
11267 SECTION("array")
11268 {
11269 SECTION("value")
11270 {
11271 json j = {"A", "B"};
11272 int counter = 1;
11273
11274 for (auto i : json::iterator_wrapper(j))
11275 {
11276 switch (counter++)
11277 {
11278 case 1:
11279 {
11280 CHECK(i.key() == "0");
11281 CHECK(i.value() == "A");
11282 break;
11283 }
11284
11285 case 2:
11286 {
11287 CHECK(i.key() == "1");
11288 CHECK(i.value() == "B");
11289 break;
11290 }
11291
11292 default:
11293 {
11294 break;
11295 }
11296 }
11297 }
11298
11299 CHECK(counter == 3);
11300 }
11301
11302 SECTION("reference")
11303 {
11304 json j = {"A", "B"};
11305 int counter = 1;
11306
11307 for (auto& i : json::iterator_wrapper(j))
11308 {
11309 switch (counter++)
11310 {
11311 case 1:
11312 {
11313 CHECK(i.key() == "0");
11314 CHECK(i.value() == "A");
11315
11316
11317 i.value() = "AA";
11318 CHECK(i.value() == "AA");
11319 break;
11320 }
11321
11322 case 2:
11323 {
11324 CHECK(i.key() == "1");
11325 CHECK(i.value() == "B");
11326
11327
11328 i.value() = "BB";
11329 CHECK(i.value() == "BB");
11330 break;
11331 }
11332
11333 default:
11334 {
11335 break;
11336 }
11337 }
11338 }
11339
11340 CHECK(counter == 3);
11341
11342
11343 CHECK(j == json({"AA", "BB"}));
11344 }
11345
11346 SECTION("const value")
11347 {
11348 json j = {"A", "B"};
11349 int counter = 1;
11350
11351 for (const auto i : json::iterator_wrapper(j))
11352 {
11353 switch (counter++)
11354 {
11355 case 1:
11356 {
11357 CHECK(i.key() == "0");
11358 CHECK(i.value() == "A");
11359 break;
11360 }
11361
11362 case 2:
11363 {
11364 CHECK(i.key() == "1");
11365 CHECK(i.value() == "B");
11366 break;
11367 }
11368
11369 default:
11370 {
11371 break;
11372 }
11373 }
11374 }
11375
11376 CHECK(counter == 3);
11377 }
11378
11379 SECTION("const reference")
11380 {
11381 json j = {"A", "B"};
11382 int counter = 1;
11383
11384 for (const auto& i : json::iterator_wrapper(j))
11385 {
11386 switch (counter++)
11387 {
11388 case 1:
11389 {
11390 CHECK(i.key() == "0");
11391 CHECK(i.value() == "A");
11392 break;
11393 }
11394
11395 case 2:
11396 {
11397 CHECK(i.key() == "1");
11398 CHECK(i.value() == "B");
11399 break;
11400 }
11401
11402 default:
11403 {
11404 break;
11405 }
11406 }
11407 }
11408
11409 CHECK(counter == 3);
11410 }
11411 }
11412
11413 SECTION("const array")
11414 {
11415 SECTION("value")
11416 {
11417 const json j = {"A", "B"};
11418 int counter = 1;
11419
11420 for (auto i : json::iterator_wrapper(j))
11421 {
11422 switch (counter++)
11423 {
11424 case 1:
11425 {
11426 CHECK(i.key() == "0");
11427 CHECK(i.value() == "A");
11428 break;
11429 }
11430
11431 case 2:
11432 {
11433 CHECK(i.key() == "1");
11434 CHECK(i.value() == "B");
11435 break;
11436 }
11437
11438 default:
11439 {
11440 break;
11441 }
11442 }
11443 }
11444
11445 CHECK(counter == 3);
11446 }
11447
11448 SECTION("reference")
11449 {
11450 const json j = {"A", "B"};
11451 int counter = 1;
11452
11453 for (auto& i : json::iterator_wrapper(j))
11454 {
11455 switch (counter++)
11456 {
11457 case 1:
11458 {
11459 CHECK(i.key() == "0");
11460 CHECK(i.value() == "A");
11461 break;
11462 }
11463
11464 case 2:
11465 {
11466 CHECK(i.key() == "1");
11467 CHECK(i.value() == "B");
11468 break;
11469 }
11470
11471 default:
11472 {
11473 break;
11474 }
11475 }
11476 }
11477
11478 CHECK(counter == 3);
11479 }
11480
11481 SECTION("const value")
11482 {
11483 const json j = {"A", "B"};
11484 int counter = 1;
11485
11486 for (const auto i : json::iterator_wrapper(j))
11487 {
11488 switch (counter++)
11489 {
11490 case 1:
11491 {
11492 CHECK(i.key() == "0");
11493 CHECK(i.value() == "A");
11494 break;
11495 }
11496
11497 case 2:
11498 {
11499 CHECK(i.key() == "1");
11500 CHECK(i.value() == "B");
11501 break;
11502 }
11503
11504 default:
11505 {
11506 break;
11507 }
11508 }
11509 }
11510
11511 CHECK(counter == 3);
11512 }
11513
11514 SECTION("const reference")
11515 {
11516 const json j = {"A", "B"};
11517 int counter = 1;
11518
11519 for (const auto& i : json::iterator_wrapper(j))
11520 {
11521 switch (counter++)
11522 {
11523 case 1:
11524 {
11525 CHECK(i.key() == "0");
11526 CHECK(i.value() == "A");
11527 break;
11528 }
11529
11530 case 2:
11531 {
11532 CHECK(i.key() == "1");
11533 CHECK(i.value() == "B");
11534 break;
11535 }
11536
11537 default:
11538 {
11539 break;
11540 }
11541 }
11542 }
11543
11544 CHECK(counter == 3);
11545 }
11546 }
11547
11548 SECTION("primitive")
11549 {
11550 SECTION("value")
11551 {
11552 json j = 1;
11553 int counter = 1;
11554
11555 for (auto i : json::iterator_wrapper(j))
11556 {
11557 ++counter;
11558 CHECK(i.key() == "");
11559 CHECK(i.value() == json(1));
11560 }
11561
11562 CHECK(counter == 2);
11563 }
11564
11565 SECTION("reference")
11566 {
11567 json j = 1;
11568 int counter = 1;
11569
11570 for (auto& i : json::iterator_wrapper(j))
11571 {
11572 ++counter;
11573 CHECK(i.key() == "");
11574 CHECK(i.value() == json(1));
11575
11576
11577 i.value() = json(2);
11578 }
11579
11580 CHECK(counter == 2);
11581
11582
11583 CHECK(j == json(2));
11584 }
11585
11586 SECTION("const value")
11587 {
11588 json j = 1;
11589 int counter = 1;
11590
11591 for (const auto i : json::iterator_wrapper(j))
11592 {
11593 ++counter;
11594 CHECK(i.key() == "");
11595 CHECK(i.value() == json(1));
11596 }
11597
11598 CHECK(counter == 2);
11599 }
11600
11601 SECTION("const reference")
11602 {
11603 json j = 1;
11604 int counter = 1;
11605
11606 for (const auto& i : json::iterator_wrapper(j))
11607 {
11608 ++counter;
11609 CHECK(i.key() == "");
11610 CHECK(i.value() == json(1));
11611 }
11612
11613 CHECK(counter == 2);
11614 }
11615 }
11616
11617 SECTION("const primitive")
11618 {
11619 SECTION("value")
11620 {
11621 const json j = 1;
11622 int counter = 1;
11623
11624 for (auto i : json::iterator_wrapper(j))
11625 {
11626 ++counter;
11627 CHECK(i.key() == "");
11628 CHECK(i.value() == json(1));
11629 }
11630
11631 CHECK(counter == 2);
11632 }
11633
11634 SECTION("reference")
11635 {
11636 const json j = 1;
11637 int counter = 1;
11638
11639 for (auto& i : json::iterator_wrapper(j))
11640 {
11641 ++counter;
11642 CHECK(i.key() == "");
11643 CHECK(i.value() == json(1));
11644 }
11645
11646 CHECK(counter == 2);
11647 }
11648
11649 SECTION("const value")
11650 {
11651 const json j = 1;
11652 int counter = 1;
11653
11654 for (const auto i : json::iterator_wrapper(j))
11655 {
11656 ++counter;
11657 CHECK(i.key() == "");
11658 CHECK(i.value() == json(1));
11659 }
11660
11661 CHECK(counter == 2);
11662 }
11663
11664 SECTION("const reference")
11665 {
11666 const json j = 1;
11667 int counter = 1;
11668
11669 for (const auto& i : json::iterator_wrapper(j))
11670 {
11671 ++counter;
11672 CHECK(i.key() == "");
11673 CHECK(i.value() == json(1));
11674 }
11675
11676 CHECK(counter == 2);
11677 }
11678 }
11679 }
11680
11681 TEST_CASE("compliance tests from json.org")
11682 {
11683
11684
11685 SECTION("expected failures")
11686 {
11687 for (auto filename :
11688 {
11689
11690 "test/data/json_tests/fail2.json",
11691 "test/data/json_tests/fail3.json",
11692 "test/data/json_tests/fail4.json",
11693 "test/data/json_tests/fail5.json",
11694 "test/data/json_tests/fail6.json",
11695 "test/data/json_tests/fail7.json",
11696 "test/data/json_tests/fail8.json",
11697 "test/data/json_tests/fail9.json",
11698 "test/data/json_tests/fail10.json",
11699 "test/data/json_tests/fail11.json",
11700 "test/data/json_tests/fail12.json",
11701 "test/data/json_tests/fail13.json",
11702 "test/data/json_tests/fail14.json",
11703 "test/data/json_tests/fail15.json",
11704 "test/data/json_tests/fail16.json",
11705 "test/data/json_tests/fail17.json",
11706
11707 "test/data/json_tests/fail19.json",
11708 "test/data/json_tests/fail20.json",
11709 "test/data/json_tests/fail21.json",
11710 "test/data/json_tests/fail22.json",
11711 "test/data/json_tests/fail23.json",
11712 "test/data/json_tests/fail24.json",
11713 "test/data/json_tests/fail25.json",
11714 "test/data/json_tests/fail26.json",
11715 "test/data/json_tests/fail27.json",
11716 "test/data/json_tests/fail28.json",
11717 "test/data/json_tests/fail29.json",
11718 "test/data/json_tests/fail30.json",
11719 "test/data/json_tests/fail31.json",
11720 "test/data/json_tests/fail32.json",
11721 "test/data/json_tests/fail33.json"
11722 })
11723 {
11724 CAPTURE(filename);
11725 json j;
11726 std::ifstream f(filename);
11727 CHECK_THROWS_AS(j << f, std::invalid_argument);
11728 }
11729 }
11730
11731 SECTION("expected passes")
11732 {
11733 for (auto filename :
11734 {
11735 "test/data/json_tests/pass1.json",
11736 "test/data/json_tests/pass2.json",
11737 "test/data/json_tests/pass3.json"
11738 })
11739 {
11740 CAPTURE(filename);
11741 json j;
11742 std::ifstream f(filename);
11743 CHECK_NOTHROW(j << f);
11744 }
11745 }
11746 }
11747
11748 TEST_CASE("compliance tests from nativejson-benchmark")
11749 {
11750
11751
11752 SECTION("doubles")
11753 {
11754 auto TEST_DOUBLE = [](const std::string & json_string, const double expected)
11755 {
11756 CAPTURE(json_string);
11757 CAPTURE(expected);
11758 CHECK(json::parse(json_string)[0].get<double>() == Approx(expected));
11759 };
11760
11761 TEST_DOUBLE("[0.0]", 0.0);
11762 TEST_DOUBLE("[-0.0]", -0.0);
11763 TEST_DOUBLE("[1.0]", 1.0);
11764 TEST_DOUBLE("[-1.0]", -1.0);
11765 TEST_DOUBLE("[1.5]", 1.5);
11766 TEST_DOUBLE("[-1.5]", -1.5);
11767 TEST_DOUBLE("[3.1416]", 3.1416);
11768 TEST_DOUBLE("[1E10]", 1E10);
11769 TEST_DOUBLE("[1e10]", 1e10);
11770 TEST_DOUBLE("[1E+10]", 1E+10);
11771 TEST_DOUBLE("[1E-10]", 1E-10);
11772 TEST_DOUBLE("[-1E10]", -1E10);
11773 TEST_DOUBLE("[-1e10]", -1e10);
11774 TEST_DOUBLE("[-1E+10]", -1E+10);
11775 TEST_DOUBLE("[-1E-10]", -1E-10);
11776 TEST_DOUBLE("[1.234E+10]", 1.234E+10);
11777 TEST_DOUBLE("[1.234E-10]", 1.234E-10);
11778 TEST_DOUBLE("[1.79769e+308]", 1.79769e+308);
11779 TEST_DOUBLE("[2.22507e-308]", 2.22507e-308);
11780 TEST_DOUBLE("[-1.79769e+308]", -1.79769e+308);
11781 TEST_DOUBLE("[-2.22507e-308]", -2.22507e-308);
11782 TEST_DOUBLE("[4.9406564584124654e-324]", 4.9406564584124654e-324);
11783 TEST_DOUBLE("[2.2250738585072009e-308]", 2.2250738585072009e-308);
11784 TEST_DOUBLE("[2.2250738585072014e-308]", 2.2250738585072014e-308);
11785 TEST_DOUBLE("[1.7976931348623157e+308]", 1.7976931348623157e+308);
11786 TEST_DOUBLE("[1e-10000]", 0.0);
11787 TEST_DOUBLE("[18446744073709551616]",
11788 18446744073709551616.0);
11789 TEST_DOUBLE("[-9223372036854775809]",
11790 -9223372036854775809.0);
11791 TEST_DOUBLE("[0.9868011474609375]",
11792 0.9868011474609375);
11793 TEST_DOUBLE("[123e34]", 123e34);
11794 TEST_DOUBLE("[45913141877270640000.0]", 45913141877270640000.0);
11795 TEST_DOUBLE("[2.2250738585072011e-308]",
11796 2.2250738585072011e-308);
11797
11798
11799 TEST_DOUBLE("[1e-214748363]", 0.0);
11800 TEST_DOUBLE("[1e-214748364]", 0.0);
11801
11802 TEST_DOUBLE("[0.017976931348623157e+310]", 1.7976931348623157e+308);
11803
11804
11805
11806
11807
11808 TEST_DOUBLE("[2.2250738585072012e-308]",
11809 2.2250738585072014e-308);
11810
11811
11812
11813 TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164564e-308]",
11814 2.2250738585072009e-308);
11815 TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164565e-308]",
11816 2.2250738585072014e-308);
11817
11818
11819
11820 TEST_DOUBLE("[0.999999999999999944488848768742172978818416595458984375]", 1.0);
11821 TEST_DOUBLE("[0.999999999999999944488848768742172978818416595458984374]",
11822 0.99999999999999989);
11823 TEST_DOUBLE("[0.999999999999999944488848768742172978818416595458984376]", 1.0);
11824
11825 TEST_DOUBLE("[1.00000000000000011102230246251565404236316680908203125]", 1.0);
11826 TEST_DOUBLE("[1.00000000000000011102230246251565404236316680908203124]", 1.0);
11827 TEST_DOUBLE("[1.00000000000000011102230246251565404236316680908203126]",
11828 1.00000000000000022);
11829
11830
11831
11832 TEST_DOUBLE("[72057594037927928.0]", 72057594037927928.0);
11833 TEST_DOUBLE("[72057594037927936.0]", 72057594037927936.0);
11834 TEST_DOUBLE("[72057594037927932.0]", 72057594037927936.0);
11835 TEST_DOUBLE("[7205759403792793199999e-5]", 72057594037927928.0);
11836 TEST_DOUBLE("[7205759403792793200001e-5]", 72057594037927936.0);
11837
11838 TEST_DOUBLE("[9223372036854774784.0]", 9223372036854774784.0);
11839 TEST_DOUBLE("[9223372036854775808.0]", 9223372036854775808.0);
11840 TEST_DOUBLE("[9223372036854775296.0]", 9223372036854775808.0);
11841 TEST_DOUBLE("[922337203685477529599999e-5]", 9223372036854774784.0);
11842 TEST_DOUBLE("[922337203685477529600001e-5]", 9223372036854775808.0);
11843
11844 TEST_DOUBLE("[10141204801825834086073718800384]", 10141204801825834086073718800384.0);
11845 TEST_DOUBLE("[10141204801825835211973625643008]", 10141204801825835211973625643008.0);
11846 TEST_DOUBLE("[10141204801825834649023672221696]", 10141204801825835211973625643008.0);
11847 TEST_DOUBLE("[1014120480182583464902367222169599999e-5]", 10141204801825834086073718800384.0);
11848 TEST_DOUBLE("[1014120480182583464902367222169600001e-5]", 10141204801825835211973625643008.0);
11849
11850 TEST_DOUBLE("[5708990770823838890407843763683279797179383808]",
11851 5708990770823838890407843763683279797179383808.0);
11852 TEST_DOUBLE("[5708990770823839524233143877797980545530986496]",
11853 5708990770823839524233143877797980545530986496.0);
11854 TEST_DOUBLE("[5708990770823839207320493820740630171355185152]",
11855 5708990770823839524233143877797980545530986496.0);
11856 TEST_DOUBLE("[5708990770823839207320493820740630171355185151999e-3]",
11857 5708990770823838890407843763683279797179383808.0);
11858 TEST_DOUBLE("[5708990770823839207320493820740630171355185152001e-3]",
11859 5708990770823839524233143877797980545530986496.0);
11860
11861 {
11862 char n1e308[312];
11863 n1e308[0] = '[';
11864 n1e308[1] = '1';
11865 for (int j = 2; j < 310; j++)
11866 {
11867 n1e308[j] = '0';
11868 }
11869 n1e308[310] = ']';
11870 n1e308[311] = '\0';
11871 TEST_DOUBLE(n1e308, 1E308);
11872 }
11873
11874
11875 TEST_DOUBLE(
11876 "[2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
11877 "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
11878 "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
11879 "6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
11880 "1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
11881 "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
11882 "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
11883 "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
11884 "e-308]",
11885 2.2250738585072014e-308);
11886 }
11887
11888 SECTION("strings")
11889 {
11890 auto TEST_STRING = [](const std::string & json_string, const std::string & expected)
11891 {
11892 CAPTURE(json_string);
11893 CAPTURE(expected);
11894 CHECK(json::parse(json_string)[0].get<std::string>() == expected);
11895 };
11896
11897 TEST_STRING("[\"\"]", "");
11898 TEST_STRING("[\"Hello\"]", "Hello");
11899 TEST_STRING("[\"Hello\\nWorld\"]", "Hello\nWorld");
11900
11901 TEST_STRING("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]", "\"\\/\b\f\n\r\t");
11902 TEST_STRING("[\"\\u0024\"]", "\x24");
11903 TEST_STRING("[\"\\u00A2\"]", "\xC2\xA2");
11904 TEST_STRING("[\"\\u20AC\"]", "\xE2\x82\xAC");
11905 TEST_STRING("[\"\\uD834\\uDD1E\"]", "\xF0\x9D\x84\x9E");
11906 }
11907
11908 SECTION("roundtrip")
11909 {
11910
11911
11912 for (auto filename :
11913 {
11914 "test/data/json_roundtrip/roundtrip01.json",
11915 "test/data/json_roundtrip/roundtrip02.json",
11916 "test/data/json_roundtrip/roundtrip03.json",
11917 "test/data/json_roundtrip/roundtrip04.json",
11918 "test/data/json_roundtrip/roundtrip05.json",
11919 "test/data/json_roundtrip/roundtrip06.json",
11920 "test/data/json_roundtrip/roundtrip07.json",
11921 "test/data/json_roundtrip/roundtrip08.json",
11922 "test/data/json_roundtrip/roundtrip09.json",
11923 "test/data/json_roundtrip/roundtrip10.json",
11924 "test/data/json_roundtrip/roundtrip11.json",
11925 "test/data/json_roundtrip/roundtrip12.json",
11926 "test/data/json_roundtrip/roundtrip13.json",
11927 "test/data/json_roundtrip/roundtrip14.json",
11928 "test/data/json_roundtrip/roundtrip15.json",
11929 "test/data/json_roundtrip/roundtrip16.json",
11930 "test/data/json_roundtrip/roundtrip17.json",
11931 "test/data/json_roundtrip/roundtrip18.json",
11932 "test/data/json_roundtrip/roundtrip19.json",
11933 "test/data/json_roundtrip/roundtrip20.json",
11934 "test/data/json_roundtrip/roundtrip21.json",
11935 "test/data/json_roundtrip/roundtrip22.json",
11936 "test/data/json_roundtrip/roundtrip23.json",
11937
11938
11939
11940
11941
11942 "test/data/json_roundtrip/roundtrip29.json",
11943
11944
11945 "test/data/json_roundtrip/roundtrip32.json"
11946 })
11947 {
11948 CAPTURE(filename);
11949 std::ifstream f(filename);
11950 std::string json_string( (std::istreambuf_iterator<char>(f) ),
11951 (std::istreambuf_iterator<char>()) );
11952
11953 json j = json::parse(json_string);
11954 CHECK(j.dump() == json_string);
11955 }
11956 }
11957 }
11958
11959 TEST_CASE("test suite from json-test-suite")
11960 {
11961 SECTION("read all sample.json")
11962 {
11963
11964
11965 std::ifstream f("test/data/json_testsuite/sample.json");
11966 json j;
11967 CHECK_NOTHROW(j << f);
11968
11969
11970 CHECK(j.size() == 3);
11971 }
11972 }
11973
11974 TEST_CASE("json.org examples")
11975 {
11976
11977
11978 SECTION("1.json")
11979 {
11980 std::ifstream f("test/data/json.org/1.json");
11981 json j;
11982 CHECK_NOTHROW(j << f);
11983 }
11984
11985 SECTION("2.json")
11986 {
11987 std::ifstream f("test/data/json.org/2.json");
11988 json j;
11989 CHECK_NOTHROW(j << f);
11990 }
11991
11992 SECTION("3.json")
11993 {
11994 std::ifstream f("test/data/json.org/3.json");
11995 json j;
11996 CHECK_NOTHROW(j << f);
11997 }
11998
11999 SECTION("4.json")
12000 {
12001 std::ifstream f("test/data/json.org/4.json");
12002 json j;
12003 CHECK_NOTHROW(j << f);
12004 }
12005
12006 SECTION("5.json")
12007 {
12008 std::ifstream f("test/data/json.org/5.json");
12009 json j;
12010 CHECK_NOTHROW(j << f);
12011 }
12012 }
12013
12014 TEST_CASE("RFC 7159 examples")
12015 {
12016
12017
12018 SECTION("7. Strings")
12019 {
12020 CHECK(json::parse("\"\\u005C\"") == json("\\"));
12021 CHECK(json::parse("\"\\uD834\\uDD1E\"") == json("𝄞"));
12022 CHECK(json::parse("\"𝄞\"") == json("𝄞"));
12023 }
12024
12025 SECTION("8.3 String Comparison")
12026 {
12027 CHECK(json::parse("\"a\\b\"") == json::parse("\"a\u005Cb\""));
12028 }
12029
12030 SECTION("13 Examples")
12031 {
12032 {
12033 CHECK_NOTHROW(json(R"(
12034 {
12035 "Image": {
12036 "Width": 800,
12037 "Height": 600,
12038 "Title": "View from 15th Floor",
12039 "Thumbnail": {
12040 "Url": "http:
12041 "Height": 125,
12042 "Width": 100
12043 },
12044 "Animated" : false,
12045 "IDs": [116, 943, 234, 38793]
12046 }
12047 }
12048 )"));
12049 }
12050
12051 {
12052 CHECK_NOTHROW(json(R"(
12053 [
12054 {
12055 "precision": "zip",
12056 "Latitude": 37.7668,
12057 "Longitude": -122.3959,
12058 "Address": "",
12059 "City": "SAN FRANCISCO",
12060 "State": "CA",
12061 "Zip": "94107",
12062 "Country": "US"
12063 },
12064 {
12065 "precision": "zip",
12066 "Latitude": 37.371991,
12067 "Longitude": -122.026020,
12068 "Address": "",
12069 "City": "SUNNYVALE",
12070 "State": "CA",
12071 "Zip": "94085",
12072 "Country": "US"
12073 }
12074 ])"));
12075 }
12076
12077 CHECK(json::parse("\"Hello world!\"") == json("Hello world!"));
12078 CHECK(json::parse("42") == json(42));
12079 CHECK(json::parse("true") == json(true));
12080 }
12081 }
12082
12083 TEST_CASE("Unicode", "[hide]")
12084 {
12085 SECTION("full enumeration of Unicode codepoints")
12086 {
12087
12088 auto codepoint_to_unicode = [](std::size_t cp)
12089 {
12090 char* buffer = new char[10];
12091 sprintf(buffer, "\\u%04lx", cp);
12092 std::string result(buffer);
12093 delete[] buffer;
12094 return result;
12095 };
12096
12097
12098 for (std::size_t cp = 0; cp <= 0x10FFFFu; ++cp)
12099 {
12100
12101
12102
12103
12104
12105 if (cp >= 0xD800u and cp <= 0xDFFFu)
12106 {
12107 continue;
12108 }
12109
12110 std::string res;
12111
12112 if (cp < 0x10000u)
12113 {
12114
12115 res += codepoint_to_unicode(cp);
12116 }
12117 else
12118 {
12119
12120 res += codepoint_to_unicode(0xd800u + (((cp - 0x10000u) >> 10) & 0x3ffu));
12121 res += codepoint_to_unicode(0xdc00u + ((cp - 0x10000u) & 0x3ffu));
12122 }
12123
12124 try
12125 {
12126 json j1, j2;
12127 CHECK_NOTHROW(j1 = json::parse("\"" + res + "\""));
12128 CHECK_NOTHROW(j2 = json::parse(j1.dump()));
12129 CHECK(j1 == j2);
12130 }
12131 catch (std::invalid_argument)
12132 {
12133
12134 }
12135 }
12136 }
12137
12138 SECTION("read all unicode characters")
12139 {
12140
12141
12142 std::ifstream f("test/data/json_nlohmann_tests/all_unicode.json");
12143 json j;
12144 CHECK_NOTHROW(j << f);
12145
12146
12147 CHECK(j.size() == 1112065);
12148
12149 SECTION("check JSON Pointers")
12150 {
12151 for (auto s : j)
12152 {
12153
12154 if (not s.is_string())
12155 {
12156 continue;
12157 }
12158
12159 std::string ptr = s;
12160
12161
12162 if (ptr == "~")
12163 {
12164 ptr += "0";
12165 }
12166
12167
12168 ptr = "/" + ptr;
12169
12170 CHECK_NOTHROW(json::json_pointer("/" + ptr));
12171
12172
12173 auto escaped = json::json_pointer::escape(ptr);
12174 json::json_pointer::unescape(escaped);
12175 CHECK(escaped == ptr);
12176 }
12177 }
12178 }
12179
12180 SECTION("ignore byte-order-mark")
12181 {
12182
12183 std::ifstream f("test/data/json_nlohmann_tests/bom.json");
12184 json j;
12185 CHECK_NOTHROW(j << f);
12186 }
12187
12188 SECTION("error for incomplete/wrong BOM")
12189 {
12190 CHECK_THROWS_AS(json::parse("\xef\xbb"), std::invalid_argument);
12191 CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), std::invalid_argument);
12192 }
12193 }
12194
12195 TEST_CASE("JSON pointers")
12196 {
12197 SECTION("errors")
12198 {
12199 CHECK_THROWS_AS(json::json_pointer("foo"), std::domain_error);
12200 CHECK_THROWS_WITH(json::json_pointer("foo"), "JSON pointer must be empty or begin with '/'");
12201
12202 CHECK_THROWS_AS(json::json_pointer("/~~"), std::domain_error);
12203 CHECK_THROWS_WITH(json::json_pointer("/~~"), "escape error: '~' must be followed with '0' or '1'");
12204
12205 CHECK_THROWS_AS(json::json_pointer("/~"), std::domain_error);
12206 CHECK_THROWS_WITH(json::json_pointer("/~"), "escape error: '~' must be followed with '0' or '1'");
12207
12208 json::json_pointer p;
12209 CHECK_THROWS_AS(p.top(), std::domain_error);
12210 CHECK_THROWS_WITH(p.top(), "JSON pointer has no parent");
12211 CHECK_THROWS_AS(p.pop_back(), std::domain_error);
12212 CHECK_THROWS_WITH(p.pop_back(), "JSON pointer has no parent");
12213 }
12214
12215 SECTION("examples from RFC 6901")
12216 {
12217 SECTION("nonconst access")
12218 {
12219 json j = R"(
12220 {
12221 "foo": ["bar", "baz"],
12222 "": 0,
12223 "a/b": 1,
12224 "c%d": 2,
12225 "e^f": 3,
12226 "g|h": 4,
12227 "i\\j": 5,
12228 "k\"l": 6,
12229 " ": 7,
12230 "m~n": 8
12231 }
12232 )"_json;
12233
12234 // the whole document
12235 CHECK(j[json::json_pointer()] == j);
12236 CHECK(j[json::json_pointer("")] == j);
12237
12238 // array access
12239 CHECK(j[json::json_pointer("/foo")] == j["foo"]);
12240 CHECK(j[json::json_pointer("/foo/0")] == j["foo"][0]);
12241 CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
12242 CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
12243
12244 // checked array access
12245 CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
12246 CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]);
12247
12248 // empty string access
12249 CHECK(j[json::json_pointer("/")] == j[""]);
12250
12251 // other cases
12252 CHECK(j[json::json_pointer("/ ")] == j[" "]);
12253 CHECK(j[json::json_pointer("/c%d")] == j["c%d"]);
12254 CHECK(j[json::json_pointer("/e^f")] == j["e^f"]);
12255 CHECK(j[json::json_pointer("/g|h")] == j["g|h"]);
12256 CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]);
12257 CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]);
12258
12259
12260 CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
12261 CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);
12262 CHECK(j.at(json::json_pointer("/e^f")) == j["e^f"]);
12263 CHECK(j.at(json::json_pointer("/g|h")) == j["g|h"]);
12264 CHECK(j.at(json::json_pointer("/i\\j")) == j["i\\j"]);
12265 CHECK(j.at(json::json_pointer("/k\"l")) == j["k\"l"]);
12266
12267
12268 CHECK(j[json::json_pointer("/a~1b")] == j["a/b"]);
12269 CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
12270
12271
12272 CHECK_THROWS_AS(j[json::json_pointer("/a/b")], std::out_of_range);
12273 CHECK_THROWS_WITH(j[json::json_pointer("/a/b")], "unresolved reference token 'b'");
12274
12275 CHECK(json({{"a", {{"b", 42}}}})[json::json_pointer("/a/b")] == json(42));
12276
12277
12278 json j_primitive = 1;
12279 CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], std::out_of_range);
12280 CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer], "unresolved reference token 'foo'");
12281 CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), std::out_of_range);
12282 CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer), "unresolved reference token 'foo'");
12283 }
12284
12285 SECTION("const access")
12286 {
12287 const json j = R"(
12288 {
12289 "foo": ["bar", "baz"],
12290 "": 0,
12291 "a/b": 1,
12292 "c%d": 2,
12293 "e^f": 3,
12294 "g|h": 4,
12295 "i\\j": 5,
12296 "k\"l": 6,
12297 " ": 7,
12298 "m~n": 8
12299 }
12300 )"_json;
12301
12302 // the whole document
12303 CHECK(j[json::json_pointer()] == j);
12304 CHECK(j[json::json_pointer("")] == j);
12305
12306 // array access
12307 CHECK(j[json::json_pointer("/foo")] == j["foo"]);
12308 CHECK(j[json::json_pointer("/foo/0")] == j["foo"][0]);
12309 CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
12310 CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
12311
12312 // checked array access
12313 CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
12314 CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]);
12315
12316 // empty string access
12317 CHECK(j[json::json_pointer("/")] == j[""]);
12318
12319 // other cases
12320 CHECK(j[json::json_pointer("/ ")] == j[" "]);
12321 CHECK(j[json::json_pointer("/c%d")] == j["c%d"]);
12322 CHECK(j[json::json_pointer("/e^f")] == j["e^f"]);
12323 CHECK(j[json::json_pointer("/g|h")] == j["g|h"]);
12324 CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]);
12325 CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]);
12326
12327
12328 CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
12329 CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);
12330 CHECK(j.at(json::json_pointer("/e^f")) == j["e^f"]);
12331 CHECK(j.at(json::json_pointer("/g|h")) == j["g|h"]);
12332 CHECK(j.at(json::json_pointer("/i\\j")) == j["i\\j"]);
12333 CHECK(j.at(json::json_pointer("/k\"l")) == j["k\"l"]);
12334
12335
12336 CHECK(j[json::json_pointer("/a~1b")] == j["a/b"]);
12337 CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
12338
12339
12340 CHECK_THROWS_AS(j.at(json::json_pointer("/a/b")), std::out_of_range);
12341 CHECK_THROWS_WITH(j.at(json::json_pointer("/a/b")), "key 'a' not found");
12342
12343
12344 const json j_primitive = 1;
12345 CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], std::out_of_range);
12346 CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer], "unresolved reference token 'foo'");
12347 CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), std::out_of_range);
12348 CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer), "unresolved reference token 'foo'");
12349 }
12350
12351 SECTION("user-defined string literal")
12352 {
12353 json j = R"(
12354 {
12355 "foo": ["bar", "baz"],
12356 "": 0,
12357 "a/b": 1,
12358 "c%d": 2,
12359 "e^f": 3,
12360 "g|h": 4,
12361 "i\\j": 5,
12362 "k\"l": 6,
12363 " ": 7,
12364 "m~n": 8
12365 }
12366 )"_json;
12367
12368 // the whole document
12369 CHECK(j[""_json_pointer] == j);
12370
12371 // array access
12372 CHECK(j["/foo"_json_pointer] == j["foo"]);
12373 CHECK(j["/foo/0"_json_pointer] == j["foo"][0]);
12374 CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
12375 }
12376 }
12377
12378 SECTION("array access")
12379 {
12380 SECTION("nonconst access")
12381 {
12382 json j = {1, 2, 3};
12383 const json j_const = j;
12384
12385 // check reading access
12386 CHECK(j["/0"_json_pointer] == j[0]);
12387 CHECK(j["/1"_json_pointer] == j[1]);
12388 CHECK(j["/2"_json_pointer] == j[2]);
12389
12390 // assign to existing index
12391 j["/1"_json_pointer] = 13;
12392 CHECK(j[1] == json(13));
12393
12394 // assign to nonexisting index
12395 j["/3"_json_pointer] = 33;
12396 CHECK(j[3] == json(33));
12397
12398 // assign to nonexisting index (with gap)
12399 j["/5"_json_pointer] = 55;
12400 CHECK(j == json({1, 13, 3, 33, nullptr, 55}));
12401
12402 // error with leading 0
12403 CHECK_THROWS_AS(j["/01"_json_pointer], std::domain_error);
12404 CHECK_THROWS_WITH(j["/01"_json_pointer], "array index must not begin with '0'");
12405 CHECK_THROWS_AS(j_const["/01"_json_pointer], std::domain_error);
12406 CHECK_THROWS_WITH(j_const["/01"_json_pointer], "array index must not begin with '0'");
12407 CHECK_THROWS_AS(j.at("/01"_json_pointer), std::domain_error);
12408 CHECK_THROWS_WITH(j.at("/01"_json_pointer), "array index must not begin with '0'");
12409 CHECK_THROWS_AS(j_const.at("/01"_json_pointer), std::domain_error);
12410 CHECK_THROWS_WITH(j_const.at("/01"_json_pointer), "array index must not begin with '0'");
12411
12412 // error with incorrect numbers
12413 CHECK_THROWS_AS(j["/one"_json_pointer] = 1, std::invalid_argument);
12414
12415 // assign to "-"
12416 j["/-"_json_pointer] = 99;
12417 CHECK(j == json({1, 13, 3, 33, nullptr, 55, 99}));
12418
12419 // error when using "-" in const object
12420 CHECK_THROWS_AS(j_const["/-"_json_pointer], std::out_of_range);
12421 CHECK_THROWS_WITH(j_const["/-"_json_pointer], "array index '-' (3) is out of range");
12422
12423 // error when using "-" with at
12424 CHECK_THROWS_AS(j.at("/-"_json_pointer), std::out_of_range);
12425 CHECK_THROWS_WITH(j.at("/-"_json_pointer), "array index '-' (7) is out of range");
12426 CHECK_THROWS_AS(j_const.at("/-"_json_pointer), std::out_of_range);
12427 CHECK_THROWS_WITH(j_const.at("/-"_json_pointer), "array index '-' (3) is out of range");
12428 }
12429
12430 SECTION("const access")
12431 {
12432 const json j = {1, 2, 3};
12433
12434
12435 CHECK(j["/0"_json_pointer] == j[0]);
12436 CHECK(j["/1"_json_pointer] == j[1]);
12437 CHECK(j["/2"_json_pointer] == j[2]);
12438
12439
12440 CHECK_THROWS_AS(j.at("/3"_json_pointer), std::out_of_range);
12441 CHECK_THROWS_WITH(j.at("/3"_json_pointer), "array index 3 is out of range");
12442
12443
12444 CHECK_THROWS_AS(j.at("/5"_json_pointer), std::out_of_range);
12445 CHECK_THROWS_WITH(j.at("/5"_json_pointer), "array index 5 is out of range");
12446
12447
12448 CHECK_THROWS_AS(j["/-"_json_pointer], std::out_of_range);
12449 CHECK_THROWS_WITH(j["/-"_json_pointer], "array index '-' (3) is out of range");
12450 CHECK_THROWS_AS(j.at("/-"_json_pointer), std::out_of_range);
12451 CHECK_THROWS_WITH(j.at("/-"_json_pointer), "array index '-' (3) is out of range");
12452 }
12453
12454 }
12455
12456 SECTION("flatten")
12457 {
12458 json j =
12459 {
12460 {"pi", 3.141},
12461 {"happy", true},
12462 {"name", "Niels"},
12463 {"nothing", nullptr},
12464 {
12465 "answer", {
12466 {"everything", 42}
12467 }
12468 },
12469 {"list", {1, 0, 2}},
12470 {
12471 "object", {
12472 {"currency", "USD"},
12473 {"value", 42.99},
12474 {"", "empty string"},
12475 {"/", "slash"},
12476 {"~", "tilde"},
12477 {"~1", "tilde1"}
12478 }
12479 }
12480 };
12481
12482 json j_flatten =
12483 {
12484 {"/pi", 3.141},
12485 {"/happy", true},
12486 {"/name", "Niels"},
12487 {"/nothing", nullptr},
12488 {"/answer/everything", 42},
12489 {"/list/0", 1},
12490 {"/list/1", 0},
12491 {"/list/2", 2},
12492 {"/object/currency", "USD"},
12493 {"/object/value", 42.99},
12494 {"/object/", "empty string"},
12495 {"/object/~1", "slash"},
12496 {"/object/~0", "tilde"},
12497 {"/object/~01", "tilde1"}
12498 };
12499
12500
12501 CHECK(j.flatten() == j_flatten);
12502
12503
12504 CHECK(j_flatten.unflatten() == j);
12505
12506
12507 CHECK_THROWS_AS(json(1).unflatten(), std::domain_error);
12508 CHECK_THROWS_WITH(json(1).unflatten(), "only objects can be unflattened");
12509
12510
12511 CHECK_THROWS_AS(json({{"/1", {1, 2, 3}}}).unflatten(), std::domain_error);
12512 CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "values in object must be primitive");
12513
12514
12515 json j_error = {{"", 42}, {"/foo", 17}};
12516 CHECK_THROWS_AS(j_error.unflatten(), std::domain_error);
12517 CHECK_THROWS_WITH(j_error.unflatten(), "invalid value to unflatten");
12518
12519
12520 CHECK(j.flatten().unflatten() == j);
12521
12522
12523 json j_null;
12524 CHECK(j_null.flatten().unflatten() == j_null);
12525 json j_number = 42;
12526 CHECK(j_number.flatten().unflatten() == j_number);
12527 json j_boolean = false;
12528 CHECK(j_boolean.flatten().unflatten() == j_boolean);
12529 json j_string = "foo";
12530 CHECK(j_string.flatten().unflatten() == j_string);
12531
12532
12533 json j_array(json::value_t::array);
12534 CHECK(j_array.flatten().unflatten() == json());
12535 json j_object(json::value_t::object);
12536 CHECK(j_object.flatten().unflatten() == json());
12537 }
12538
12539 SECTION("string representation")
12540 {
12541 for (auto ptr :
12542 {"", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n"
12543 })
12544 {
12545 CHECK(json::json_pointer(ptr).to_string() == ptr);
12546 }
12547 }
12548 }
12549
12550 TEST_CASE("JSON patch")
12551 {
12552 SECTION("examples from RFC 6902")
12553 {
12554 SECTION("4. Operations")
12555 {
12556
12557 json op1 = R"({ "op": "add", "path": "/a/b/c", "value": "foo" })"_json;
12558 json op2 = R"({ "path": "/a/b/c", "op": "add", "value": "foo" })"_json;
12559 json op3 = R"({ "value": "foo", "path": "/a/b/c", "op": "add" })"_json;
12560
12561
12562 CHECK(op1 == op2);
12563 CHECK(op1 == op3);
12564 }
12565
12566 SECTION("4.1 add")
12567 {
12568 json patch = R"([{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }])"_json;
12569
12570
12571
12572
12573
12574 json doc1 = R"({ "a": { "foo": 1 } })"_json;
12575
12576
12577
12578 CHECK_NOTHROW(doc1.patch(patch));
12579 CHECK(doc1.patch(patch) == R"(
12580 {
12581 "a": {
12582 "foo": 1,
12583 "b": {
12584 "c": [ "foo", "bar" ]
12585 }
12586 }
12587 }
12588 )"_json);
12589
12590
12591 json doc2 = R"({ "q": { "bar": 2 } })"_json;
12592
12593
12594 CHECK_THROWS_AS(doc2.patch(patch), std::out_of_range);
12595 CHECK_THROWS_WITH(doc2.patch(patch), "key 'a' not found");
12596 }
12597
12598 SECTION("4.2 remove")
12599 {
12600
12601
12602 json doc = {1, 2, 3, 4};
12603 json patch = {{{"op", "remove"}, {"path", "/1"}}};
12604 CHECK(doc.patch(patch) == json({1, 3, 4}));
12605 }
12606
12607 SECTION("A.1. Adding an Object Member")
12608 {
12609
12610 json doc = R"(
12611 { "foo": "bar"}
12612 )"_json;
12613
12614
12615 json patch = R"(
12616 [
12617 { "op": "add", "path": "/baz", "value": "qux" }
12618 ]
12619 )"_json;
12620
12621
12622 json expected = R"(
12623 {
12624 "baz": "qux",
12625 "foo": "bar"
12626 }
12627 )"_json;
12628
12629
12630 CHECK(doc.patch(patch) == expected);
12631
12632
12633 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12634 }
12635
12636 SECTION("A.2. Adding an Array Element")
12637 {
12638
12639 json doc = R"(
12640 { "foo": [ "bar", "baz" ] }
12641 )"_json;
12642
12643
12644 json patch = R"(
12645 [
12646 { "op": "add", "path": "/foo/1", "value": "qux" }
12647 ]
12648 )"_json;
12649
12650
12651 json expected = R"(
12652 { "foo": [ "bar", "qux", "baz" ] }
12653 )"_json;
12654
12655
12656 CHECK(doc.patch(patch) == expected);
12657
12658
12659 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12660 }
12661
12662 SECTION("A.3. Removing an Object Member")
12663 {
12664
12665 json doc = R"(
12666 {
12667 "baz": "qux",
12668 "foo": "bar"
12669 }
12670 )"_json;
12671
12672
12673 json patch = R"(
12674 [
12675 { "op": "remove", "path": "/baz" }
12676 ]
12677 )"_json;
12678
12679
12680 json expected = R"(
12681 { "foo": "bar" }
12682 )"_json;
12683
12684
12685 CHECK(doc.patch(patch) == expected);
12686
12687
12688 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12689 }
12690
12691 SECTION("A.4. Removing an Array Element")
12692 {
12693
12694 json doc = R"(
12695 { "foo": [ "bar", "qux", "baz" ] }
12696 )"_json;
12697
12698
12699 json patch = R"(
12700 [
12701 { "op": "remove", "path": "/foo/1" }
12702 ]
12703 )"_json;
12704
12705
12706 json expected = R"(
12707 { "foo": [ "bar", "baz" ] }
12708 )"_json;
12709
12710
12711 CHECK(doc.patch(patch) == expected);
12712
12713
12714 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12715 }
12716
12717 SECTION("A.5. Replacing a Value")
12718 {
12719
12720 json doc = R"(
12721 {
12722 "baz": "qux",
12723 "foo": "bar"
12724 }
12725 )"_json;
12726
12727
12728 json patch = R"(
12729 [
12730 { "op": "replace", "path": "/baz", "value": "boo" }
12731 ]
12732 )"_json;
12733
12734 json expected = R"(
12735 {
12736 "baz": "boo",
12737 "foo": "bar"
12738 }
12739 )"_json;
12740
12741
12742 CHECK(doc.patch(patch) == expected);
12743
12744
12745 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12746 }
12747
12748 SECTION("A.6. Moving a Value")
12749 {
12750
12751 json doc = R"(
12752 {
12753 "foo": {
12754 "bar": "baz",
12755 "waldo": "fred"
12756 },
12757 "qux": {
12758 "corge": "grault"
12759 }
12760 }
12761 )"_json;
12762
12763
12764 json patch = R"(
12765 [
12766 { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" }
12767 ]
12768 )"_json;
12769
12770
12771 json expected = R"(
12772 {
12773 "foo": {
12774 "bar": "baz"
12775 },
12776 "qux": {
12777 "corge": "grault",
12778 "thud": "fred"
12779 }
12780 }
12781 )"_json;
12782
12783
12784 CHECK(doc.patch(patch) == expected);
12785
12786
12787 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12788 }
12789
12790 SECTION("A.7. Moving a Value")
12791 {
12792
12793 json doc = R"(
12794 { "foo": [ "all", "grass", "cows", "eat" ] }
12795 )"_json;
12796
12797
12798 json patch = R"(
12799 [
12800 { "op": "move", "from": "/foo/1", "path": "/foo/3" }
12801 ]
12802 )"_json;
12803
12804
12805 json expected = R"(
12806 { "foo": [ "all", "cows", "eat", "grass" ] }
12807 )"_json;
12808
12809
12810 CHECK(doc.patch(patch) == expected);
12811
12812
12813 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12814 }
12815
12816 SECTION("A.8. Testing a Value: Success")
12817 {
12818
12819 json doc = R"(
12820 {
12821 "baz": "qux",
12822 "foo": [ "a", 2, "c" ]
12823 }
12824 )"_json;
12825
12826
12827 json patch = R"(
12828 [
12829 { "op": "test", "path": "/baz", "value": "qux" },
12830 { "op": "test", "path": "/foo/1", "value": 2 }
12831 ]
12832 )"_json;
12833
12834
12835 CHECK_NOTHROW(doc.patch(patch));
12836
12837 CHECK(doc.patch(patch) == doc);
12838 }
12839
12840 SECTION("A.9. Testing a Value: Error")
12841 {
12842
12843 json doc = R"(
12844 { "baz": "qux" }
12845 )"_json;
12846
12847
12848 json patch = R"(
12849 [
12850 { "op": "test", "path": "/baz", "value": "bar" }
12851 ]
12852 )"_json;
12853
12854
12855 CHECK_THROWS_AS(doc.patch(patch), std::domain_error);
12856 CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump());
12857 }
12858
12859 SECTION("A.10. Adding a Nested Member Object")
12860 {
12861
12862 json doc = R"(
12863 { "foo": "bar" }
12864 )"_json;
12865
12866
12867 json patch = R"(
12868 [
12869 { "op": "add", "path": "/child", "value": { "grandchild": { } } }
12870 ]
12871 )"_json;
12872
12873
12874 json expected = R"(
12875 {
12876 "foo": "bar",
12877 "child": {
12878 "grandchild": {
12879 }
12880 }
12881 }
12882 )"_json;
12883
12884
12885 CHECK(doc.patch(patch) == expected);
12886
12887
12888 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12889 }
12890
12891 SECTION("A.11. Ignoring Unrecognized Elements")
12892 {
12893
12894 json doc = R"(
12895 { "foo": "bar" }
12896 )"_json;
12897
12898
12899 json patch = R"(
12900 [
12901 { "op": "add", "path": "/baz", "value": "qux", "xyz": 123 }
12902 ]
12903 )"_json;
12904
12905 json expected = R"(
12906 {
12907 "foo": "bar",
12908 "baz": "qux"
12909 }
12910 )"_json;
12911
12912
12913 CHECK(doc.patch(patch) == expected);
12914
12915
12916 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12917 }
12918
12919 SECTION("A.12. Adding to a Nonexistent Target")
12920 {
12921
12922 json doc = R"(
12923 { "foo": "bar" }
12924 )"_json;
12925
12926
12927 json patch = R"(
12928 [
12929 { "op": "add", "path": "/baz/bat", "value": "qux" }
12930 ]
12931 )"_json;
12932
12933
12934
12935
12936
12937
12938
12939 CHECK_THROWS_AS(doc.patch(patch), std::out_of_range);
12940 CHECK_THROWS_WITH(doc.patch(patch), "key 'baz' not found");
12941 }
12942
12943
12944
12945
12946 SECTION("A.14. Escape Ordering")
12947 {
12948
12949 json doc = R"(
12950 {
12951 "/": 9,
12952 "~1": 10
12953 }
12954 )"_json;
12955
12956
12957 json patch = R"(
12958 [
12959 {"op": "test", "path": "/~01", "value": 10}
12960 ]
12961 )"_json;
12962
12963 json expected = R"(
12964 {
12965 "/": 9,
12966 "~1": 10
12967 }
12968 )"_json;
12969
12970
12971 CHECK(doc.patch(patch) == expected);
12972
12973
12974 CHECK(doc.patch(json::diff(doc, expected)) == expected);
12975 }
12976
12977 SECTION("A.15. Comparing Strings and Numbers")
12978 {
12979
12980 json doc = R"(
12981 {
12982 "/": 9,
12983 "~1": 10
12984 }
12985 )"_json;
12986
12987
12988 json patch = R"(
12989 [
12990 {"op": "test", "path": "/~01", "value": "10"}
12991 ]
12992 )"_json;
12993
12994
12995 CHECK_THROWS_AS(doc.patch(patch), std::domain_error);
12996 CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump());
12997 }
12998
12999 SECTION("A.16. Adding an Array Value")
13000 {
13001
13002 json doc = R"(
13003 { "foo": ["bar"] }
13004 )"_json;
13005
13006
13007 json patch = R"(
13008 [
13009 { "op": "add", "path": "/foo/-", "value": ["abc", "def"] }
13010 ]
13011 )"_json;
13012
13013
13014 json expected = R"(
13015 { "foo": ["bar", ["abc", "def"]] }
13016 )"_json;
13017
13018
13019 CHECK(doc.patch(patch) == expected);
13020
13021
13022 CHECK(doc.patch(json::diff(doc, expected)) == expected);
13023 }
13024 }
13025
13026 SECTION("own examples")
13027 {
13028 SECTION("add")
13029 {
13030 SECTION("add to the root element")
13031 {
13032
13033
13034
13035
13036
13037 json doc = 17;
13038
13039
13040 json patch = R"(
13041 [
13042 { "op": "add", "path": "", "value": [1,2,3] }
13043 ]
13044 )"_json;
13045
13046
13047 json expected = {1, 2, 3};
13048
13049
13050 CHECK(doc.patch(patch) == expected);
13051
13052
13053 CHECK(doc.patch(json::diff(doc, expected)) == expected);
13054 }
13055
13056 SECTION("add to end of the array")
13057 {
13058
13059
13060
13061
13062
13063 json doc = {0, 1, 2};
13064
13065
13066 json patch = R"(
13067 [
13068 { "op": "add", "path": "/3", "value": 3 }
13069 ]
13070 )"_json;
13071
13072
13073 json expected = {0, 1, 2, 3};
13074
13075
13076 CHECK(doc.patch(patch) == expected);
13077
13078
13079 CHECK(doc.patch(json::diff(doc, expected)) == expected);
13080 }
13081 }
13082
13083 SECTION("copy")
13084 {
13085
13086 json doc = R"(
13087 {
13088 "foo": {
13089 "bar": "baz",
13090 "waldo": "fred"
13091 },
13092 "qux": {
13093 "corge": "grault"
13094 }
13095 }
13096 )"_json;
13097
13098
13099 json patch = R"(
13100 [
13101 { "op": "copy", "from": "/foo/waldo", "path": "/qux/thud" }
13102 ]
13103 )"_json;
13104
13105
13106 json expected = R"(
13107 {
13108 "foo": {
13109 "bar": "baz",
13110 "waldo": "fred"
13111 },
13112 "qux": {
13113 "corge": "grault",
13114 "thud": "fred"
13115 }
13116 }
13117 )"_json;
13118
13119
13120 CHECK(doc.patch(patch) == expected);
13121
13122
13123 CHECK(doc.patch(json::diff(doc, expected)) == expected);
13124 }
13125
13126 SECTION("replace")
13127 {
13128 json j = "string";
13129 json patch = {{{"op", "replace"}, {"path", ""}, {"value", 1}}};
13130 CHECK(j.patch(patch) == json(1));
13131 }
13132
13133 SECTION("documentation GIF")
13134 {
13135 {
13136
13137 json p1 = R"(
13138 [{"op": "add", "path": "/GB", "value": "London"}]
13139 )"_json;
13140
13141
13142 json source = R"(
13143 {"D": "Berlin", "F": "Paris"}
13144 )"_json;
13145
13146
13147 json target = source.patch(p1);
13148
13149 CHECK(target == R"({ "D": "Berlin", "F": "Paris", "GB": "London" })"_json);
13150
13151
13152 json p2 = json::diff(target, source);
13153
13154 CHECK(p2 == R"([{"op":"remove","path":"/GB"}])"_json);
13155 }
13156 {
13157
13158 json j = {"good", "bad", "ugly"};
13159
13160
13161 auto ptr = json::json_pointer("/2");
13162
13163
13164 j[ptr] = {{"it", "cattivo"}};
13165 CHECK(j == R"(["good","bad",{"it":"cattivo"}])"_json);
13166
13167
13168 j["/2/en"_json_pointer] = "ugly";
13169 CHECK(j == R"(["good","bad",{"en":"ugly","it":"cattivo"}])"_json);
13170
13171 json flat = j.flatten();
13172 CHECK(flat == R"({"/0":"good","/1":"bad","/2/en":"ugly","/2/it":"cattivo"})"_json);
13173 }
13174 }
13175 }
13176
13177 SECTION("errors")
13178 {
13179 SECTION("unknown operation")
13180 {
13181 SECTION("not an array")
13182 {
13183 json j;
13184 json patch = {{"op", "add"}, {"path", ""}, {"value", 1}};
13185 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13186 CHECK_THROWS_WITH(j.patch(patch), "JSON patch must be an array of objects");
13187 }
13188
13189 SECTION("not an array of objects")
13190 {
13191 json j;
13192 json patch = {"op", "add", "path", "", "value", 1};
13193 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13194 CHECK_THROWS_WITH(j.patch(patch), "JSON patch must be an array of objects");
13195 }
13196
13197 SECTION("missing 'op'")
13198 {
13199 json j;
13200 json patch = {{{"foo", "bar"}}};
13201 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13202 CHECK_THROWS_WITH(j.patch(patch), "operation must have member 'op'");
13203 }
13204
13205 SECTION("non-string 'op'")
13206 {
13207 json j;
13208 json patch = {{{"op", 1}}};
13209 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13210 CHECK_THROWS_WITH(j.patch(patch), "operation must have string member 'op'");
13211 }
13212
13213 SECTION("invalid operation")
13214 {
13215 json j;
13216 json patch = {{{"op", "foo"}, {"path", ""}}};
13217 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13218 CHECK_THROWS_WITH(j.patch(patch), "operation value 'foo' is invalid");
13219 }
13220 }
13221
13222 SECTION("add")
13223 {
13224 SECTION("missing 'path'")
13225 {
13226 json j;
13227 json patch = {{{"op", "add"}}};
13228 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13229 CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have member 'path'");
13230 }
13231
13232 SECTION("non-string 'path'")
13233 {
13234 json j;
13235 json patch = {{{"op", "add"}, {"path", 1}}};
13236 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13237 CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have string member 'path'");
13238 }
13239
13240 SECTION("missing 'value'")
13241 {
13242 json j;
13243 json patch = {{{"op", "add"}, {"path", ""}}};
13244 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13245 CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have member 'value'");
13246 }
13247
13248 SECTION("invalid array index")
13249 {
13250 json j = {1, 2};
13251 json patch = {{{"op", "add"}, {"path", "/4"}, {"value", 4}}};
13252 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13253 CHECK_THROWS_WITH(j.patch(patch), "array index 4 is out of range");
13254 }
13255 }
13256
13257 SECTION("remove")
13258 {
13259 SECTION("missing 'path'")
13260 {
13261 json j;
13262 json patch = {{{"op", "remove"}}};
13263 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13264 CHECK_THROWS_WITH(j.patch(patch), "operation 'remove' must have member 'path'");
13265 }
13266
13267 SECTION("non-string 'path'")
13268 {
13269 json j;
13270 json patch = {{{"op", "remove"}, {"path", 1}}};
13271 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13272 CHECK_THROWS_WITH(j.patch(patch), "operation 'remove' must have string member 'path'");
13273 }
13274
13275 SECTION("nonexisting target location (array)")
13276 {
13277 json j = {1, 2, 3};
13278 json patch = {{{"op", "remove"}, {"path", "/17"}}};
13279 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13280 CHECK_THROWS_WITH(j.patch(patch), "array index 17 is out of range");
13281 }
13282
13283 SECTION("nonexisting target location (object)")
13284 {
13285 json j = {{"foo", 1}, {"bar", 2}};
13286 json patch = {{{"op", "remove"}, {"path", "/baz"}}};
13287 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13288 CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found");
13289 }
13290
13291 SECTION("root element as target location")
13292 {
13293 json j = "string";
13294 json patch = {{{"op", "remove"}, {"path", ""}}};
13295 CHECK_THROWS_AS(j.patch(patch), std::domain_error);
13296 CHECK_THROWS_WITH(j.patch(patch), "JSON pointer has no parent");
13297 }
13298 }
13299
13300 SECTION("replace")
13301 {
13302 SECTION("missing 'path'")
13303 {
13304 json j;
13305 json patch = {{{"op", "replace"}}};
13306 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13307 CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have member 'path'");
13308 }
13309
13310 SECTION("non-string 'path'")
13311 {
13312 json j;
13313 json patch = {{{"op", "replace"}, {"path", 1}}};
13314 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13315 CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have string member 'path'");
13316 }
13317
13318 SECTION("missing 'value'")
13319 {
13320 json j;
13321 json patch = {{{"op", "replace"}, {"path", ""}}};
13322 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13323 CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have member 'value'");
13324 }
13325
13326 SECTION("nonexisting target location (array)")
13327 {
13328 json j = {1, 2, 3};
13329 json patch = {{{"op", "replace"}, {"path", "/17"}, {"value", 19}}};
13330 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13331 CHECK_THROWS_WITH(j.patch(patch), "array index 17 is out of range");
13332 }
13333
13334 SECTION("nonexisting target location (object)")
13335 {
13336 json j = {{"foo", 1}, {"bar", 2}};
13337 json patch = {{{"op", "replace"}, {"path", "/baz"}, {"value", 3}}};
13338 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13339 CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found");
13340 }
13341 }
13342
13343 SECTION("move")
13344 {
13345 SECTION("missing 'path'")
13346 {
13347 json j;
13348 json patch = {{{"op", "move"}}};
13349 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13350 CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have member 'path'");
13351 }
13352
13353 SECTION("non-string 'path'")
13354 {
13355 json j;
13356 json patch = {{{"op", "move"}, {"path", 1}}};
13357 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13358 CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have string member 'path'");
13359 }
13360
13361 SECTION("missing 'from'")
13362 {
13363 json j;
13364 json patch = {{{"op", "move"}, {"path", ""}}};
13365 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13366 CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have member 'from'");
13367 }
13368
13369 SECTION("non-string 'from'")
13370 {
13371 json j;
13372 json patch = {{{"op", "move"}, {"path", ""}, {"from", 1}}};
13373 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13374 CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have string member 'from'");
13375 }
13376
13377 SECTION("nonexisting from location (array)")
13378 {
13379 json j = {1, 2, 3};
13380 json patch = {{{"op", "move"}, {"path", "/0"}, {"from", "/5"}}};
13381 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13382 CHECK_THROWS_WITH(j.patch(patch), "array index 5 is out of range");
13383 }
13384
13385 SECTION("nonexisting from location (object)")
13386 {
13387 json j = {{"foo", 1}, {"bar", 2}};
13388 json patch = {{{"op", "move"}, {"path", "/baz"}, {"from", "/baz"}}};
13389 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13390 CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found");
13391 }
13392 }
13393
13394 SECTION("copy")
13395 {
13396 SECTION("missing 'path'")
13397 {
13398 json j;
13399 json patch = {{{"op", "copy"}}};
13400 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13401 CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have member 'path'");
13402 }
13403
13404 SECTION("non-string 'path'")
13405 {
13406 json j;
13407 json patch = {{{"op", "copy"}, {"path", 1}}};
13408 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13409 CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have string member 'path'");
13410 }
13411
13412 SECTION("missing 'from'")
13413 {
13414 json j;
13415 json patch = {{{"op", "copy"}, {"path", ""}}};
13416 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13417 CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have member 'from'");
13418 }
13419
13420 SECTION("non-string 'from'")
13421 {
13422 json j;
13423 json patch = {{{"op", "copy"}, {"path", ""}, {"from", 1}}};
13424 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13425 CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have string member 'from'");
13426 }
13427
13428 SECTION("nonexisting from location (array)")
13429 {
13430 json j = {1, 2, 3};
13431 json patch = {{{"op", "copy"}, {"path", "/0"}, {"from", "/5"}}};
13432 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13433 CHECK_THROWS_WITH(j.patch(patch), "array index 5 is out of range");
13434 }
13435
13436 SECTION("nonexisting from location (object)")
13437 {
13438 json j = {{"foo", 1}, {"bar", 2}};
13439 json patch = {{{"op", "copy"}, {"path", "/fob"}, {"from", "/baz"}}};
13440 CHECK_THROWS_AS(j.patch(patch), std::out_of_range);
13441 CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found");
13442 }
13443 }
13444
13445 SECTION("test")
13446 {
13447 SECTION("missing 'path'")
13448 {
13449 json j;
13450 json patch = {{{"op", "test"}}};
13451 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13452 CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have member 'path'");
13453 }
13454
13455 SECTION("non-string 'path'")
13456 {
13457 json j;
13458 json patch = {{{"op", "test"}, {"path", 1}}};
13459 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13460 CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have string member 'path'");
13461 }
13462
13463 SECTION("missing 'value'")
13464 {
13465 json j;
13466 json patch = {{{"op", "test"}, {"path", ""}}};
13467 CHECK_THROWS_AS(j.patch(patch), std::invalid_argument);
13468 CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have member 'value'");
13469 }
13470 }
13471 }
13472
13473 SECTION("Examples from jsonpatch.com")
13474 {
13475 SECTION("Simple Example")
13476 {
13477
13478 json doc = R"(
13479 {
13480 "baz": "qux",
13481 "foo": "bar"
13482 }
13483 )"_json;
13484
13485
13486 json patch = R"(
13487 [
13488 { "op": "replace", "path": "/baz", "value": "boo" },
13489 { "op": "add", "path": "/hello", "value": ["world"] },
13490 { "op": "remove", "path": "/foo"}
13491 ]
13492 )"_json;
13493
13494
13495 json result = R"(
13496 {
13497 "baz": "boo",
13498 "hello": ["world"]
13499 }
13500 )"_json;
13501
13502
13503 CHECK(doc.patch(patch) == result);
13504
13505
13506 CHECK(doc.patch(json::diff(doc, result)) == result);
13507 }
13508
13509 SECTION("Operations")
13510 {
13511
13512 json doc = R"(
13513 {
13514 "biscuits": [
13515 {"name":"Digestive"},
13516 {"name": "Choco Liebniz"}
13517 ]
13518 }
13519 )"_json;
13520
13521 SECTION("add")
13522 {
13523
13524 json patch = R"(
13525 [
13526 {"op": "add", "path": "/biscuits/1", "value": {"name": "Ginger Nut"}}
13527 ]
13528 )"_json;
13529
13530
13531 json result = R"(
13532 {
13533 "biscuits": [
13534 {"name": "Digestive"},
13535 {"name": "Ginger Nut"},
13536 {"name": "Choco Liebniz"}
13537 ]
13538 }
13539 )"_json;
13540
13541
13542 CHECK(doc.patch(patch) == result);
13543
13544
13545 CHECK(doc.patch(json::diff(doc, result)) == result);
13546 }
13547
13548 SECTION("remove")
13549 {
13550
13551 json patch = R"(
13552 [
13553 {"op": "remove", "path": "/biscuits"}
13554 ]
13555 )"_json;
13556
13557
13558 json result = R"(
13559 {}
13560 )"_json;
13561
13562
13563 CHECK(doc.patch(patch) == result);
13564
13565
13566 CHECK(doc.patch(json::diff(doc, result)) == result);
13567 }
13568
13569 SECTION("replace")
13570 {
13571
13572 json patch = R"(
13573 [
13574 {"op": "replace", "path": "/biscuits/0/name", "value": "Chocolate Digestive"}
13575 ]
13576 )"_json;
13577
13578
13579 json result = R"(
13580 {
13581 "biscuits": [
13582 {"name": "Chocolate Digestive"},
13583 {"name": "Choco Liebniz"}
13584 ]
13585 }
13586 )"_json;
13587
13588
13589 CHECK(doc.patch(patch) == result);
13590
13591
13592 CHECK(doc.patch(json::diff(doc, result)) == result);
13593 }
13594
13595 SECTION("copy")
13596 {
13597
13598 json patch = R"(
13599 [
13600 {"op": "copy", "from": "/biscuits/0", "path": "/best_biscuit"}
13601 ]
13602 )"_json;
13603
13604
13605 json result = R"(
13606 {
13607 "biscuits": [
13608 {"name": "Digestive"},
13609 {"name": "Choco Liebniz"}
13610 ],
13611 "best_biscuit": {
13612 "name": "Digestive"
13613 }
13614 }
13615 )"_json;
13616
13617
13618 CHECK(doc.patch(patch) == result);
13619
13620
13621 CHECK(doc.patch(json::diff(doc, result)) == result);
13622 }
13623
13624 SECTION("move")
13625 {
13626
13627 json patch = R"(
13628 [
13629 {"op": "move", "from": "/biscuits", "path": "/cookies"}
13630 ]
13631 )"_json;
13632
13633
13634 json result = R"(
13635 {
13636 "cookies": [
13637 {"name": "Digestive"},
13638 {"name": "Choco Liebniz"}
13639 ]
13640 }
13641 )"_json;
13642
13643
13644 CHECK(doc.patch(patch) == result);
13645
13646
13647 CHECK(doc.patch(json::diff(doc, result)) == result);
13648 }
13649
13650 SECTION("test")
13651 {
13652
13653 json patch = R"(
13654 [
13655 {"op": "test", "path": "/best_biscuit/name", "value": "Choco Liebniz"}
13656 ]
13657 )"_json;
13658
13659
13660 CHECK_THROWS_AS(doc.patch(patch), std::domain_error);
13661 CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump());
13662 }
13663 }
13664 }
13665
13666 SECTION("Examples from bruth.github.io/jsonpatch-js")
13667 {
13668 SECTION("add")
13669 {
13670 CHECK(R"( {} )"_json.patch(
13671 R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json
13672 ) == R"( {"foo": "bar"} )"_json);
13673
13674 CHECK(R"( {"foo": [1, 3]} )"_json.patch(
13675 R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json
13676 ) == R"( {"foo": "bar"} )"_json);
13677
13678 CHECK(R"( {"foo": [{}]} )"_json.patch(
13679 R"( [{"op": "add", "path": "/foo/0/bar", "value": "baz"}] )"_json
13680 ) == R"( {"foo": [{"bar": "baz"}]} )"_json);
13681 }
13682
13683 SECTION("remove")
13684 {
13685 CHECK(R"( {"foo": "bar"} )"_json.patch(
13686 R"( [{"op": "remove", "path": "/foo"}] )"_json
13687 ) == R"( {} )"_json);
13688
13689 CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
13690 R"( [{"op": "remove", "path": "/foo/1"}] )"_json
13691 ) == R"( {"foo": [1, 3]} )"_json);
13692
13693 CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(
13694 R"( [{"op": "remove", "path": "/foo/0/bar"}] )"_json
13695 ) == R"( {"foo": [{}]} )"_json);
13696 }
13697
13698 SECTION("replace")
13699 {
13700 CHECK(R"( {"foo": "bar"} )"_json.patch(
13701 R"( [{"op": "replace", "path": "/foo", "value": 1}] )"_json
13702 ) == R"( {"foo": 1} )"_json);
13703
13704 CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
13705 R"( [{"op": "replace", "path": "/foo/1", "value": 4}] )"_json
13706 ) == R"( {"foo": [1, 4, 3]} )"_json);
13707
13708 CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(
13709 R"( [{"op": "replace", "path": "/foo/0/bar", "value": 1}] )"_json
13710 ) == R"( {"foo": [{"bar": 1}]} )"_json);
13711 }
13712
13713 SECTION("move")
13714 {
13715 CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
13716 R"( [{"op": "move", "from": "/foo", "path": "/bar"}] )"_json
13717 ) == R"( {"bar": [1, 2, 3]} )"_json);
13718 }
13719
13720 SECTION("copy")
13721 {
13722 CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
13723 R"( [{"op": "copy", "from": "/foo/1", "path": "/bar"}] )"_json
13724 ) == R"( {"foo": [1, 2, 3], "bar": 2} )"_json);
13725 }
13726
13727 SECTION("copy")
13728 {
13729 CHECK_NOTHROW(R"( {"foo": "bar"} )"_json.patch(
13730 R"( [{"op": "test", "path": "/foo", "value": "bar"}] )"_json));
13731 }
13732 }
13733 }
13734
13735 TEST_CASE("regression tests")
13736 {
13737 SECTION("issue #60 - Double quotation mark is not parsed correctly")
13738 {
13739 SECTION("escape_dobulequote")
13740 {
13741 auto s = "[\"\\\"foo\\\"\"]";
13742 json j = json::parse(s);
13743 auto expected = R"(["\"foo\""])"_json;
13744 CHECK(j == expected);
13745 }
13746 }
13747
13748 SECTION("issue #70 - Handle infinity and NaN cases")
13749 {
13750 SECTION("NAN value")
13751 {
13752 CHECK(json(NAN) == json());
13753 CHECK(json(json::number_float_t(NAN)) == json());
13754 }
13755
13756 SECTION("infinity")
13757 {
13758 CHECK(json(INFINITY) == json());
13759 CHECK(json(json::number_float_t(INFINITY)) == json());
13760 }
13761 }
13762
13763 SECTION("pull request #71 - handle enum type")
13764 {
13765 enum { t = 0 };
13766 json j = json::array();
13767 j.push_back(t);
13768
13769 j.push_back(json::object(
13770 {
13771 {"game_type", t}
13772 }));
13773 }
13774
13775 SECTION("issue #76 - dump() / parse() not idempotent")
13776 {
13777 // create JSON object
13778 json fields;
13779 fields["one"] = std::string("one");
13780 fields["two"] = std::string("two three");
13781 fields["three"] = std::string("three \"four\"");
13782
13783
13784 std::string payload = fields.dump();
13785 json parsed_fields = json::parse(payload);
13786
13787
13788 CHECK(parsed_fields["one"] == fields["one"]);
13789 CHECK(parsed_fields["two"] == fields["two"]);
13790 CHECK(parsed_fields["three"] == fields["three"]);
13791
13792
13793 CHECK(parsed_fields["one"] == std::string("one"));
13794 CHECK(parsed_fields["two"] == std::string("two three"));
13795 CHECK(parsed_fields["three"] == std::string("three \"four\""));
13796
13797
13798 CHECK(parsed_fields == fields);
13799
13800
13801 CHECK(fields.dump() == parsed_fields.dump());
13802
13803
13804 CHECK(fields == json::parse(fields.dump()));
13805 }
13806
13807 SECTION("issue #82 - lexer::get_number return NAN")
13808 {
13809 const auto content = R"(
13810 {
13811 "Test":"Test1",
13812 "Number":100,
13813 "Foo":42.42
13814 })";
13815
13816 std::stringstream ss;
13817 ss << content;
13818 json j;
13819 ss >> j;
13820
13821 std::string test = j["Test"];
13822 CHECK(test == "Test1");
13823 int number = j["Number"];
13824 CHECK(number == 100);
13825 float foo = j["Foo"];
13826 CHECK(foo == Approx(42.42));
13827 }
13828
13829 SECTION("issue #89 - nonstandard integer type")
13830 {
13831
13832 using custom_json =
13833 nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
13834 custom_json j;
13835 j["int_1"] = 1;
13836
13837 CHECK(static_cast<int>(j["int_1"]) == 1);
13838
13839
13840
13841
13842 j = 4294967296U;
13843 CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_unsigned));
13844 CHECK(j.get<uint32_t>() == 0);
13845
13846
13847 j = custom_json::parse("4294967296");
13848 CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
13849 CHECK(j.get<float>() == 4294967296.0f);
13850
13851
13852 j = -2147483649LL;
13853 CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_integer));
13854 CHECK(j.get<int32_t>() == 2147483647);
13855
13856
13857 j = custom_json::parse("-2147483649");
13858 CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
13859 CHECK(j.get<float>() == -2147483650.0f);
13860 }
13861
13862 SECTION("issue #93 reverse_iterator operator inheritance problem")
13863 {
13864 {
13865 json a = {1, 2, 3};
13866 json::reverse_iterator rit = a.rbegin();
13867 ++rit;
13868 CHECK(*rit == json(2));
13869 CHECK(rit.value() == json(2));
13870 }
13871 {
13872 json a = {1, 2, 3};
13873 json::reverse_iterator rit = ++a.rbegin();
13874 }
13875 {
13876 json a = {1, 2, 3};
13877 json::reverse_iterator rit = a.rbegin();
13878 ++rit;
13879 json b = {0, 0, 0};
13880 std::transform(rit, a.rend(), b.rbegin(), [](json el)
13881 {
13882 return el;
13883 });
13884 CHECK(b == json({0, 1, 2}));
13885 }
13886 {
13887 json a = {1, 2, 3};
13888 json b = {0, 0, 0};
13889 std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)
13890 {
13891 return el;
13892 });
13893 CHECK(b == json({0, 1, 2}));
13894 }
13895 }
13896
13897 SECTION("issue #100 - failed to iterator json object with reverse_iterator")
13898 {
13899 json config =
13900 {
13901 { "111", 111 },
13902 { "112", 112 },
13903 { "113", 113 }
13904 };
13905
13906 std::stringstream ss;
13907
13908 for (auto it = config.begin(); it != config.end(); ++it)
13909 {
13910 ss << it.key() << ": " << it.value() << '\n';
13911 }
13912
13913 for (auto it = config.rbegin(); it != config.rend(); ++it)
13914 {
13915 ss << it.key() << ": " << it.value() << '\n';
13916 }
13917
13918 CHECK(ss.str() == "111: 111\n112: 112\n113: 113\n113: 113\n112: 112\n111: 111\n");
13919 }
13920
13921 SECTION("issue #101 - binary string causes numbers to be dumped as hex")
13922 {
13923 int64_t number = 10;
13924 std::string bytes{"\x00" "asdf\n", 6};
13925 json j;
13926 j["int64"] = number;
13927 j["binary string"] = bytes;
13928
13929
13930 CHECK(j.dump() == "{\"binary string\":\"\\u0000asdf\\n\",\"int64\":10}");
13931 }
13932
13933 SECTION("issue #111 - subsequent unicode chars")
13934 {
13935 std::string bytes{0x7, 0x7};
13936 json j;
13937 j["string"] = bytes;
13938 CHECK(j["string"] == "\u0007\u0007");
13939 }
13940
13941 SECTION("issue #144 - implicit assignment to std::string fails")
13942 {
13943 json o = {{"name", "value"}};
13944
13945 std::string s1 = o["name"];
13946 CHECK(s1 == "value");
13947
13948 std::string s2;
13949 s2 = o["name"];
13950
13951 CHECK(s2 == "value");
13952 }
13953
13954 SECTION("issue #146 - character following a surrogate pair is skipped")
13955 {
13956 CHECK(json::parse("\"\\ud80c\\udc60abc\"").get<json::string_t>() == u8"\U00013060abc");
13957 }
13958
13959 SECTION("issue #171 - Cannot index by key of type static constexpr const char*")
13960 {
13961 json j;
13962
13963
13964 char array_key[] = "Key1";
13965 CHECK_NOTHROW(j[array_key] = 1);
13966 CHECK(j[array_key] == json(1));
13967
13968
13969 const char const_array_key[] = "Key2";
13970 CHECK_NOTHROW(j[const_array_key] = 2);
13971 CHECK(j[const_array_key] == json(2));
13972
13973
13974 char _ptr_key[] = "Key3";
13975 char* ptr_key = &_ptr_key[0];
13976 CHECK_NOTHROW(j[ptr_key] = 3);
13977 CHECK(j[ptr_key] == json(3));
13978
13979
13980 const char* const_ptr_key = "Key4";
13981 CHECK_NOTHROW(j[const_ptr_key] = 4);
13982 CHECK(j[const_ptr_key] == json(4));
13983
13984
13985 static constexpr const char* constexpr_ptr_key = "Key5";
13986 CHECK_NOTHROW(j[constexpr_ptr_key] = 5);
13987 CHECK(j[constexpr_ptr_key] == json(5));
13988
13989 const json j_const = j;
13990
13991
13992 CHECK(j_const[array_key] == json(1));
13993
13994
13995 CHECK(j_const[const_array_key] == json(2));
13996
13997
13998 CHECK(j_const[ptr_key] == json(3));
13999
14000
14001 CHECK(j_const[const_ptr_key] == json(4));
14002
14003
14004 CHECK(j_const[constexpr_ptr_key] == json(5));
14005 }
14006
14007 SECTION("issue #186 miloyip/nativejson-benchmark: floating-point parsing")
14008 {
14009 json j;
14010
14011 j = json::parse("-0.0");
14012 CHECK(j.get<double>() == -0.0);
14013
14014 j = json::parse("2.22507385850720113605740979670913197593481954635164564e-308");
14015 CHECK(j.get<double>() == 2.2250738585072009e-308);
14016
14017 j = json::parse("0.999999999999999944488848768742172978818416595458984374");
14018 CHECK(j.get<double>() == 0.99999999999999989);
14019
14020 j = json::parse("1.00000000000000011102230246251565404236316680908203126");
14021 CHECK(j.get<double>() == 1.00000000000000022);
14022
14023 j = json::parse("7205759403792793199999e-5");
14024 CHECK(j.get<double>() == 72057594037927928.0);
14025
14026 j = json::parse("922337203685477529599999e-5");
14027 CHECK(j.get<double>() == 9223372036854774784.0);
14028
14029 j = json::parse("1014120480182583464902367222169599999e-5");
14030 CHECK(j.get<double>() == 10141204801825834086073718800384.0);
14031
14032 j = json::parse("5708990770823839207320493820740630171355185151999e-3");
14033 CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);
14034
14035
14036
14037
14038 nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> j_float =
14039 1.23e25f;
14040 CHECK(j_float.get<float>() == 1.23e25f);
14041
14042
14043 nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> j_double =
14044 1.23e35f;
14045 CHECK(j_double.get<double>() == 1.23e35f);
14046
14047
14048 nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>
14049 j_long_double = 1.23e45L;
14050 CHECK(j_long_double.get<long double>() == 1.23e45L);
14051 }
14052
14053 SECTION("issue #228 - double values are serialized with commas as decimal points")
14054 {
14055 json j1a = 23.42;
14056 json j1b = json::parse("23.42");
14057
14058 json j2a = 2342e-2;
14059
14060
14061
14062 json j3a = 10E3;
14063 json j3b = json::parse("10E3");
14064 json j3c = json::parse("10e3");
14065
14066
14067 class CommaDecimalSeparator : public std::numpunct<char>
14068 {
14069 protected:
14070 char do_decimal_point() const
14071 {
14072 return ',';
14073 }
14074 };
14075
14076
14077 std::locale::global(std::locale(std::locale(), new CommaDecimalSeparator));
14078
14079 CHECK(j1a.dump() == "23.42");
14080 CHECK(j1b.dump() == "23.42");
14081
14082 CHECK(j2a.dump() == "23.42");
14083
14084
14085
14086 CHECK(j3a.dump() == "10000");
14087 CHECK(j3b.dump() == "10000");
14088 CHECK(j3c.dump() == "10000");
14089
14090
14091 }
14092
14093 SECTION("issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator")
14094 {
14095 json source = {"a", "b", "c"};
14096 json expected = {"a", "b"};
14097 json dest;
14098
14099 std::copy_n(std::make_move_iterator(source.begin()), 2, std::back_inserter(dest));
14100
14101 CHECK(dest == expected);
14102 }
14103
14104 SECTION("issue #235 - ambiguous overload for 'push_back' and 'operator+='")
14105 {
14106 json data = {{"key", "value"}};
14107 data.push_back({"key2", "value2"});
14108 data += {"key3", "value3"};
14109
14110 CHECK(data == json({{"key", "value"}, {"key2", "value2"}, {"key3", "value3"}}));
14111 }
14112
14113 SECTION("issue #269 - diff generates incorrect patch when removing multiple array elements")
14114 {
14115 json doc = R"( { "arr1": [1, 2, 3, 4] } )"_json;
14116 json expected = R"( { "arr1": [1, 2] } )"_json;
14117
14118
14119 CHECK(doc.patch(json::diff(doc, expected)) == expected);
14120 }
14121 }
14122
14123
14124
14125 template<class T>
14126 struct my_allocator : std::allocator<T>
14127 {
14128 template<class... Args>
14129 void construct(T*, Args&& ...)
14130 {
14131 throw std::bad_alloc();
14132 }
14133 };
14134
14135 TEST_CASE("bad_alloc")
14136 {
14137 SECTION("bad_alloc")
14138 {
14139
14140 using my_json = nlohmann::basic_json<std::map,
14141 std::vector,
14142 std::string,
14143 bool,
14144 std::int64_t,
14145 std::uint64_t,
14146 double,
14147 my_allocator>;
14148
14149
14150 CHECK_THROWS_AS(my_json j(my_json::value_t::object), std::bad_alloc);
14151 }
14152 }