• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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