1 // __ _____ _____ _____ 2 // __| | __| | | | JSON for Modern C++ (supporting code) 3 // | | |__ | | | | | | version 3.11.3 4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 // 6 // Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>. 7 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me> 8 // SPDX-License-Identifier: MIT 9 10 #include "doctest_compatibility.h" 11 12 #include <nlohmann/json.hpp> 13 #ifdef JSON_TEST_NO_GLOBAL_UDLS 14 using namespace nlohmann::literals; // NOLINT(google-build-using-namespace) 15 #endif 16 17 // build test with C++14 18 // JSON_HAS_CPP_14 19 20 TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_json) 21 { 22 SECTION("object") 23 { 24 Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; 25 const Json j_const = j; 26 27 SECTION("access specified element with bounds checking") 28 { 29 SECTION("access within bounds") 30 { 31 CHECK(j.at("integer") == Json(1)); 32 CHECK(j.at("unsigned") == Json(1u)); 33 CHECK(j.at("boolean") == Json(true)); 34 CHECK(j.at("null") == Json(nullptr)); 35 CHECK(j.at("string") == Json("hello world")); 36 CHECK(j.at("floating") == Json(42.23)); 37 CHECK(j.at("object") == Json::object()); 38 CHECK(j.at("array") == Json({1, 2, 3})); 39 40 CHECK(j_const.at("integer") == Json(1)); 41 CHECK(j_const.at("unsigned") == Json(1u)); 42 CHECK(j_const.at("boolean") == Json(true)); 43 CHECK(j_const.at("null") == Json(nullptr)); 44 CHECK(j_const.at("string") == Json("hello world")); 45 CHECK(j_const.at("floating") == Json(42.23)); 46 CHECK(j_const.at("object") == Json::object()); 47 CHECK(j_const.at("array") == Json({1, 2, 3})); 48 49 #ifdef JSON_HAS_CPP_17 50 CHECK(j.at(std::string_view("integer")) == Json(1)); 51 CHECK(j.at(std::string_view("unsigned")) == Json(1u)); 52 CHECK(j.at(std::string_view("boolean")) == Json(true)); 53 CHECK(j.at(std::string_view("null")) == Json(nullptr)); 54 CHECK(j.at(std::string_view("string")) == Json("hello world")); 55 CHECK(j.at(std::string_view("floating")) == Json(42.23)); 56 CHECK(j.at(std::string_view("object")) == Json::object()); 57 CHECK(j.at(std::string_view("array")) == Json({1, 2, 3})); 58 59 CHECK(j_const.at(std::string_view("integer")) == Json(1)); 60 CHECK(j_const.at(std::string_view("unsigned")) == Json(1u)); 61 CHECK(j_const.at(std::string_view("boolean")) == Json(true)); 62 CHECK(j_const.at(std::string_view("null")) == Json(nullptr)); 63 CHECK(j_const.at(std::string_view("string")) == Json("hello world")); 64 CHECK(j_const.at(std::string_view("floating")) == Json(42.23)); 65 CHECK(j_const.at(std::string_view("object")) == Json::object()); 66 CHECK(j_const.at(std::string_view("array")) == Json({1, 2, 3})); 67 #endif 68 } 69 70 SECTION("access outside bounds") 71 { 72 CHECK_THROWS_WITH_AS(j.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); 73 CHECK_THROWS_WITH_AS(j_const.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); 74 75 #ifdef JSON_HAS_CPP_17 76 CHECK_THROWS_WITH_AS(j.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); 77 CHECK_THROWS_WITH_AS(j_const.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); 78 #endif 79 } 80 81 SECTION("access on non-object type") 82 { 83 SECTION("null") 84 { 85 Json j_nonobject(Json::value_t::null); 86 const Json j_nonobject_const(j_nonobject); 87 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); 88 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); 89 90 #ifdef JSON_HAS_CPP_17 91 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); 92 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); 93 #endif 94 } 95 96 SECTION("boolean") 97 { 98 Json j_nonobject(Json::value_t::boolean); 99 const Json j_nonobject_const(j_nonobject); 100 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); 101 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); 102 103 #ifdef JSON_HAS_CPP_17 104 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); 105 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); 106 #endif 107 } 108 109 SECTION("string") 110 { 111 Json j_nonobject(Json::value_t::string); 112 const Json j_nonobject_const(j_nonobject); 113 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); 114 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); 115 116 #ifdef JSON_HAS_CPP_17 117 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); 118 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); 119 #endif 120 } 121 122 SECTION("array") 123 { 124 Json j_nonobject(Json::value_t::array); 125 const Json j_nonobject_const(j_nonobject); 126 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); 127 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); 128 129 #ifdef JSON_HAS_CPP_17 130 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); 131 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); 132 #endif 133 } 134 135 SECTION("number (integer)") 136 { 137 Json j_nonobject(Json::value_t::number_integer); 138 const Json j_nonobject_const(j_nonobject); 139 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 140 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 141 142 #ifdef JSON_HAS_CPP_17 143 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 144 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 145 #endif 146 } 147 148 SECTION("number (unsigned)") 149 { 150 Json j_nonobject(Json::value_t::number_unsigned); 151 const Json j_nonobject_const(j_nonobject); 152 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 153 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 154 155 #ifdef JSON_HAS_CPP_17 156 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 157 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 158 #endif 159 } 160 161 SECTION("number (floating-point)") 162 { 163 Json j_nonobject(Json::value_t::number_float); 164 const Json j_nonobject_const(j_nonobject); 165 CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 166 CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 167 168 #ifdef JSON_HAS_CPP_17 169 CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 170 CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); 171 #endif 172 } 173 } 174 } 175 176 SECTION("access specified element with default value") 177 { 178 SECTION("given a key") 179 { 180 SECTION("access existing value") 181 { 182 CHECK(j.value("integer", 2) == 1); 183 CHECK(j.value("integer", 1.0) == Approx(1)); 184 CHECK(j.value("unsigned", 2) == 1u); 185 CHECK(j.value("unsigned", 1.0) == Approx(1u)); 186 CHECK(j.value("null", Json(1)) == Json()); 187 CHECK(j.value("boolean", false) == true); 188 CHECK(j.value("string", "bar") == "hello world"); 189 CHECK(j.value("string", std::string("bar")) == "hello world"); 190 CHECK(j.value("floating", 12.34) == Approx(42.23)); 191 CHECK(j.value("floating", 12) == 42); 192 CHECK(j.value("object", Json({{"foo", "bar"}})) == Json::object()); 193 CHECK(j.value("array", Json({10, 100})) == Json({1, 2, 3})); 194 195 CHECK(j_const.value("integer", 2) == 1); 196 CHECK(j_const.value("integer", 1.0) == Approx(1)); 197 CHECK(j_const.value("unsigned", 2) == 1u); 198 CHECK(j_const.value("unsigned", 1.0) == Approx(1u)); 199 CHECK(j_const.value("boolean", false) == true); 200 CHECK(j_const.value("string", "bar") == "hello world"); 201 CHECK(j_const.value("string", std::string("bar")) == "hello world"); 202 CHECK(j_const.value("floating", 12.34) == Approx(42.23)); 203 CHECK(j_const.value("floating", 12) == 42); 204 CHECK(j_const.value("object", Json({{"foo", "bar"}})) == Json::object()); 205 CHECK(j_const.value("array", Json({10, 100})) == Json({1, 2, 3})); 206 207 #ifdef JSON_HAS_CPP_17 208 CHECK(j.value(std::string_view("integer"), 2) == 1); 209 CHECK(j.value(std::string_view("integer"), 1.0) == Approx(1)); 210 CHECK(j.value(std::string_view("unsigned"), 2) == 1u); 211 CHECK(j.value(std::string_view("unsigned"), 1.0) == Approx(1u)); 212 CHECK(j.value(std::string_view("null"), Json(1)) == Json()); 213 CHECK(j.value(std::string_view("boolean"), false) == true); 214 CHECK(j.value(std::string_view("string"), "bar") == "hello world"); 215 CHECK(j.value(std::string_view("string"), std::string("bar")) == "hello world"); 216 CHECK(j.value(std::string_view("floating"), 12.34) == Approx(42.23)); 217 CHECK(j.value(std::string_view("floating"), 12) == 42); 218 CHECK(j.value(std::string_view("object"), Json({{"foo", "bar"}})) == Json::object()); 219 CHECK(j.value(std::string_view("array"), Json({10, 100})) == Json({1, 2, 3})); 220 221 CHECK(j_const.value(std::string_view("integer"), 2) == 1); 222 CHECK(j_const.value(std::string_view("integer"), 1.0) == Approx(1)); 223 CHECK(j_const.value(std::string_view("unsigned"), 2) == 1u); 224 CHECK(j_const.value(std::string_view("unsigned"), 1.0) == Approx(1u)); 225 CHECK(j_const.value(std::string_view("boolean"), false) == true); 226 CHECK(j_const.value(std::string_view("string"), "bar") == "hello world"); 227 CHECK(j_const.value(std::string_view("string"), std::string("bar")) == "hello world"); 228 CHECK(j_const.value(std::string_view("floating"), 12.34) == Approx(42.23)); 229 CHECK(j_const.value(std::string_view("floating"), 12) == 42); 230 CHECK(j_const.value(std::string_view("object"), Json({{"foo", "bar"}})) == Json::object()); 231 CHECK(j_const.value(std::string_view("array"), Json({10, 100})) == Json({1, 2, 3})); 232 #endif 233 } 234 235 SECTION("access non-existing value") 236 { 237 CHECK(j.value("_", 2) == 2); 238 CHECK(j.value("_", 2u) == 2u); 239 CHECK(j.value("_", false) == false); 240 CHECK(j.value("_", "bar") == "bar"); 241 CHECK(j.value("_", 12.34) == Approx(12.34)); 242 CHECK(j.value("_", Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 243 CHECK(j.value("_", Json({10, 100})) == Json({10, 100})); 244 245 CHECK(j_const.value("_", 2) == 2); 246 CHECK(j_const.value("_", 2u) == 2u); 247 CHECK(j_const.value("_", false) == false); 248 CHECK(j_const.value("_", "bar") == "bar"); 249 CHECK(j_const.value("_", 12.34) == Approx(12.34)); 250 CHECK(j_const.value("_", Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 251 CHECK(j_const.value("_", Json({10, 100})) == Json({10, 100})); 252 253 #ifdef JSON_HAS_CPP_17 254 CHECK(j.value(std::string_view("_"), 2) == 2); 255 CHECK(j.value(std::string_view("_"), 2u) == 2u); 256 CHECK(j.value(std::string_view("_"), false) == false); 257 CHECK(j.value(std::string_view("_"), "bar") == "bar"); 258 CHECK(j.value(std::string_view("_"), 12.34) == Approx(12.34)); 259 CHECK(j.value(std::string_view("_"), Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 260 CHECK(j.value(std::string_view("_"), Json({10, 100})) == Json({10, 100})); 261 262 CHECK(j_const.value(std::string_view("_"), 2) == 2); 263 CHECK(j_const.value(std::string_view("_"), 2u) == 2u); 264 CHECK(j_const.value(std::string_view("_"), false) == false); 265 CHECK(j_const.value(std::string_view("_"), "bar") == "bar"); 266 CHECK(j_const.value(std::string_view("_"), 12.34) == Approx(12.34)); 267 CHECK(j_const.value(std::string_view("_"), Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 268 CHECK(j_const.value(std::string_view("_"), Json({10, 100})) == Json({10, 100})); 269 #endif 270 } 271 272 SECTION("access on non-object type") 273 { 274 SECTION("null") 275 { 276 Json j_nonobject(Json::value_t::null); 277 const Json j_nonobject_const(Json::value_t::null); 278 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 279 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 280 281 #ifdef JSON_HAS_CPP_17 282 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 283 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 284 #endif 285 } 286 287 SECTION("boolean") 288 { 289 Json j_nonobject(Json::value_t::boolean); 290 const Json j_nonobject_const(Json::value_t::boolean); 291 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 292 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 293 294 #ifdef JSON_HAS_CPP_17 295 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 296 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 297 #endif 298 } 299 300 SECTION("string") 301 { 302 Json j_nonobject(Json::value_t::string); 303 const Json j_nonobject_const(Json::value_t::string); 304 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 305 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 306 307 #ifdef JSON_HAS_CPP_17 308 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 309 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 310 #endif 311 } 312 313 SECTION("array") 314 { 315 Json j_nonobject(Json::value_t::array); 316 const Json j_nonobject_const(Json::value_t::array); 317 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 318 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 319 320 #ifdef JSON_HAS_CPP_17 321 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 322 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 323 #endif 324 } 325 326 SECTION("number (integer)") 327 { 328 Json j_nonobject(Json::value_t::number_integer); 329 const Json j_nonobject_const(Json::value_t::number_integer); 330 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 331 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 332 333 #ifdef JSON_HAS_CPP_17 334 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 335 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 336 #endif 337 } 338 339 SECTION("number (unsigned)") 340 { 341 Json j_nonobject(Json::value_t::number_unsigned); 342 const Json j_nonobject_const(Json::value_t::number_unsigned); 343 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 344 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 345 346 #ifdef JSON_HAS_CPP_17 347 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 348 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 349 #endif 350 } 351 352 SECTION("number (floating-point)") 353 { 354 Json j_nonobject(Json::value_t::number_float); 355 const Json j_nonobject_const(Json::value_t::number_float); 356 CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 357 CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 358 359 #ifdef JSON_HAS_CPP_17 360 CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 361 CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 362 #endif 363 } 364 } 365 } 366 367 SECTION("given a JSON pointer") 368 { 369 SECTION("access existing value") 370 { 371 CHECK(j.value("/integer"_json_pointer, 2) == 1); 372 CHECK(j.value("/integer"_json_pointer, 1.0) == Approx(1)); 373 CHECK(j.value("/unsigned"_json_pointer, 2) == 1u); 374 CHECK(j.value("/unsigned"_json_pointer, 1.0) == Approx(1u)); 375 CHECK(j.value("/null"_json_pointer, Json(1)) == Json()); 376 CHECK(j.value("/boolean"_json_pointer, false) == true); 377 CHECK(j.value("/string"_json_pointer, "bar") == "hello world"); 378 CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world"); 379 CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23)); 380 CHECK(j.value("/floating"_json_pointer, 12) == 42); 381 CHECK(j.value("/object"_json_pointer, Json({{"foo", "bar"}})) == Json::object()); 382 CHECK(j.value("/array"_json_pointer, Json({10, 100})) == Json({1, 2, 3})); 383 384 CHECK(j_const.value("/integer"_json_pointer, 2) == 1); 385 CHECK(j_const.value("/integer"_json_pointer, 1.0) == Approx(1)); 386 CHECK(j_const.value("/unsigned"_json_pointer, 2) == 1u); 387 CHECK(j_const.value("/unsigned"_json_pointer, 1.0) == Approx(1u)); 388 CHECK(j_const.value("/boolean"_json_pointer, false) == true); 389 CHECK(j_const.value("/string"_json_pointer, "bar") == "hello world"); 390 CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world"); 391 CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23)); 392 CHECK(j_const.value("/floating"_json_pointer, 12) == 42); 393 CHECK(j_const.value("/object"_json_pointer, Json({{"foo", "bar"}})) == Json::object()); 394 CHECK(j_const.value("/array"_json_pointer, Json({10, 100})) == Json({1, 2, 3})); 395 } 396 397 SECTION("access on non-object type") 398 { 399 SECTION("null") 400 { 401 Json j_nonobject(Json::value_t::null); 402 const Json j_nonobject_const(Json::value_t::null); 403 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 404 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 405 } 406 407 SECTION("boolean") 408 { 409 Json j_nonobject(Json::value_t::boolean); 410 const Json j_nonobject_const(Json::value_t::boolean); 411 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 412 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); 413 } 414 415 SECTION("string") 416 { 417 Json j_nonobject(Json::value_t::string); 418 const Json j_nonobject_const(Json::value_t::string); 419 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 420 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); 421 } 422 423 SECTION("array") 424 { 425 Json j_nonobject(Json::value_t::array); 426 const Json j_nonobject_const(Json::value_t::array); 427 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 428 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); 429 } 430 431 SECTION("number (integer)") 432 { 433 Json j_nonobject(Json::value_t::number_integer); 434 const Json j_nonobject_const(Json::value_t::number_integer); 435 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 436 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 437 } 438 439 SECTION("number (unsigned)") 440 { 441 Json j_nonobject(Json::value_t::number_unsigned); 442 const Json j_nonobject_const(Json::value_t::number_unsigned); 443 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 444 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 445 } 446 447 SECTION("number (floating-point)") 448 { 449 Json j_nonobject(Json::value_t::number_float); 450 const Json j_nonobject_const(Json::value_t::number_float); 451 CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 452 CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); 453 } 454 } 455 } 456 } 457 458 SECTION("non-const operator[]") 459 { 460 { 461 Json j_null; 462 CHECK(j_null.is_null()); 463 j_null["key"] = 1; 464 CHECK(j_null.is_object()); 465 CHECK(j_null.size() == 1); 466 j_null["key"] = 2; 467 CHECK(j_null.size() == 1); 468 } 469 #ifdef JSON_HAS_CPP_17 470 { 471 std::string_view const key = "key"; 472 Json j_null; 473 CHECK(j_null.is_null()); 474 j_null[key] = 1; 475 CHECK(j_null.is_object()); 476 CHECK(j_null.size() == 1); 477 j_null[key] = 2; 478 CHECK(j_null.size() == 1); 479 } 480 #endif 481 } 482 483 SECTION("front and back") 484 { 485 if (std::is_same<Json, nlohmann::ordered_json>::value) 486 { 487 // "integer" is the first key 488 CHECK(j.front() == Json(1)); 489 CHECK(j_const.front() == Json(1)); 490 // "array" is last key 491 CHECK(j.back() == Json({1, 2, 3})); 492 CHECK(j_const.back() == Json({1, 2, 3})); 493 } 494 else 495 { 496 // "array" is the smallest key 497 CHECK(j.front() == Json({1, 2, 3})); 498 CHECK(j_const.front() == Json({1, 2, 3})); 499 // "unsigned" is the largest key 500 CHECK(j.back() == Json(1u)); 501 CHECK(j_const.back() == Json(1u)); 502 } 503 } 504 505 SECTION("access specified element") 506 { 507 SECTION("access within bounds") 508 { 509 CHECK(j["integer"] == Json(1)); 510 CHECK(j[typename Json::object_t::key_type("integer")] == j["integer"]); 511 512 CHECK(j["unsigned"] == Json(1u)); 513 CHECK(j[typename Json::object_t::key_type("unsigned")] == j["unsigned"]); 514 515 CHECK(j["boolean"] == Json(true)); 516 CHECK(j[typename Json::object_t::key_type("boolean")] == j["boolean"]); 517 518 CHECK(j["null"] == Json(nullptr)); 519 CHECK(j[typename Json::object_t::key_type("null")] == j["null"]); 520 521 CHECK(j["string"] == Json("hello world")); 522 CHECK(j[typename Json::object_t::key_type("string")] == j["string"]); 523 524 CHECK(j["floating"] == Json(42.23)); 525 CHECK(j[typename Json::object_t::key_type("floating")] == j["floating"]); 526 527 CHECK(j["object"] == Json::object()); 528 CHECK(j[typename Json::object_t::key_type("object")] == j["object"]); 529 530 CHECK(j["array"] == Json({1, 2, 3})); 531 CHECK(j[typename Json::object_t::key_type("array")] == j["array"]); 532 533 CHECK(j_const["integer"] == Json(1)); 534 CHECK(j_const[typename Json::object_t::key_type("integer")] == j["integer"]); 535 536 CHECK(j_const["boolean"] == Json(true)); 537 CHECK(j_const[typename Json::object_t::key_type("boolean")] == j["boolean"]); 538 539 CHECK(j_const["null"] == Json(nullptr)); 540 CHECK(j_const[typename Json::object_t::key_type("null")] == j["null"]); 541 542 CHECK(j_const["string"] == Json("hello world")); 543 CHECK(j_const[typename Json::object_t::key_type("string")] == j["string"]); 544 545 CHECK(j_const["floating"] == Json(42.23)); 546 CHECK(j_const[typename Json::object_t::key_type("floating")] == j["floating"]); 547 548 CHECK(j_const["object"] == Json::object()); 549 CHECK(j_const[typename Json::object_t::key_type("object")] == j["object"]); 550 551 CHECK(j_const["array"] == Json({1, 2, 3})); 552 CHECK(j_const[typename Json::object_t::key_type("array")] == j["array"]); 553 } 554 555 #ifdef JSON_HAS_CPP_17 556 SECTION("access within bounds (string_view)") 557 { 558 CHECK(j["integer"] == Json(1)); 559 CHECK(j[std::string_view("integer")] == j["integer"]); 560 561 CHECK(j["unsigned"] == Json(1u)); 562 CHECK(j[std::string_view("unsigned")] == j["unsigned"]); 563 564 CHECK(j["boolean"] == Json(true)); 565 CHECK(j[std::string_view("boolean")] == j["boolean"]); 566 567 CHECK(j["null"] == Json(nullptr)); 568 CHECK(j[std::string_view("null")] == j["null"]); 569 570 CHECK(j["string"] == Json("hello world")); 571 CHECK(j[std::string_view("string")] == j["string"]); 572 573 CHECK(j["floating"] == Json(42.23)); 574 CHECK(j[std::string_view("floating")] == j["floating"]); 575 576 CHECK(j["object"] == Json::object()); 577 CHECK(j[std::string_view("object")] == j["object"]); 578 579 CHECK(j["array"] == Json({1, 2, 3})); 580 CHECK(j[std::string_view("array")] == j["array"]); 581 582 CHECK(j_const["integer"] == Json(1)); 583 CHECK(j_const[std::string_view("integer")] == j["integer"]); 584 585 CHECK(j_const["boolean"] == Json(true)); 586 CHECK(j_const[std::string_view("boolean")] == j["boolean"]); 587 588 CHECK(j_const["null"] == Json(nullptr)); 589 CHECK(j_const[std::string_view("null")] == j["null"]); 590 591 CHECK(j_const["string"] == Json("hello world")); 592 CHECK(j_const[std::string_view("string")] == j["string"]); 593 594 CHECK(j_const["floating"] == Json(42.23)); 595 CHECK(j_const[std::string_view("floating")] == j["floating"]); 596 597 CHECK(j_const["object"] == Json::object()); 598 CHECK(j_const[std::string_view("object")] == j["object"]); 599 600 CHECK(j_const["array"] == Json({1, 2, 3})); 601 CHECK(j_const[std::string_view("array")] == j["array"]); 602 } 603 #endif 604 605 SECTION("access on non-object type") 606 { 607 SECTION("null") 608 { 609 Json j_nonobject(Json::value_t::null); 610 Json j_nonobject2(Json::value_t::null); 611 const Json j_const_nonobject(j_nonobject); 612 613 CHECK_NOTHROW(j_nonobject["foo"]); 614 CHECK_NOTHROW(j_nonobject2[typename Json::object_t::key_type("foo")]); 615 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); 616 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); 617 618 #ifdef JSON_HAS_CPP_17 619 CHECK_NOTHROW(j_nonobject2[std::string_view("foo")]); 620 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); 621 #endif 622 } 623 624 SECTION("boolean") 625 { 626 Json j_nonobject(Json::value_t::boolean); 627 const Json j_const_nonobject(j_nonobject); 628 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 629 "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 630 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], 631 "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 632 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 633 "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 634 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 635 "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 636 637 #ifdef JSON_HAS_CPP_17 638 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 639 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); 640 #endif 641 } 642 643 SECTION("string") 644 { 645 Json j_nonobject(Json::value_t::string); 646 const Json j_const_nonobject(j_nonobject); 647 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 648 "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 649 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], 650 "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 651 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 652 "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 653 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 654 "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 655 656 #ifdef JSON_HAS_CPP_17 657 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 658 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); 659 #endif 660 } 661 662 SECTION("array") 663 { 664 Json j_nonobject(Json::value_t::array); 665 const Json j_const_nonobject(j_nonobject); 666 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 667 "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 668 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 669 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 670 "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 671 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 672 "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 673 674 #ifdef JSON_HAS_CPP_17 675 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 676 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); 677 #endif 678 } 679 680 SECTION("number (integer)") 681 { 682 Json j_nonobject(Json::value_t::number_integer); 683 const Json j_const_nonobject(j_nonobject); 684 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 685 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 686 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], 687 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 688 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 689 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 690 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 691 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 692 693 #ifdef JSON_HAS_CPP_17 694 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 695 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 696 #endif 697 } 698 699 SECTION("number (unsigned)") 700 { 701 Json j_nonobject(Json::value_t::number_unsigned); 702 const Json j_const_nonobject(j_nonobject); 703 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 704 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 705 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], 706 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 707 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 708 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 709 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 710 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 711 712 #ifdef JSON_HAS_CPP_17 713 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 714 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 715 #endif 716 } 717 718 SECTION("number (floating-point)") 719 { 720 Json j_nonobject(Json::value_t::number_float); 721 const Json j_const_nonobject(j_nonobject); 722 CHECK_THROWS_WITH_AS(j_nonobject["foo"], 723 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 724 CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], 725 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 726 CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], 727 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 728 CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], 729 "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 730 731 #ifdef JSON_HAS_CPP_17 732 CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 733 CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); 734 #endif 735 } 736 } 737 } 738 739 SECTION("remove specified element") 740 { 741 SECTION("remove element by key") 742 { 743 CHECK(j.find("integer") != j.end()); 744 CHECK(j.erase("integer") == 1); 745 CHECK(j.find("integer") == j.end()); 746 CHECK(j.erase("integer") == 0); 747 748 CHECK(j.find("unsigned") != j.end()); 749 CHECK(j.erase("unsigned") == 1); 750 CHECK(j.find("unsigned") == j.end()); 751 CHECK(j.erase("unsigned") == 0); 752 753 CHECK(j.find("boolean") != j.end()); 754 CHECK(j.erase("boolean") == 1); 755 CHECK(j.find("boolean") == j.end()); 756 CHECK(j.erase("boolean") == 0); 757 758 CHECK(j.find("null") != j.end()); 759 CHECK(j.erase("null") == 1); 760 CHECK(j.find("null") == j.end()); 761 CHECK(j.erase("null") == 0); 762 763 CHECK(j.find("string") != j.end()); 764 CHECK(j.erase("string") == 1); 765 CHECK(j.find("string") == j.end()); 766 CHECK(j.erase("string") == 0); 767 768 CHECK(j.find("floating") != j.end()); 769 CHECK(j.erase("floating") == 1); 770 CHECK(j.find("floating") == j.end()); 771 CHECK(j.erase("floating") == 0); 772 773 CHECK(j.find("object") != j.end()); 774 CHECK(j.erase("object") == 1); 775 CHECK(j.find("object") == j.end()); 776 CHECK(j.erase("object") == 0); 777 778 CHECK(j.find("array") != j.end()); 779 CHECK(j.erase("array") == 1); 780 CHECK(j.find("array") == j.end()); 781 CHECK(j.erase("array") == 0); 782 } 783 784 #ifdef JSON_HAS_CPP_17 785 SECTION("remove element by key (string_view)") 786 { 787 CHECK(j.find(std::string_view("integer")) != j.end()); 788 CHECK(j.erase(std::string_view("integer")) == 1); 789 CHECK(j.find(std::string_view("integer")) == j.end()); 790 CHECK(j.erase(std::string_view("integer")) == 0); 791 792 CHECK(j.find(std::string_view("unsigned")) != j.end()); 793 CHECK(j.erase(std::string_view("unsigned")) == 1); 794 CHECK(j.find(std::string_view("unsigned")) == j.end()); 795 CHECK(j.erase(std::string_view("unsigned")) == 0); 796 797 CHECK(j.find(std::string_view("boolean")) != j.end()); 798 CHECK(j.erase(std::string_view("boolean")) == 1); 799 CHECK(j.find(std::string_view("boolean")) == j.end()); 800 CHECK(j.erase(std::string_view("boolean")) == 0); 801 802 CHECK(j.find(std::string_view("null")) != j.end()); 803 CHECK(j.erase(std::string_view("null")) == 1); 804 CHECK(j.find(std::string_view("null")) == j.end()); 805 CHECK(j.erase(std::string_view("null")) == 0); 806 807 CHECK(j.find(std::string_view("string")) != j.end()); 808 CHECK(j.erase(std::string_view("string")) == 1); 809 CHECK(j.find(std::string_view("string")) == j.end()); 810 CHECK(j.erase(std::string_view("string")) == 0); 811 812 CHECK(j.find(std::string_view("floating")) != j.end()); 813 CHECK(j.erase(std::string_view("floating")) == 1); 814 CHECK(j.find(std::string_view("floating")) == j.end()); 815 CHECK(j.erase(std::string_view("floating")) == 0); 816 817 CHECK(j.find(std::string_view("object")) != j.end()); 818 CHECK(j.erase(std::string_view("object")) == 1); 819 CHECK(j.find(std::string_view("object")) == j.end()); 820 CHECK(j.erase(std::string_view("object")) == 0); 821 822 CHECK(j.find(std::string_view("array")) != j.end()); 823 CHECK(j.erase(std::string_view("array")) == 1); 824 CHECK(j.find(std::string_view("array")) == j.end()); 825 CHECK(j.erase(std::string_view("array")) == 0); 826 } 827 #endif 828 829 SECTION("remove element by iterator") 830 { 831 SECTION("erase(begin())") 832 { 833 { 834 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 835 typename Json::iterator const it2 = jobject.erase(jobject.begin()); 836 CHECK(jobject == Json({{"b", 1}, {"c", 17u}})); 837 CHECK(*it2 == Json(1)); 838 } 839 { 840 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 841 typename Json::const_iterator const it2 = jobject.erase(jobject.cbegin()); 842 CHECK(jobject == Json({{"b", 1}, {"c", 17u}})); 843 CHECK(*it2 == Json(1)); 844 } 845 } 846 847 SECTION("erase(begin(), end())") 848 { 849 { 850 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 851 typename Json::iterator it2 = jobject.erase(jobject.begin(), jobject.end()); 852 CHECK(jobject == Json::object()); 853 CHECK(it2 == jobject.end()); 854 } 855 { 856 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 857 typename Json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend()); 858 CHECK(jobject == Json::object()); 859 CHECK(it2 == jobject.cend()); 860 } 861 } 862 863 SECTION("erase(begin(), begin())") 864 { 865 { 866 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 867 typename Json::iterator const it2 = jobject.erase(jobject.begin(), jobject.begin()); 868 CHECK(jobject == Json({{"a", "a"}, {"b", 1}, {"c", 17u}})); 869 CHECK(*it2 == Json("a")); 870 } 871 { 872 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 873 typename Json::const_iterator const it2 = jobject.erase(jobject.cbegin(), jobject.cbegin()); 874 CHECK(jobject == Json({{"a", "a"}, {"b", 1}, {"c", 17u}})); 875 CHECK(*it2 == Json("a")); 876 } 877 } 878 879 SECTION("erase at offset") 880 { 881 { 882 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 883 typename Json::iterator const it = jobject.find("b"); 884 typename Json::iterator const it2 = jobject.erase(it); 885 CHECK(jobject == Json({{"a", "a"}, {"c", 17u}})); 886 CHECK(*it2 == Json(17)); 887 } 888 { 889 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 890 typename Json::const_iterator const it = jobject.find("b"); 891 typename Json::const_iterator const it2 = jobject.erase(it); 892 CHECK(jobject == Json({{"a", "a"}, {"c", 17u}})); 893 CHECK(*it2 == Json(17)); 894 } 895 } 896 897 SECTION("erase subrange") 898 { 899 { 900 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 901 typename Json::iterator const it2 = jobject.erase(jobject.find("b"), jobject.find("e")); 902 CHECK(jobject == Json({{"a", "a"}, {"e", true}})); 903 CHECK(*it2 == Json(true)); 904 } 905 { 906 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 907 typename Json::const_iterator const it2 = jobject.erase(jobject.find("b"), jobject.find("e")); 908 CHECK(jobject == Json({{"a", "a"}, {"e", true}})); 909 CHECK(*it2 == Json(true)); 910 } 911 } 912 913 SECTION("different objects") 914 { 915 { 916 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 917 Json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 918 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin()), 919 "[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&); 920 CHECK_THROWS_WITH_AS(jobject.erase(jobject.begin(), jobject2.end()), 921 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 922 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject.end()), 923 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 924 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject2.end()), 925 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 926 } 927 { 928 Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; 929 Json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; 930 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin()), 931 "[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&); 932 CHECK_THROWS_WITH_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), 933 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 934 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), 935 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 936 CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), 937 "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); 938 } 939 } 940 } 941 942 SECTION("remove element by key in non-object type") 943 { 944 SECTION("null") 945 { 946 Json j_nonobject(Json::value_t::null); 947 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&); 948 949 #ifdef JSON_HAS_CPP_17 950 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&); 951 #endif 952 } 953 954 SECTION("boolean") 955 { 956 Json j_nonobject(Json::value_t::boolean); 957 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&); 958 959 #ifdef JSON_HAS_CPP_17 960 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&); 961 #endif 962 } 963 964 SECTION("string") 965 { 966 Json j_nonobject(Json::value_t::string); 967 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&); 968 969 #ifdef JSON_HAS_CPP_17 970 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&); 971 #endif 972 } 973 974 SECTION("array") 975 { 976 Json j_nonobject(Json::value_t::array); 977 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&); 978 979 #ifdef JSON_HAS_CPP_17 980 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&); 981 #endif 982 } 983 984 SECTION("number (integer)") 985 { 986 Json j_nonobject(Json::value_t::number_integer); 987 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); 988 989 #ifdef JSON_HAS_CPP_17 990 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); 991 #endif 992 } 993 994 SECTION("number (floating-point)") 995 { 996 Json j_nonobject(Json::value_t::number_float); 997 CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); 998 999 #ifdef JSON_HAS_CPP_17 1000 CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); 1001 #endif 1002 } 1003 } 1004 } 1005 1006 SECTION("find an element in an object") 1007 { 1008 SECTION("existing element") 1009 { 1010 for (const auto* key : 1011 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1012 }) 1013 { 1014 CHECK(j.find(key) != j.end()); 1015 CHECK(*j.find(key) == j.at(key)); 1016 CHECK(j_const.find(key) != j_const.end()); 1017 CHECK(*j_const.find(key) == j_const.at(key)); 1018 } 1019 #ifdef JSON_HAS_CPP_17 1020 for (const std::string_view key : 1021 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1022 }) 1023 { 1024 CHECK(j.find(key) != j.end()); 1025 CHECK(*j.find(key) == j.at(key)); 1026 CHECK(j_const.find(key) != j_const.end()); 1027 CHECK(*j_const.find(key) == j_const.at(key)); 1028 } 1029 #endif 1030 } 1031 1032 SECTION("nonexisting element") 1033 { 1034 CHECK(j.find("foo") == j.end()); 1035 CHECK(j_const.find("foo") == j_const.end()); 1036 1037 #ifdef JSON_HAS_CPP_17 1038 CHECK(j.find(std::string_view("foo")) == j.end()); 1039 CHECK(j_const.find(std::string_view("foo")) == j_const.end()); 1040 #endif 1041 } 1042 1043 SECTION("all types") 1044 { 1045 SECTION("null") 1046 { 1047 Json j_nonarray(Json::value_t::null); 1048 const Json j_nonarray_const(j_nonarray); 1049 1050 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1051 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1052 1053 #ifdef JSON_HAS_CPP_17 1054 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1055 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1056 #endif 1057 } 1058 1059 SECTION("string") 1060 { 1061 Json j_nonarray(Json::value_t::string); 1062 const Json j_nonarray_const(j_nonarray); 1063 1064 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1065 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1066 1067 #ifdef JSON_HAS_CPP_17 1068 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1069 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1070 #endif 1071 } 1072 1073 SECTION("object") 1074 { 1075 Json j_nonarray(Json::value_t::object); 1076 const Json j_nonarray_const(j_nonarray); 1077 1078 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1079 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1080 1081 #ifdef JSON_HAS_CPP_17 1082 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1083 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1084 #endif 1085 } 1086 1087 SECTION("array") 1088 { 1089 Json j_nonarray(Json::value_t::array); 1090 const Json j_nonarray_const(j_nonarray); 1091 1092 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1093 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1094 1095 #ifdef JSON_HAS_CPP_17 1096 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1097 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1098 #endif 1099 } 1100 1101 SECTION("boolean") 1102 { 1103 Json j_nonarray(Json::value_t::boolean); 1104 const Json j_nonarray_const(j_nonarray); 1105 1106 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1107 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1108 1109 #ifdef JSON_HAS_CPP_17 1110 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1111 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1112 #endif 1113 } 1114 1115 SECTION("number (integer)") 1116 { 1117 Json j_nonarray(Json::value_t::number_integer); 1118 const Json j_nonarray_const(j_nonarray); 1119 1120 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1121 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1122 1123 #ifdef JSON_HAS_CPP_17 1124 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1125 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1126 #endif 1127 } 1128 1129 SECTION("number (unsigned)") 1130 { 1131 Json j_nonarray(Json::value_t::number_unsigned); 1132 const Json j_nonarray_const(j_nonarray); 1133 1134 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1135 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1136 1137 #ifdef JSON_HAS_CPP_17 1138 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1139 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1140 #endif 1141 } 1142 1143 SECTION("number (floating-point)") 1144 { 1145 Json j_nonarray(Json::value_t::number_float); 1146 const Json j_nonarray_const(j_nonarray); 1147 1148 CHECK(j_nonarray.find("foo") == j_nonarray.end()); 1149 CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); 1150 1151 #ifdef JSON_HAS_CPP_17 1152 CHECK(j_nonarray.find(std::string_view("foo")) == j_nonarray.end()); 1153 CHECK(j_nonarray_const.find(std::string_view("foo")) == j_nonarray_const.end()); 1154 #endif 1155 } 1156 } 1157 } 1158 1159 SECTION("count keys in an object") 1160 { 1161 SECTION("existing element") 1162 { 1163 for (const auto* key : 1164 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1165 }) 1166 { 1167 CHECK(j.count(key) == 1); 1168 CHECK(j_const.count(key) == 1); 1169 } 1170 #ifdef JSON_HAS_CPP_17 1171 for (const std::string_view key : 1172 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1173 }) 1174 { 1175 CHECK(j.count(key) == 1); 1176 CHECK(j_const.count(key) == 1); 1177 } 1178 #endif 1179 } 1180 1181 SECTION("nonexisting element") 1182 { 1183 CHECK(j.count("foo") == 0); 1184 CHECK(j_const.count("foo") == 0); 1185 1186 #ifdef JSON_HAS_CPP_17 1187 CHECK(j.count(std::string_view("foo")) == 0); 1188 CHECK(j_const.count(std::string_view("foo")) == 0); 1189 #endif 1190 } 1191 1192 SECTION("all types") 1193 { 1194 SECTION("null") 1195 { 1196 Json j_nonobject(Json::value_t::null); 1197 const Json j_nonobject_const(Json::value_t::null); 1198 1199 CHECK(j_nonobject.count("foo") == 0); 1200 CHECK(j_nonobject_const.count("foo") == 0); 1201 1202 #ifdef JSON_HAS_CPP_17 1203 CHECK(j.count(std::string_view("foo")) == 0); 1204 CHECK(j_const.count(std::string_view("foo")) == 0); 1205 #endif 1206 } 1207 1208 SECTION("string") 1209 { 1210 Json j_nonobject(Json::value_t::string); 1211 const Json j_nonobject_const(Json::value_t::string); 1212 1213 CHECK(j_nonobject.count("foo") == 0); 1214 CHECK(j_nonobject_const.count("foo") == 0); 1215 1216 #ifdef JSON_HAS_CPP_17 1217 CHECK(j.count(std::string_view("foo")) == 0); 1218 CHECK(j_const.count(std::string_view("foo")) == 0); 1219 #endif 1220 } 1221 1222 SECTION("object") 1223 { 1224 Json j_nonobject(Json::value_t::object); 1225 const Json j_nonobject_const(Json::value_t::object); 1226 1227 CHECK(j_nonobject.count("foo") == 0); 1228 CHECK(j_nonobject_const.count("foo") == 0); 1229 1230 #ifdef JSON_HAS_CPP_17 1231 CHECK(j.count(std::string_view("foo")) == 0); 1232 CHECK(j_const.count(std::string_view("foo")) == 0); 1233 #endif 1234 } 1235 1236 SECTION("array") 1237 { 1238 Json j_nonobject(Json::value_t::array); 1239 const Json j_nonobject_const(Json::value_t::array); 1240 1241 CHECK(j_nonobject.count("foo") == 0); 1242 CHECK(j_nonobject_const.count("foo") == 0); 1243 1244 #ifdef JSON_HAS_CPP_17 1245 CHECK(j.count(std::string_view("foo")) == 0); 1246 CHECK(j_const.count(std::string_view("foo")) == 0); 1247 #endif 1248 } 1249 1250 SECTION("boolean") 1251 { 1252 Json j_nonobject(Json::value_t::boolean); 1253 const Json j_nonobject_const(Json::value_t::boolean); 1254 1255 CHECK(j_nonobject.count("foo") == 0); 1256 CHECK(j_nonobject_const.count("foo") == 0); 1257 1258 #ifdef JSON_HAS_CPP_17 1259 CHECK(j.count(std::string_view("foo")) == 0); 1260 CHECK(j_const.count(std::string_view("foo")) == 0); 1261 #endif 1262 } 1263 1264 SECTION("number (integer)") 1265 { 1266 Json j_nonobject(Json::value_t::number_integer); 1267 const Json j_nonobject_const(Json::value_t::number_integer); 1268 1269 CHECK(j_nonobject.count("foo") == 0); 1270 CHECK(j_nonobject_const.count("foo") == 0); 1271 1272 #ifdef JSON_HAS_CPP_17 1273 CHECK(j.count(std::string_view("foo")) == 0); 1274 CHECK(j_const.count(std::string_view("foo")) == 0); 1275 #endif 1276 } 1277 1278 SECTION("number (unsigned)") 1279 { 1280 Json j_nonobject(Json::value_t::number_unsigned); 1281 const Json j_nonobject_const(Json::value_t::number_unsigned); 1282 1283 CHECK(j_nonobject.count("foo") == 0); 1284 CHECK(j_nonobject_const.count("foo") == 0); 1285 1286 #ifdef JSON_HAS_CPP_17 1287 CHECK(j.count(std::string_view("foo")) == 0); 1288 CHECK(j_const.count(std::string_view("foo")) == 0); 1289 #endif 1290 } 1291 1292 SECTION("number (floating-point)") 1293 { 1294 Json j_nonobject(Json::value_t::number_float); 1295 const Json j_nonobject_const(Json::value_t::number_float); 1296 1297 CHECK(j_nonobject.count("foo") == 0); 1298 CHECK(j_nonobject_const.count("foo") == 0); 1299 1300 #ifdef JSON_HAS_CPP_17 1301 CHECK(j.count(std::string_view("foo")) == 0); 1302 CHECK(j_const.count(std::string_view("foo")) == 0); 1303 #endif 1304 } 1305 } 1306 } 1307 1308 SECTION("check existence of key in an object") 1309 { 1310 SECTION("existing element") 1311 { 1312 for (const auto* key : 1313 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1314 }) 1315 { 1316 CHECK(j.contains(key) == true); 1317 CHECK(j_const.contains(key) == true); 1318 } 1319 1320 #ifdef JSON_HAS_CPP_17 1321 for (const std::string_view key : 1322 {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" 1323 }) 1324 { 1325 CHECK(j.contains(key) == true); 1326 CHECK(j_const.contains(key) == true); 1327 } 1328 #endif 1329 } 1330 1331 SECTION("nonexisting element") 1332 { 1333 CHECK(j.contains("foo") == false); 1334 CHECK(j_const.contains("foo") == false); 1335 1336 #ifdef JSON_HAS_CPP_17 1337 CHECK(j.contains(std::string_view("foo")) == false); 1338 CHECK(j_const.contains(std::string_view("foo")) == false); 1339 #endif 1340 } 1341 1342 SECTION("all types") 1343 { 1344 SECTION("null") 1345 { 1346 Json j_nonobject(Json::value_t::null); 1347 const Json j_nonobject_const(Json::value_t::null); 1348 1349 CHECK(j_nonobject.contains("foo") == false); 1350 CHECK(j_nonobject_const.contains("foo") == false); 1351 1352 #ifdef JSON_HAS_CPP_17 1353 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1354 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1355 #endif 1356 } 1357 1358 SECTION("string") 1359 { 1360 Json j_nonobject(Json::value_t::string); 1361 const Json j_nonobject_const(Json::value_t::string); 1362 1363 CHECK(j_nonobject.contains("foo") == false); 1364 CHECK(j_nonobject_const.contains("foo") == false); 1365 1366 #ifdef JSON_HAS_CPP_17 1367 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1368 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1369 #endif 1370 } 1371 1372 SECTION("object") 1373 { 1374 Json j_nonobject(Json::value_t::object); 1375 const Json j_nonobject_const(Json::value_t::object); 1376 1377 CHECK(j_nonobject.contains("foo") == false); 1378 CHECK(j_nonobject_const.contains("foo") == false); 1379 1380 #ifdef JSON_HAS_CPP_17 1381 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1382 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1383 #endif 1384 } 1385 1386 SECTION("array") 1387 { 1388 Json j_nonobject(Json::value_t::array); 1389 const Json j_nonobject_const(Json::value_t::array); 1390 1391 CHECK(j_nonobject.contains("foo") == false); 1392 CHECK(j_nonobject_const.contains("foo") == false); 1393 1394 #ifdef JSON_HAS_CPP_17 1395 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1396 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1397 #endif 1398 } 1399 1400 SECTION("boolean") 1401 { 1402 Json j_nonobject(Json::value_t::boolean); 1403 const Json j_nonobject_const(Json::value_t::boolean); 1404 1405 CHECK(j_nonobject.contains("foo") == false); 1406 CHECK(j_nonobject_const.contains("foo") == false); 1407 1408 #ifdef JSON_HAS_CPP_17 1409 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1410 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1411 #endif 1412 } 1413 1414 SECTION("number (integer)") 1415 { 1416 Json j_nonobject(Json::value_t::number_integer); 1417 const Json j_nonobject_const(Json::value_t::number_integer); 1418 1419 CHECK(j_nonobject.contains("foo") == false); 1420 CHECK(j_nonobject_const.contains("foo") == false); 1421 1422 #ifdef JSON_HAS_CPP_17 1423 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1424 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1425 #endif 1426 } 1427 1428 SECTION("number (unsigned)") 1429 { 1430 Json j_nonobject(Json::value_t::number_unsigned); 1431 const Json j_nonobject_const(Json::value_t::number_unsigned); 1432 1433 CHECK(j_nonobject.contains("foo") == false); 1434 CHECK(j_nonobject_const.contains("foo") == false); 1435 1436 #ifdef JSON_HAS_CPP_17 1437 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1438 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1439 #endif 1440 } 1441 1442 SECTION("number (floating-point)") 1443 { 1444 Json j_nonobject(Json::value_t::number_float); 1445 const Json j_nonobject_const(Json::value_t::number_float); 1446 CHECK(j_nonobject.contains("foo") == false); 1447 CHECK(j_nonobject_const.contains("foo") == false); 1448 #ifdef JSON_HAS_CPP_17 1449 CHECK(j_nonobject.contains(std::string_view("foo")) == false); 1450 CHECK(j_nonobject_const.contains(std::string_view("foo")) == false); 1451 #endif 1452 } 1453 } 1454 } 1455 } 1456 } 1457 1458 #if !defined(JSON_NOEXCEPTION) 1459 TEST_CASE_TEMPLATE("element access 2 (throwing tests)", Json, nlohmann::json, nlohmann::ordered_json) 1460 { 1461 SECTION("object") 1462 { 1463 Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; 1464 const Json j_const = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; 1465 1466 SECTION("access specified element with default value") 1467 { 1468 SECTION("given a JSON pointer") 1469 { 1470 SECTION("access non-existing value") 1471 { 1472 CHECK(j.value("/not/existing"_json_pointer, 2) == 2); 1473 CHECK(j.value("/not/existing"_json_pointer, 2u) == 2u); 1474 CHECK(j.value("/not/existing"_json_pointer, false) == false); 1475 CHECK(j.value("/not/existing"_json_pointer, "bar") == "bar"); 1476 CHECK(j.value("/not/existing"_json_pointer, 12.34) == Approx(12.34)); 1477 CHECK(j.value("/not/existing"_json_pointer, Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 1478 CHECK(j.value("/not/existing"_json_pointer, Json({10, 100})) == Json({10, 100})); 1479 1480 CHECK(j_const.value("/not/existing"_json_pointer, 2) == 2); 1481 CHECK(j_const.value("/not/existing"_json_pointer, 2u) == 2u); 1482 CHECK(j_const.value("/not/existing"_json_pointer, false) == false); 1483 CHECK(j_const.value("/not/existing"_json_pointer, "bar") == "bar"); 1484 CHECK(j_const.value("/not/existing"_json_pointer, 12.34) == Approx(12.34)); 1485 CHECK(j_const.value("/not/existing"_json_pointer, Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); 1486 CHECK(j_const.value("/not/existing"_json_pointer, Json({10, 100})) == Json({10, 100})); 1487 } 1488 } 1489 } 1490 } 1491 } 1492 #endif 1493 1494 // TODO(falbrechtskirchinger) merge with the other test case; clean up 1495 TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann::json, nlohmann::ordered_json) 1496 { 1497 using string_t = typename Json::string_t; 1498 using number_integer_t = typename Json::number_integer_t; 1499 1500 // test assumes string_t and object_t::key_type are the same 1501 REQUIRE(std::is_same<string_t, typename Json::object_t::key_type>::value); 1502 1503 Json j 1504 { 1505 {"foo", "bar"}, 1506 {"baz", 42} 1507 }; 1508 1509 const char* cpstr = "default"; 1510 const char castr[] = "default"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1511 string_t const str = "default"; 1512 1513 number_integer_t integer = 69; 1514 std::size_t size = 69; 1515 1516 SECTION("deduced ValueType") 1517 { 1518 SECTION("literal key") 1519 { 1520 CHECK(j.value("foo", "default") == "bar"); 1521 CHECK(j.value("foo", cpstr) == "bar"); 1522 CHECK(j.value("foo", castr) == "bar"); 1523 CHECK(j.value("foo", str) == "bar"); 1524 // this test is in fact different from the one below, 1525 // because of 0 considering const char * overloads 1526 // whereas any other number does not 1527 CHECK(j.value("baz", 0) == 42); 1528 CHECK(j.value("baz", 47) == 42); 1529 CHECK(j.value("baz", integer) == 42); 1530 CHECK(j.value("baz", size) == 42); 1531 1532 CHECK(j.value("bar", "default") == "default"); 1533 CHECK(j.value("bar", 0) == 0); 1534 CHECK(j.value("bar", 47) == 47); 1535 CHECK(j.value("bar", integer) == integer); 1536 CHECK(j.value("bar", size) == size); 1537 1538 CHECK_THROWS_WITH_AS(Json().value("foo", "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1539 CHECK_THROWS_WITH_AS(Json().value("foo", str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1540 } 1541 1542 SECTION("const char * key") 1543 { 1544 const char* key = "foo"; 1545 const char* key2 = "baz"; 1546 const char* key_notfound = "bar"; 1547 1548 CHECK(j.value(key, "default") == "bar"); 1549 CHECK(j.value(key, cpstr) == "bar"); 1550 CHECK(j.value(key, castr) == "bar"); 1551 CHECK(j.value(key, str) == "bar"); 1552 CHECK(j.value(key2, 0) == 42); 1553 CHECK(j.value(key2, 47) == 42); 1554 CHECK(j.value(key2, integer) == 42); 1555 CHECK(j.value(key2, size) == 42); 1556 1557 CHECK(j.value(key_notfound, "default") == "default"); 1558 CHECK(j.value(key_notfound, 0) == 0); 1559 CHECK(j.value(key_notfound, 47) == 47); 1560 CHECK(j.value(key_notfound, integer) == integer); 1561 CHECK(j.value(key_notfound, size) == size); 1562 1563 CHECK_THROWS_WITH_AS(Json().value(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1564 CHECK_THROWS_WITH_AS(Json().value(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1565 } 1566 1567 SECTION("const char(&)[] key") 1568 { 1569 const char key[] = "foo"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1570 const char key2[] = "baz"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1571 const char key_notfound[] = "bar"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1572 1573 CHECK(j.value(key, "default") == "bar"); 1574 CHECK(j.value(key, cpstr) == "bar"); 1575 CHECK(j.value(key, castr) == "bar"); 1576 CHECK(j.value(key, str) == "bar"); 1577 CHECK(j.value(key2, 0) == 42); 1578 CHECK(j.value(key2, 47) == 42); 1579 CHECK(j.value(key2, integer) == 42); 1580 CHECK(j.value(key2, size) == 42); 1581 1582 CHECK(j.value(key_notfound, "default") == "default"); 1583 CHECK(j.value(key_notfound, 0) == 0); 1584 CHECK(j.value(key_notfound, 47) == 47); 1585 CHECK(j.value(key_notfound, integer) == integer); 1586 CHECK(j.value(key_notfound, size) == size); 1587 1588 CHECK_THROWS_WITH_AS(Json().value(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1589 CHECK_THROWS_WITH_AS(Json().value(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1590 } 1591 1592 SECTION("string_t/object_t::key_type key") 1593 { 1594 string_t const key = "foo"; 1595 string_t const key2 = "baz"; 1596 string_t const key_notfound = "bar"; 1597 1598 CHECK(j.value(key, "default") == "bar"); 1599 CHECK(j.value(key, cpstr) == "bar"); 1600 CHECK(j.value(key, castr) == "bar"); 1601 CHECK(j.value(key, str) == "bar"); 1602 CHECK(j.value(key2, 0) == 42); 1603 CHECK(j.value(key2, 47) == 42); 1604 CHECK(j.value(key2, integer) == 42); 1605 CHECK(j.value(key2, size) == 42); 1606 1607 CHECK(j.value(key_notfound, "default") == "default"); 1608 CHECK(j.value(key_notfound, 0) == 0); 1609 CHECK(j.value(key_notfound, 47) == 47); 1610 CHECK(j.value(key_notfound, integer) == integer); 1611 CHECK(j.value(key_notfound, size) == size); 1612 1613 CHECK_THROWS_WITH_AS(Json().value(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1614 CHECK_THROWS_WITH_AS(Json().value(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1615 } 1616 1617 #ifdef JSON_HAS_CPP_17 1618 SECTION("std::string_view key") 1619 { 1620 std::string_view const key = "foo"; 1621 std::string_view const key2 = "baz"; 1622 std::string_view const key_notfound = "bar"; 1623 1624 CHECK(j.value(key, "default") == "bar"); 1625 CHECK(j.value(key, cpstr) == "bar"); 1626 CHECK(j.value(key, castr) == "bar"); 1627 CHECK(j.value(key, str) == "bar"); 1628 CHECK(j.value(key2, 0) == 42); 1629 CHECK(j.value(key2, 47) == 42); 1630 CHECK(j.value(key2, integer) == 42); 1631 CHECK(j.value(key2, size) == 42); 1632 1633 CHECK(j.value(key_notfound, "default") == "default"); 1634 CHECK(j.value(key_notfound, 0) == 0); 1635 CHECK(j.value(key_notfound, 47) == 47); 1636 CHECK(j.value(key_notfound, integer) == integer); 1637 CHECK(j.value(key_notfound, size) == size); 1638 1639 CHECK_THROWS_WITH_AS(Json().value(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1640 CHECK_THROWS_WITH_AS(Json().value(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1641 } 1642 #endif 1643 } 1644 1645 SECTION("explicit ValueType") 1646 { 1647 SECTION("literal key") 1648 { 1649 CHECK(j.template value<string_t>("foo", "default") == "bar"); 1650 CHECK(j.template value<string_t>("foo", cpstr) == "bar"); 1651 CHECK(j.template value<string_t>("foo", castr) == "bar"); 1652 CHECK(j.template value<string_t>("foo", str) == "bar"); 1653 CHECK(j.template value<number_integer_t>("baz", 0) == 42); 1654 CHECK(j.template value<number_integer_t>("baz", 47) == 42); 1655 CHECK(j.template value<number_integer_t>("baz", integer) == 42); 1656 CHECK(j.template value<std::size_t>("baz", 0) == 42); 1657 CHECK(j.template value<std::size_t>("baz", 47) == 42); 1658 CHECK(j.template value<std::size_t>("baz", size) == 42); 1659 1660 CHECK(j.template value<string_t>("bar", "default") == "default"); 1661 CHECK(j.template value<number_integer_t>("bar", 0) == 0); 1662 CHECK(j.template value<number_integer_t>("bar", 47) == 47); 1663 CHECK(j.template value<number_integer_t>("bar", integer) == integer); 1664 CHECK(j.template value<std::size_t>("bar", 0) == 0); 1665 CHECK(j.template value<std::size_t>("bar", 47) == 47); 1666 CHECK(j.template value<std::size_t>("bar", size) == size); 1667 1668 CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1669 CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1670 } 1671 1672 SECTION("const char * key") 1673 { 1674 const char* key = "foo"; 1675 const char* key2 = "baz"; 1676 const char* key_notfound = "bar"; 1677 1678 CHECK(j.template value<string_t>(key, "default") == "bar"); 1679 CHECK(j.template value<string_t>(key, cpstr) == "bar"); 1680 CHECK(j.template value<string_t>(key, castr) == "bar"); 1681 CHECK(j.template value<string_t>(key, str) == "bar"); 1682 CHECK(j.template value<number_integer_t>(key2, 0) == 42); 1683 CHECK(j.template value<number_integer_t>(key2, 47) == 42); 1684 CHECK(j.template value<number_integer_t>(key2, integer) == 42); 1685 CHECK(j.template value<std::size_t>(key2, 0) == 42); 1686 CHECK(j.template value<std::size_t>(key2, 47) == 42); 1687 CHECK(j.template value<std::size_t>(key2, size) == 42); 1688 1689 CHECK(j.template value<string_t>(key_notfound, "default") == "default"); 1690 CHECK(j.template value<number_integer_t>(key_notfound, 0) == 0); 1691 CHECK(j.template value<number_integer_t>(key_notfound, 47) == 47); 1692 CHECK(j.template value<number_integer_t>(key_notfound, integer) == integer); 1693 CHECK(j.template value<std::size_t>(key_notfound, 0) == 0); 1694 CHECK(j.template value<std::size_t>(key_notfound, 47) == 47); 1695 CHECK(j.template value<std::size_t>(key_notfound, size) == size); 1696 1697 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1698 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1699 } 1700 1701 SECTION("const char(&)[] key") 1702 { 1703 const char key[] = "foo"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1704 const char key2[] = "baz"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1705 const char key_notfound[] = "bar"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) 1706 1707 CHECK(j.template value<string_t>(key, "default") == "bar"); 1708 CHECK(j.template value<string_t>(key, cpstr) == "bar"); 1709 CHECK(j.template value<string_t>(key, castr) == "bar"); 1710 CHECK(j.template value<string_t>(key, str) == "bar"); 1711 CHECK(j.template value<number_integer_t>(key2, 0) == 42); 1712 CHECK(j.template value<number_integer_t>(key2, 47) == 42); 1713 CHECK(j.template value<number_integer_t>(key2, integer) == 42); 1714 CHECK(j.template value<std::size_t>(key2, 0) == 42); 1715 CHECK(j.template value<std::size_t>(key2, 47) == 42); 1716 CHECK(j.template value<std::size_t>(key2, size) == 42); 1717 1718 CHECK(j.template value<string_t>(key_notfound, "default") == "default"); 1719 CHECK(j.template value<number_integer_t>(key_notfound, 0) == 0); 1720 CHECK(j.template value<number_integer_t>(key_notfound, 47) == 47); 1721 CHECK(j.template value<number_integer_t>(key_notfound, integer) == integer); 1722 CHECK(j.template value<std::size_t>(key_notfound, 0) == 0); 1723 CHECK(j.template value<std::size_t>(key_notfound, 47) == 47); 1724 CHECK(j.template value<std::size_t>(key_notfound, size) == size); 1725 1726 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1727 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1728 } 1729 1730 SECTION("string_t/object_t::key_type key") 1731 { 1732 string_t const key = "foo"; 1733 string_t const key2 = "baz"; 1734 string_t const key_notfound = "bar"; 1735 1736 CHECK(j.template value<string_t>(key, "default") == "bar"); 1737 CHECK(j.template value<string_t>(key, cpstr) == "bar"); 1738 CHECK(j.template value<string_t>(key, castr) == "bar"); 1739 CHECK(j.template value<string_t>(key, str) == "bar"); 1740 CHECK(j.template value<number_integer_t>(key2, 0) == 42); 1741 CHECK(j.template value<number_integer_t>(key2, 47) == 42); 1742 CHECK(j.template value<std::size_t>(key2, 0) == 42); 1743 CHECK(j.template value<std::size_t>(key2, 47) == 42); 1744 1745 CHECK(j.template value<string_t>(key_notfound, "default") == "default"); 1746 CHECK(j.template value<number_integer_t>(key_notfound, 0) == 0); 1747 CHECK(j.template value<number_integer_t>(key_notfound, 47) == 47); 1748 CHECK(j.template value<std::size_t>(key_notfound, 0) == 0); 1749 CHECK(j.template value<std::size_t>(key_notfound, 47) == 47); 1750 1751 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1752 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1753 } 1754 1755 #ifdef JSON_HAS_CPP_17 1756 SECTION("std::string_view key") 1757 { 1758 std::string_view const key = "foo"; 1759 std::string_view const key2 = "baz"; 1760 std::string_view const key_notfound = "bar"; 1761 1762 CHECK(j.template value<string_t>(key, "default") == "bar"); 1763 CHECK(j.template value<string_t>(key, cpstr) == "bar"); 1764 CHECK(j.template value<string_t>(key, castr) == "bar"); 1765 CHECK(j.template value<string_t>(key, str) == "bar"); 1766 CHECK(j.template value<number_integer_t>(key2, 0) == 42); 1767 CHECK(j.template value<number_integer_t>(key2, 47) == 42); 1768 CHECK(j.template value<number_integer_t>(key2, integer) == 42); 1769 CHECK(j.template value<std::size_t>(key2, 0) == 42); 1770 CHECK(j.template value<std::size_t>(key2, 47) == 42); 1771 CHECK(j.template value<std::size_t>(key2, size) == 42); 1772 1773 CHECK(j.template value<string_t>(key_notfound, "default") == "default"); 1774 CHECK(j.template value<number_integer_t>(key_notfound, 0) == 0); 1775 CHECK(j.template value<number_integer_t>(key_notfound, 47) == 47); 1776 CHECK(j.template value<number_integer_t>(key_notfound, integer) == integer); 1777 CHECK(j.template value<std::size_t>(key_notfound, 0) == 0); 1778 CHECK(j.template value<std::size_t>(key_notfound, 47) == 47); 1779 CHECK(j.template value<std::size_t>(key_notfound, size) == size); 1780 1781 CHECK(j.template value<std::string_view>(key, "default") == "bar"); 1782 CHECK(j.template value<std::string_view>(key, cpstr) == "bar"); 1783 CHECK(j.template value<std::string_view>(key, castr) == "bar"); 1784 CHECK(j.template value<std::string_view>(key, str) == "bar"); 1785 1786 CHECK(j.template value<std::string_view>(key_notfound, "default") == "default"); 1787 1788 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1789 CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); 1790 } 1791 #endif 1792 } 1793 } 1794