• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #include "doctest_compatibility.h"
31 
32 #include <nlohmann/json.hpp>
33 using nlohmann::json;
34 
35 TEST_CASE("element access 2")
36 {
37     SECTION("object")
38     {
39         json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
40         const json j_const = j;
41 
42         SECTION("access specified element with bounds checking")
43         {
44             SECTION("access within bounds")
45             {
46                 CHECK(j.at("integer") == json(1));
47                 CHECK(j.at("unsigned") == json(1u));
48                 CHECK(j.at("boolean") == json(true));
49                 CHECK(j.at("null") == json(nullptr));
50                 CHECK(j.at("string") == json("hello world"));
51                 CHECK(j.at("floating") == json(42.23));
52                 CHECK(j.at("object") == json::object());
53                 CHECK(j.at("array") == json({1, 2, 3}));
54 
55                 CHECK(j_const.at("integer") == json(1));
56                 CHECK(j_const.at("unsigned") == json(1u));
57                 CHECK(j_const.at("boolean") == json(true));
58                 CHECK(j_const.at("null") == json(nullptr));
59                 CHECK(j_const.at("string") == json("hello world"));
60                 CHECK(j_const.at("floating") == json(42.23));
61                 CHECK(j_const.at("object") == json::object());
62                 CHECK(j_const.at("array") == json({1, 2, 3}));
63             }
64 
65             SECTION("access outside bounds")
66             {
67                 CHECK_THROWS_AS(j.at("foo"), json::out_of_range&);
68                 CHECK_THROWS_AS(j_const.at("foo"), json::out_of_range&);
69                 CHECK_THROWS_WITH(j.at("foo"),
70                                   "[json.exception.out_of_range.403] key 'foo' not found");
71                 CHECK_THROWS_WITH(j_const.at("foo"),
72                                   "[json.exception.out_of_range.403] key 'foo' not found");
73             }
74 
75             SECTION("access on non-object type")
76             {
77                 SECTION("null")
78                 {
79                     json j_nonobject(json::value_t::null);
80                     const json j_nonobject_const(j_nonobject);
81                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
82                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
83                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with null");
84                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null");
85                 }
86 
87                 SECTION("boolean")
88                 {
89                     json j_nonobject(json::value_t::boolean);
90                     const json j_nonobject_const(j_nonobject);
91                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
92                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
93                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean");
94                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean");
95                 }
96 
97                 SECTION("string")
98                 {
99                     json j_nonobject(json::value_t::string);
100                     const json j_nonobject_const(j_nonobject);
101                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
102                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
103                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string");
104                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string");
105                 }
106 
107                 SECTION("array")
108                 {
109                     json j_nonobject(json::value_t::array);
110                     const json j_nonobject_const(j_nonobject);
111                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
112                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
113                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with array");
114                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array");
115                 }
116 
117                 SECTION("number (integer)")
118                 {
119                     json j_nonobject(json::value_t::number_integer);
120                     const json j_nonobject_const(j_nonobject);
121                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
122                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
123                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
124                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
125                 }
126 
127                 SECTION("number (unsigned)")
128                 {
129                     json j_nonobject(json::value_t::number_unsigned);
130                     const json j_nonobject_const(j_nonobject);
131                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
132                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
133                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
134                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
135                 }
136 
137                 SECTION("number (floating-point)")
138                 {
139                     json j_nonobject(json::value_t::number_float);
140                     const json j_nonobject_const(j_nonobject);
141                     CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error&);
142                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error&);
143                     CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
144                     CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
145                 }
146             }
147         }
148 
149         SECTION("access specified element with default value")
150         {
151             SECTION("given a key")
152             {
153                 SECTION("access existing value")
154                 {
155                     CHECK(j.value("integer", 2) == 1);
156                     CHECK(j.value("integer", 1.0) == Approx(1));
157                     CHECK(j.value("unsigned", 2) == 1u);
158                     CHECK(j.value("unsigned", 1.0) == Approx(1u));
159                     CHECK(j.value("null", json(1)) == json());
160                     CHECK(j.value("boolean", false) == true);
161                     CHECK(j.value("string", "bar") == "hello world");
162                     CHECK(j.value("string", std::string("bar")) == "hello world");
163                     CHECK(j.value("floating", 12.34) == Approx(42.23));
164                     CHECK(j.value("floating", 12) == 42);
165                     CHECK(j.value("object", json({{"foo", "bar"}})) == json::object());
166                     CHECK(j.value("array", json({10, 100})) == json({1, 2, 3}));
167 
168                     CHECK(j_const.value("integer", 2) == 1);
169                     CHECK(j_const.value("integer", 1.0) == Approx(1));
170                     CHECK(j_const.value("unsigned", 2) == 1u);
171                     CHECK(j_const.value("unsigned", 1.0) == Approx(1u));
172                     CHECK(j_const.value("boolean", false) == true);
173                     CHECK(j_const.value("string", "bar") == "hello world");
174                     CHECK(j_const.value("string", std::string("bar")) == "hello world");
175                     CHECK(j_const.value("floating", 12.34) == Approx(42.23));
176                     CHECK(j_const.value("floating", 12) == 42);
177                     CHECK(j_const.value("object", json({{"foo", "bar"}})) == json::object());
178                     CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3}));
179                 }
180 
181                 SECTION("access non-existing value")
182                 {
183                     CHECK(j.value("_", 2) == 2);
184                     CHECK(j.value("_", 2u) == 2u);
185                     CHECK(j.value("_", false) == false);
186                     CHECK(j.value("_", "bar") == "bar");
187                     CHECK(j.value("_", 12.34) == Approx(12.34));
188                     CHECK(j.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
189                     CHECK(j.value("_", json({10, 100})) == json({10, 100}));
190 
191                     CHECK(j_const.value("_", 2) == 2);
192                     CHECK(j_const.value("_", 2u) == 2u);
193                     CHECK(j_const.value("_", false) == false);
194                     CHECK(j_const.value("_", "bar") == "bar");
195                     CHECK(j_const.value("_", 12.34) == Approx(12.34));
196                     CHECK(j_const.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
197                     CHECK(j_const.value("_", json({10, 100})) == json({10, 100}));
198                 }
199 
200                 SECTION("access on non-object type")
201                 {
202                     SECTION("null")
203                     {
204                         json j_nonobject(json::value_t::null);
205                         const json j_nonobject_const(j_nonobject);
206                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
207                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
208                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
209                                           "[json.exception.type_error.306] cannot use value() with null");
210                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
211                                           "[json.exception.type_error.306] cannot use value() with null");
212                     }
213 
214                     SECTION("boolean")
215                     {
216                         json j_nonobject(json::value_t::boolean);
217                         const json j_nonobject_const(j_nonobject);
218                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
219                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
220                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
221                                           "[json.exception.type_error.306] cannot use value() with boolean");
222                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
223                                           "[json.exception.type_error.306] cannot use value() with boolean");
224                     }
225 
226                     SECTION("string")
227                     {
228                         json j_nonobject(json::value_t::string);
229                         const json j_nonobject_const(j_nonobject);
230                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
231                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
232                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
233                                           "[json.exception.type_error.306] cannot use value() with string");
234                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
235                                           "[json.exception.type_error.306] cannot use value() with string");
236                     }
237 
238                     SECTION("array")
239                     {
240                         json j_nonobject(json::value_t::array);
241                         const json j_nonobject_const(j_nonobject);
242                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
243                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
244                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
245                                           "[json.exception.type_error.306] cannot use value() with array");
246                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
247                                           "[json.exception.type_error.306] cannot use value() with array");
248                     }
249 
250                     SECTION("number (integer)")
251                     {
252                         json j_nonobject(json::value_t::number_integer);
253                         const json j_nonobject_const(j_nonobject);
254                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
255                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
256                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
257                                           "[json.exception.type_error.306] cannot use value() with number");
258                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
259                                           "[json.exception.type_error.306] cannot use value() with number");
260                     }
261 
262                     SECTION("number (unsigned)")
263                     {
264                         json j_nonobject(json::value_t::number_unsigned);
265                         const json j_nonobject_const(j_nonobject);
266                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
267                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
268                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
269                                           "[json.exception.type_error.306] cannot use value() with number");
270                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
271                                           "[json.exception.type_error.306] cannot use value() with number");
272                     }
273 
274                     SECTION("number (floating-point)")
275                     {
276                         json j_nonobject(json::value_t::number_float);
277                         const json j_nonobject_const(j_nonobject);
278                         CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error&);
279                         CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error&);
280                         CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
281                                           "[json.exception.type_error.306] cannot use value() with number");
282                         CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
283                                           "[json.exception.type_error.306] cannot use value() with number");
284                     }
285                 }
286             }
287 
288             SECTION("given a JSON pointer")
289             {
290                 SECTION("access existing value")
291                 {
292                     CHECK(j.value("/integer"_json_pointer, 2) == 1);
293                     CHECK(j.value("/integer"_json_pointer, 1.0) == Approx(1));
294                     CHECK(j.value("/unsigned"_json_pointer, 2) == 1u);
295                     CHECK(j.value("/unsigned"_json_pointer, 1.0) == Approx(1u));
296                     CHECK(j.value("/null"_json_pointer, json(1)) == json());
297                     CHECK(j.value("/boolean"_json_pointer, false) == true);
298                     CHECK(j.value("/string"_json_pointer, "bar") == "hello world");
299                     CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world");
300                     CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23));
301                     CHECK(j.value("/floating"_json_pointer, 12) == 42);
302                     CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
303                     CHECK(j.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
304 
305                     CHECK(j_const.value("/integer"_json_pointer, 2) == 1);
306                     CHECK(j_const.value("/integer"_json_pointer, 1.0) == Approx(1));
307                     CHECK(j_const.value("/unsigned"_json_pointer, 2) == 1u);
308                     CHECK(j_const.value("/unsigned"_json_pointer, 1.0) == Approx(1u));
309                     CHECK(j_const.value("/boolean"_json_pointer, false) == true);
310                     CHECK(j_const.value("/string"_json_pointer, "bar") == "hello world");
311                     CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world");
312                     CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23));
313                     CHECK(j_const.value("/floating"_json_pointer, 12) == 42);
314                     CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
315                     CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
316                 }
317 
318                 SECTION("access on non-object type")
319                 {
320                     SECTION("null")
321                     {
322                         json j_nonobject(json::value_t::null);
323                         const json j_nonobject_const(j_nonobject);
324                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
325                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
326                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
327                                           "[json.exception.type_error.306] cannot use value() with null");
328                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
329                                           "[json.exception.type_error.306] cannot use value() with null");
330                     }
331 
332                     SECTION("boolean")
333                     {
334                         json j_nonobject(json::value_t::boolean);
335                         const json j_nonobject_const(j_nonobject);
336                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
337                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
338                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
339                                           "[json.exception.type_error.306] cannot use value() with boolean");
340                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
341                                           "[json.exception.type_error.306] cannot use value() with boolean");
342                     }
343 
344                     SECTION("string")
345                     {
346                         json j_nonobject(json::value_t::string);
347                         const json j_nonobject_const(j_nonobject);
348                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
349                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
350                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
351                                           "[json.exception.type_error.306] cannot use value() with string");
352                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
353                                           "[json.exception.type_error.306] cannot use value() with string");
354                     }
355 
356                     SECTION("array")
357                     {
358                         json j_nonobject(json::value_t::array);
359                         const json j_nonobject_const(j_nonobject);
360                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
361                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
362                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
363                                           "[json.exception.type_error.306] cannot use value() with array");
364                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
365                                           "[json.exception.type_error.306] cannot use value() with array");
366                     }
367 
368                     SECTION("number (integer)")
369                     {
370                         json j_nonobject(json::value_t::number_integer);
371                         const json j_nonobject_const(j_nonobject);
372                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
373                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
374                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
375                                           "[json.exception.type_error.306] cannot use value() with number");
376                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
377                                           "[json.exception.type_error.306] cannot use value() with number");
378                     }
379 
380                     SECTION("number (unsigned)")
381                     {
382                         json j_nonobject(json::value_t::number_unsigned);
383                         const json j_nonobject_const(j_nonobject);
384                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
385                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
386                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
387                                           "[json.exception.type_error.306] cannot use value() with number");
388                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
389                                           "[json.exception.type_error.306] cannot use value() with number");
390                     }
391 
392                     SECTION("number (floating-point)")
393                     {
394                         json j_nonobject(json::value_t::number_float);
395                         const json j_nonobject_const(j_nonobject);
396                         CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error&);
397                         CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error&);
398                         CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
399                                           "[json.exception.type_error.306] cannot use value() with number");
400                         CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
401                                           "[json.exception.type_error.306] cannot use value() with number");
402                     }
403                 }
404             }
405         }
406 
407         SECTION("front and back")
408         {
409             // "array" is the smallest key
410             CHECK(j.front() == json({1, 2, 3}));
411             CHECK(j_const.front() == json({1, 2, 3}));
412             // "unsigned" is the largest key
413             CHECK(j.back() == json(1u));
414             CHECK(j_const.back() == json(1u));
415         }
416 
417         SECTION("access specified element")
418         {
419             SECTION("access within bounds")
420             {
421                 CHECK(j["integer"] == json(1));
422                 CHECK(j[json::object_t::key_type("integer")] == j["integer"]);
423 
424                 CHECK(j["unsigned"] == json(1u));
425                 CHECK(j[json::object_t::key_type("unsigned")] == j["unsigned"]);
426 
427                 CHECK(j["boolean"] == json(true));
428                 CHECK(j[json::object_t::key_type("boolean")] == j["boolean"]);
429 
430                 CHECK(j["null"] == json(nullptr));
431                 CHECK(j[json::object_t::key_type("null")] == j["null"]);
432 
433                 CHECK(j["string"] == json("hello world"));
434                 CHECK(j[json::object_t::key_type("string")] == j["string"]);
435 
436                 CHECK(j["floating"] == json(42.23));
437                 CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
438 
439                 CHECK(j["object"] == json::object());
440                 CHECK(j[json::object_t::key_type("object")] == j["object"]);
441 
442                 CHECK(j["array"] == json({1, 2, 3}));
443                 CHECK(j[json::object_t::key_type("array")] == j["array"]);
444 
445                 CHECK(j_const["integer"] == json(1));
446                 CHECK(j_const[json::object_t::key_type("integer")] == j["integer"]);
447 
448                 CHECK(j_const["boolean"] == json(true));
449                 CHECK(j_const[json::object_t::key_type("boolean")] == j["boolean"]);
450 
451                 CHECK(j_const["null"] == json(nullptr));
452                 CHECK(j_const[json::object_t::key_type("null")] == j["null"]);
453 
454                 CHECK(j_const["string"] == json("hello world"));
455                 CHECK(j_const[json::object_t::key_type("string")] == j["string"]);
456 
457                 CHECK(j_const["floating"] == json(42.23));
458                 CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]);
459 
460                 CHECK(j_const["object"] == json::object());
461                 CHECK(j_const[json::object_t::key_type("object")] == j["object"]);
462 
463                 CHECK(j_const["array"] == json({1, 2, 3}));
464                 CHECK(j_const[json::object_t::key_type("array")] == j["array"]);
465             }
466 
467             SECTION("access on non-object type")
468             {
469                 SECTION("null")
470                 {
471                     json j_nonobject(json::value_t::null);
472                     json j_nonobject2(json::value_t::null);
473                     const json j_const_nonobject(j_nonobject);
474                     CHECK_NOTHROW(j_nonobject["foo"]);
475                     CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
476                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
477                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
478                     CHECK_THROWS_WITH(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null");
479                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
480                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with null");
481                 }
482 
483                 SECTION("boolean")
484                 {
485                     json j_nonobject(json::value_t::boolean);
486                     const json j_const_nonobject(j_nonobject);
487                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
488                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
489                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
490                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
491                     CHECK_THROWS_WITH(j_nonobject["foo"],
492                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
493                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
494                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
495                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
496                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
497                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
498                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
499                 }
500 
501                 SECTION("string")
502                 {
503                     json j_nonobject(json::value_t::string);
504                     const json j_const_nonobject(j_nonobject);
505                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
506                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
507                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
508                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
509                     CHECK_THROWS_WITH(j_nonobject["foo"],
510                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
511                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
512                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
513                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
514                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
515                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
516                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
517                 }
518 
519                 SECTION("array")
520                 {
521                     json j_nonobject(json::value_t::array);
522                     const json j_const_nonobject(j_nonobject);
523                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
524                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
525                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
526                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
527                     CHECK_THROWS_WITH(j_nonobject["foo"],
528                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
529                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
530                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
531                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
532                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
533                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
534                 }
535 
536                 SECTION("number (integer)")
537                 {
538                     json j_nonobject(json::value_t::number_integer);
539                     const json j_const_nonobject(j_nonobject);
540                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
541                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
542                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
543                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
544                     CHECK_THROWS_WITH(j_nonobject["foo"],
545                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
546                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
547                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
548                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
549                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
550                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
551                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
552                 }
553 
554                 SECTION("number (unsigned)")
555                 {
556                     json j_nonobject(json::value_t::number_unsigned);
557                     const json j_const_nonobject(j_nonobject);
558                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
559                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
560                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
561                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
562                     CHECK_THROWS_WITH(j_nonobject["foo"],
563                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
564                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
565                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
566                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
567                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
568                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
569                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
570                 }
571 
572                 SECTION("number (floating-point)")
573                 {
574                     json j_nonobject(json::value_t::number_float);
575                     const json j_const_nonobject(j_nonobject);
576                     CHECK_THROWS_AS(j_nonobject["foo"], json::type_error&);
577                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error&);
578                     CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
579                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
580                     CHECK_THROWS_WITH(j_nonobject["foo"],
581                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
582                     CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
583                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
584                     CHECK_THROWS_WITH(j_const_nonobject["foo"],
585                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
586                     CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
587                                       "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
588                 }
589             }
590         }
591 
592         SECTION("remove specified element")
593         {
594             SECTION("remove element by key")
595             {
596                 CHECK(j.find("integer") != j.end());
597                 CHECK(j.erase("integer") == 1);
598                 CHECK(j.find("integer") == j.end());
599                 CHECK(j.erase("integer") == 0);
600 
601                 CHECK(j.find("unsigned") != j.end());
602                 CHECK(j.erase("unsigned") == 1);
603                 CHECK(j.find("unsigned") == j.end());
604                 CHECK(j.erase("unsigned") == 0);
605 
606                 CHECK(j.find("boolean") != j.end());
607                 CHECK(j.erase("boolean") == 1);
608                 CHECK(j.find("boolean") == j.end());
609                 CHECK(j.erase("boolean") == 0);
610 
611                 CHECK(j.find("null") != j.end());
612                 CHECK(j.erase("null") == 1);
613                 CHECK(j.find("null") == j.end());
614                 CHECK(j.erase("null") == 0);
615 
616                 CHECK(j.find("string") != j.end());
617                 CHECK(j.erase("string") == 1);
618                 CHECK(j.find("string") == j.end());
619                 CHECK(j.erase("string") == 0);
620 
621                 CHECK(j.find("floating") != j.end());
622                 CHECK(j.erase("floating") == 1);
623                 CHECK(j.find("floating") == j.end());
624                 CHECK(j.erase("floating") == 0);
625 
626                 CHECK(j.find("object") != j.end());
627                 CHECK(j.erase("object") == 1);
628                 CHECK(j.find("object") == j.end());
629                 CHECK(j.erase("object") == 0);
630 
631                 CHECK(j.find("array") != j.end());
632                 CHECK(j.erase("array") == 1);
633                 CHECK(j.find("array") == j.end());
634                 CHECK(j.erase("array") == 0);
635             }
636 
637             SECTION("remove element by iterator")
638             {
639                 SECTION("erase(begin())")
640                 {
641                     {
642                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
643                         json::iterator it2 = jobject.erase(jobject.begin());
644                         CHECK(jobject == json({{"b", 1}, {"c", 17u}}));
645                         CHECK(*it2 == json(1));
646                     }
647                     {
648                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
649                         json::const_iterator it2 = jobject.erase(jobject.cbegin());
650                         CHECK(jobject == json({{"b", 1}, {"c", 17u}}));
651                         CHECK(*it2 == json(1));
652                     }
653                 }
654 
655                 SECTION("erase(begin(), end())")
656                 {
657                     {
658                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
659                         json::iterator it2 = jobject.erase(jobject.begin(), jobject.end());
660                         CHECK(jobject == json::object());
661                         CHECK(it2 == jobject.end());
662                     }
663                     {
664                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
665                         json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend());
666                         CHECK(jobject == json::object());
667                         CHECK(it2 == jobject.cend());
668                     }
669                 }
670 
671                 SECTION("erase(begin(), begin())")
672                 {
673                     {
674                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
675                         json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin());
676                         CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
677                         CHECK(*it2 == json("a"));
678                     }
679                     {
680                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
681                         json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin());
682                         CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
683                         CHECK(*it2 == json("a"));
684                     }
685                 }
686 
687                 SECTION("erase at offset")
688                 {
689                     {
690                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
691                         json::iterator it = jobject.find("b");
692                         json::iterator it2 = jobject.erase(it);
693                         CHECK(jobject == json({{"a", "a"}, {"c", 17u}}));
694                         CHECK(*it2 == json(17));
695                     }
696                     {
697                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
698                         json::const_iterator it = jobject.find("b");
699                         json::const_iterator it2 = jobject.erase(it);
700                         CHECK(jobject == json({{"a", "a"}, {"c", 17u}}));
701                         CHECK(*it2 == json(17));
702                     }
703                 }
704 
705                 SECTION("erase subrange")
706                 {
707                     {
708                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
709                         json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
710                         CHECK(jobject == json({{"a", "a"}, {"e", true}}));
711                         CHECK(*it2 == json(true));
712                     }
713                     {
714                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
715                         json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
716                         CHECK(jobject == json({{"a", "a"}, {"e", true}}));
717                         CHECK(*it2 == json(true));
718                     }
719                 }
720 
721                 SECTION("different objects")
722                 {
723                     {
724                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
725                         json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
726                         CHECK_THROWS_AS(jobject.erase(jobject2.begin()), json::invalid_iterator&);
727                         CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), json::invalid_iterator&);
728                         CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), json::invalid_iterator&);
729                         CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), json::invalid_iterator&);
730                         CHECK_THROWS_WITH(jobject.erase(jobject2.begin()),
731                                           "[json.exception.invalid_iterator.202] iterator does not fit current value");
732                         CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()),
733                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
734                         CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()),
735                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
736                         CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()),
737                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
738                     }
739                     {
740                         json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
741                         json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
742                         CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), json::invalid_iterator&);
743                         CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), json::invalid_iterator&);
744                         CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), json::invalid_iterator&);
745                         CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), json::invalid_iterator&);
746                         CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()),
747                                           "[json.exception.invalid_iterator.202] iterator does not fit current value");
748                         CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()),
749                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
750                         CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()),
751                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
752                         CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()),
753                                           "[json.exception.invalid_iterator.203] iterators do not fit current value");
754                     }
755                 }
756             }
757 
758             SECTION("remove element by key in non-object type")
759             {
760                 SECTION("null")
761                 {
762                     json j_nonobject(json::value_t::null);
763                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
764                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
765                                       "[json.exception.type_error.307] cannot use erase() with null");
766                 }
767 
768                 SECTION("boolean")
769                 {
770                     json j_nonobject(json::value_t::boolean);
771                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
772                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
773                                       "[json.exception.type_error.307] cannot use erase() with boolean");
774                 }
775 
776                 SECTION("string")
777                 {
778                     json j_nonobject(json::value_t::string);
779                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
780                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
781                                       "[json.exception.type_error.307] cannot use erase() with string");
782                 }
783 
784                 SECTION("array")
785                 {
786                     json j_nonobject(json::value_t::array);
787                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
788                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
789                                       "[json.exception.type_error.307] cannot use erase() with array");
790                 }
791 
792                 SECTION("number (integer)")
793                 {
794                     json j_nonobject(json::value_t::number_integer);
795                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
796                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
797                                       "[json.exception.type_error.307] cannot use erase() with number");
798                 }
799 
800                 SECTION("number (floating-point)")
801                 {
802                     json j_nonobject(json::value_t::number_float);
803                     CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error&);
804                     CHECK_THROWS_WITH(j_nonobject.erase("foo"),
805                                       "[json.exception.type_error.307] cannot use erase() with number");
806                 }
807             }
808         }
809 
810         SECTION("find an element in an object")
811         {
812             SECTION("existing element")
813             {
814                 for (auto key :
815                         {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
816                         })
817                 {
818                     CHECK(j.find(key) != j.end());
819                     CHECK(*j.find(key) == j.at(key));
820                     CHECK(j_const.find(key) != j_const.end());
821                     CHECK(*j_const.find(key) == j_const.at(key));
822                 }
823             }
824 
825             SECTION("nonexisting element")
826             {
827                 CHECK(j.find("foo") == j.end());
828                 CHECK(j_const.find("foo") == j_const.end());
829             }
830 
831             SECTION("all types")
832             {
833                 SECTION("null")
834                 {
835                     json j_nonarray(json::value_t::null);
836                     const json j_nonarray_const(j_nonarray);
837                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
838                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
839                 }
840 
841                 SECTION("string")
842                 {
843                     json j_nonarray(json::value_t::string);
844                     const json j_nonarray_const(j_nonarray);
845                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
846                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
847                 }
848 
849                 SECTION("object")
850                 {
851                     json j_nonarray(json::value_t::object);
852                     const json j_nonarray_const(j_nonarray);
853                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
854                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
855                 }
856 
857                 SECTION("array")
858                 {
859                     json j_nonarray(json::value_t::array);
860                     const json j_nonarray_const(j_nonarray);
861                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
862                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
863                 }
864 
865                 SECTION("boolean")
866                 {
867                     json j_nonarray(json::value_t::boolean);
868                     const json j_nonarray_const(j_nonarray);
869                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
870                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
871                 }
872 
873                 SECTION("number (integer)")
874                 {
875                     json j_nonarray(json::value_t::number_integer);
876                     const json j_nonarray_const(j_nonarray);
877                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
878                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
879                 }
880 
881                 SECTION("number (unsigned)")
882                 {
883                     json j_nonarray(json::value_t::number_unsigned);
884                     const json j_nonarray_const(j_nonarray);
885                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
886                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
887                 }
888 
889                 SECTION("number (floating-point)")
890                 {
891                     json j_nonarray(json::value_t::number_float);
892                     const json j_nonarray_const(j_nonarray);
893                     CHECK(j_nonarray.find("foo") == j_nonarray.end());
894                     CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end());
895                 }
896             }
897         }
898 
899         SECTION("count keys in an object")
900         {
901             SECTION("existing element")
902             {
903                 for (auto key :
904                         {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
905                         })
906                 {
907                     CHECK(j.count(key) == 1);
908                     CHECK(j_const.count(key) == 1);
909                 }
910             }
911 
912             SECTION("nonexisting element")
913             {
914                 CHECK(j.count("foo") == 0);
915                 CHECK(j_const.count("foo") == 0);
916             }
917 
918             SECTION("all types")
919             {
920                 SECTION("null")
921                 {
922                     json j_nonobject(json::value_t::null);
923                     const json j_nonobject_const(j_nonobject);
924                     CHECK(j_nonobject.count("foo") == 0);
925                     CHECK(j_nonobject_const.count("foo") == 0);
926                 }
927 
928                 SECTION("string")
929                 {
930                     json j_nonobject(json::value_t::string);
931                     const json j_nonobject_const(j_nonobject);
932                     CHECK(j_nonobject.count("foo") == 0);
933                     CHECK(j_nonobject_const.count("foo") == 0);
934                 }
935 
936                 SECTION("object")
937                 {
938                     json j_nonobject(json::value_t::object);
939                     const json j_nonobject_const(j_nonobject);
940                     CHECK(j_nonobject.count("foo") == 0);
941                     CHECK(j_nonobject_const.count("foo") == 0);
942                 }
943 
944                 SECTION("array")
945                 {
946                     json j_nonobject(json::value_t::array);
947                     const json j_nonobject_const(j_nonobject);
948                     CHECK(j_nonobject.count("foo") == 0);
949                     CHECK(j_nonobject_const.count("foo") == 0);
950                 }
951 
952                 SECTION("boolean")
953                 {
954                     json j_nonobject(json::value_t::boolean);
955                     const json j_nonobject_const(j_nonobject);
956                     CHECK(j_nonobject.count("foo") == 0);
957                     CHECK(j_nonobject_const.count("foo") == 0);
958                 }
959 
960                 SECTION("number (integer)")
961                 {
962                     json j_nonobject(json::value_t::number_integer);
963                     const json j_nonobject_const(j_nonobject);
964                     CHECK(j_nonobject.count("foo") == 0);
965                     CHECK(j_nonobject_const.count("foo") == 0);
966                 }
967 
968                 SECTION("number (unsigned)")
969                 {
970                     json j_nonobject(json::value_t::number_unsigned);
971                     const json j_nonobject_const(j_nonobject);
972                     CHECK(j_nonobject.count("foo") == 0);
973                     CHECK(j_nonobject_const.count("foo") == 0);
974                 }
975 
976                 SECTION("number (floating-point)")
977                 {
978                     json j_nonobject(json::value_t::number_float);
979                     const json j_nonobject_const(j_nonobject);
980                     CHECK(j_nonobject.count("foo") == 0);
981                     CHECK(j_nonobject_const.count("foo") == 0);
982                 }
983             }
984         }
985 
986         SECTION("check existence of key in an object")
987         {
988             SECTION("existing element")
989             {
990                 for (auto key :
991                         {"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
992                         })
993                 {
994                     CHECK(j.contains(key) == true);
995                     CHECK(j_const.contains(key) == true);
996                 }
997             }
998 
999             SECTION("nonexisting element")
1000             {
1001                 CHECK(j.contains("foo") == false);
1002                 CHECK(j_const.contains("foo") == false);
1003             }
1004 
1005             SECTION("all types")
1006             {
1007                 SECTION("null")
1008                 {
1009                     json j_nonobject(json::value_t::null);
1010                     const json j_nonobject_const(j_nonobject);
1011                     CHECK(j_nonobject.contains("foo") == false);
1012                     CHECK(j_nonobject_const.contains("foo") == false);
1013                 }
1014 
1015                 SECTION("string")
1016                 {
1017                     json j_nonobject(json::value_t::string);
1018                     const json j_nonobject_const(j_nonobject);
1019                     CHECK(j_nonobject.contains("foo") == false);
1020                     CHECK(j_nonobject_const.contains("foo") == false);
1021                 }
1022 
1023                 SECTION("object")
1024                 {
1025                     json j_nonobject(json::value_t::object);
1026                     const json j_nonobject_const(j_nonobject);
1027                     CHECK(j_nonobject.contains("foo") == false);
1028                     CHECK(j_nonobject_const.contains("foo") == false);
1029                 }
1030 
1031                 SECTION("array")
1032                 {
1033                     json j_nonobject(json::value_t::array);
1034                     const json j_nonobject_const(j_nonobject);
1035                     CHECK(j_nonobject.contains("foo") == false);
1036                     CHECK(j_nonobject_const.contains("foo") == false);
1037                 }
1038 
1039                 SECTION("boolean")
1040                 {
1041                     json j_nonobject(json::value_t::boolean);
1042                     const json j_nonobject_const(j_nonobject);
1043                     CHECK(j_nonobject.contains("foo") == false);
1044                     CHECK(j_nonobject_const.contains("foo") == false);
1045                 }
1046 
1047                 SECTION("number (integer)")
1048                 {
1049                     json j_nonobject(json::value_t::number_integer);
1050                     const json j_nonobject_const(j_nonobject);
1051                     CHECK(j_nonobject.contains("foo") == false);
1052                     CHECK(j_nonobject_const.contains("foo") == false);
1053                 }
1054 
1055                 SECTION("number (unsigned)")
1056                 {
1057                     json j_nonobject(json::value_t::number_unsigned);
1058                     const json j_nonobject_const(j_nonobject);
1059                     CHECK(j_nonobject.contains("foo") == false);
1060                     CHECK(j_nonobject_const.contains("foo") == false);
1061                 }
1062 
1063                 SECTION("number (floating-point)")
1064                 {
1065                     json j_nonobject(json::value_t::number_float);
1066                     const json j_nonobject_const(j_nonobject);
1067                     CHECK(j_nonobject.contains("foo") == false);
1068                     CHECK(j_nonobject_const.contains("foo") == false);
1069                 }
1070             }
1071         }
1072     }
1073 }
1074 
1075 #if !defined(JSON_NOEXCEPTION)
1076 TEST_CASE("element access 2 (throwing tests)")
1077 {
1078     SECTION("object")
1079     {
1080         json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
1081         const json j_const = j;
1082 
1083         SECTION("access specified element with default value")
1084         {
1085             SECTION("given a JSON pointer")
1086             {
1087                 SECTION("access non-existing value")
1088                 {
1089                     CHECK(j.value("/not/existing"_json_pointer, 2) == 2);
1090                     CHECK(j.value("/not/existing"_json_pointer, 2u) == 2u);
1091                     CHECK(j.value("/not/existing"_json_pointer, false) == false);
1092                     CHECK(j.value("/not/existing"_json_pointer, "bar") == "bar");
1093                     CHECK(j.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
1094                     CHECK(j.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
1095                     CHECK(j.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
1096 
1097                     CHECK(j_const.value("/not/existing"_json_pointer, 2) == 2);
1098                     CHECK(j_const.value("/not/existing"_json_pointer, 2u) == 2u);
1099                     CHECK(j_const.value("/not/existing"_json_pointer, false) == false);
1100                     CHECK(j_const.value("/not/existing"_json_pointer, "bar") == "bar");
1101                     CHECK(j_const.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
1102                     CHECK(j_const.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
1103                     CHECK(j_const.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
1104                 }
1105             }
1106         }
1107     }
1108 }
1109 #endif
1110