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