1//     __ _____ _____ _____
2//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3// |  |  |__   |  |  | | | |  version 3.11.2
4// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#include "doctest_compatibility.h"
10
11#include <nlohmann/json.hpp>
12using nlohmann::json;
13
14TEST_CASE("pointer access")
15{
16    SECTION("pointer access to object_t")
17    {
18        using test_type = json::object_t;
19        json value = {{"one", 1}, {"two", 2}};
20
21        // check if pointers are returned correctly
22        test_type* p1 = value.get_ptr<test_type*>();
23        CHECK(p1 == value.get_ptr<test_type*>());
24        CHECK(*p1 == value.get<test_type>());
25
26        const test_type* p2 = value.get_ptr<const test_type*>();
27        CHECK(p2 == value.get_ptr<const test_type*>());
28        CHECK(*p2 == value.get<test_type>());
29
30        const test_type* const p3 = value.get_ptr<const test_type* const>();
31        CHECK(p3 == value.get_ptr<const test_type* const>());
32        CHECK(*p3 == value.get<test_type>());
33
34        // check if null pointers are returned correctly
35        CHECK(value.get_ptr<json::object_t*>() != nullptr);
36        CHECK(value.get_ptr<json::array_t*>() == nullptr);
37        CHECK(value.get_ptr<json::string_t*>() == nullptr);
38        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
39        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
40        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
41        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
42        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
43    }
44
45    SECTION("pointer access to const object_t")
46    {
47        using test_type = const json::object_t;
48        const json value = {{"one", 1}, {"two", 2}};
49
50        // check if pointers are returned correctly
51        test_type* p1 = value.get_ptr<test_type*>();
52        CHECK(p1 == value.get_ptr<test_type*>());
53        CHECK(*p1 == value.get<test_type>());
54
55        const test_type* p2 = value.get_ptr<const test_type*>();
56        CHECK(p2 == value.get_ptr<const test_type*>());
57        CHECK(*p2 == value.get<test_type>());
58
59        const test_type* const p3 = value.get_ptr<const test_type* const>();
60        CHECK(p3 == value.get_ptr<const test_type* const>());
61        CHECK(*p3 == value.get<test_type>());
62
63        // check if null pointers are returned correctly
64        CHECK(value.get_ptr<const json::object_t*>() != nullptr);
65        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
66        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
67        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
68        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
69        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
70        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
71        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
72    }
73
74    SECTION("pointer access to array_t")
75    {
76        using test_type = json::array_t;
77        json value = {1, 2, 3, 4};
78
79        // check if pointers are returned correctly
80        test_type* p1 = value.get_ptr<test_type*>();
81        CHECK(p1 == value.get_ptr<test_type*>());
82        CHECK(*p1 == value.get<test_type>());
83
84        const test_type* p2 = value.get_ptr<const test_type*>();
85        CHECK(p2 == value.get_ptr<const test_type*>());
86        CHECK(*p2 == value.get<test_type>());
87
88        const test_type* const p3 = value.get_ptr<const test_type* const>();
89        CHECK(p3 == value.get_ptr<const test_type* const>());
90        CHECK(*p3 == value.get<test_type>());
91
92        // check if null pointers are returned correctly
93        CHECK(value.get_ptr<json::object_t*>() == nullptr);
94        CHECK(value.get_ptr<json::array_t*>() != nullptr);
95        CHECK(value.get_ptr<json::string_t*>() == nullptr);
96        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
97        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
98        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
99        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
100        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
101    }
102
103    SECTION("pointer access to const array_t")
104    {
105        using test_type = const json::array_t;
106        const json value = {1, 2, 3, 4};
107
108        // check if pointers are returned correctly
109        test_type* p1 = value.get_ptr<test_type*>();
110        CHECK(p1 == value.get_ptr<test_type*>());
111        CHECK(*p1 == value.get<test_type>());
112
113        const test_type* p2 = value.get_ptr<const test_type*>();
114        CHECK(p2 == value.get_ptr<const test_type*>());
115        CHECK(*p2 == value.get<test_type>());
116
117        const test_type* const p3 = value.get_ptr<const test_type* const>();
118        CHECK(p3 == value.get_ptr<const test_type* const>());
119        CHECK(*p3 == value.get<test_type>());
120
121        // check if null pointers are returned correctly
122        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
123        CHECK(value.get_ptr<const json::array_t*>() != nullptr);
124        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
125        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
126        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
127        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
128        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
129        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
130    }
131
132    SECTION("pointer access to string_t")
133    {
134        using test_type = json::string_t;
135        json value = "hello";
136
137        // check if pointers are returned correctly
138        test_type* p1 = value.get_ptr<test_type*>();
139        CHECK(p1 == value.get_ptr<test_type*>());
140        CHECK(*p1 == value.get<test_type>());
141
142        const test_type* p2 = value.get_ptr<const test_type*>();
143        CHECK(p2 == value.get_ptr<const test_type*>());
144        CHECK(*p2 == value.get<test_type>());
145
146        const test_type* const p3 = value.get_ptr<const test_type* const>();
147        CHECK(p3 == value.get_ptr<const test_type* const>());
148        CHECK(*p3 == value.get<test_type>());
149
150        // check if null pointers are returned correctly
151        CHECK(value.get_ptr<json::object_t*>() == nullptr);
152        CHECK(value.get_ptr<json::array_t*>() == nullptr);
153        CHECK(value.get_ptr<json::string_t*>() != nullptr);
154        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
155        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
156        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
157        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
158        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
159    }
160
161    SECTION("pointer access to const string_t")
162    {
163        using test_type = const json::string_t;
164        const json value = "hello";
165
166        // check if pointers are returned correctly
167        test_type* p1 = value.get_ptr<test_type*>();
168        CHECK(p1 == value.get_ptr<test_type*>());
169        CHECK(*p1 == value.get<test_type>());
170
171        const test_type* p2 = value.get_ptr<const test_type*>();
172        CHECK(p2 == value.get_ptr<const test_type*>());
173        CHECK(*p2 == value.get<test_type>());
174
175        const test_type* const p3 = value.get_ptr<const test_type* const>();
176        CHECK(p3 == value.get_ptr<const test_type* const>());
177        CHECK(*p3 == value.get<test_type>());
178
179        // check if null pointers are returned correctly
180        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
181        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
182        CHECK(value.get_ptr<const json::string_t*>() != nullptr);
183        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
184        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
185        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
186        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
187        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
188    }
189
190    SECTION("pointer access to boolean_t")
191    {
192        using test_type = json::boolean_t;
193        json value = false;
194
195        // check if pointers are returned correctly
196        test_type* p1 = value.get_ptr<test_type*>();
197        CHECK(p1 == value.get_ptr<test_type*>());
198        CHECK(*p1 == value.get<test_type>());
199
200        const test_type* p2 = value.get_ptr<const test_type*>();
201        CHECK(p2 == value.get_ptr<const test_type*>());
202        CHECK(*p2 == value.get<test_type>());
203
204        const test_type* const p3 = value.get_ptr<const test_type* const>();
205        CHECK(p3 == value.get_ptr<const test_type* const>());
206        CHECK(*p3 == value.get<test_type>());
207
208        // check if null pointers are returned correctly
209        CHECK(value.get_ptr<json::object_t*>() == nullptr);
210        CHECK(value.get_ptr<json::array_t*>() == nullptr);
211        CHECK(value.get_ptr<json::string_t*>() == nullptr);
212        CHECK(value.get_ptr<json::boolean_t*>() != nullptr);
213        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
214        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
215        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
216        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
217    }
218
219    SECTION("pointer access to const boolean_t")
220    {
221        using test_type = const json::boolean_t;
222        const json value = false;
223
224        // check if pointers are returned correctly
225        test_type* p1 = value.get_ptr<test_type*>();
226        CHECK(p1 == value.get_ptr<test_type*>());
227        //CHECK(*p1 == value.get<test_type>());
228
229        const test_type* p2 = value.get_ptr<const test_type*>();
230        CHECK(p2 == value.get_ptr<const test_type*>());
231        CHECK(*p2 == value.get<test_type>());
232
233        const test_type* const p3 = value.get_ptr<const test_type* const>();
234        CHECK(p3 == value.get_ptr<const test_type* const>());
235        CHECK(*p3 == value.get<test_type>());
236
237        // check if null pointers are returned correctly
238        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
239        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
240        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
241        CHECK(value.get_ptr<const json::boolean_t*>() != nullptr);
242        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
243        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
244        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
245        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
246    }
247
248    SECTION("pointer access to number_integer_t")
249    {
250        using test_type = json::number_integer_t;
251        json value = 23;
252
253        // check if pointers are returned correctly
254        test_type* p1 = value.get_ptr<test_type*>();
255        CHECK(p1 == value.get_ptr<test_type*>());
256        CHECK(*p1 == value.get<test_type>());
257
258        const test_type* p2 = value.get_ptr<const test_type*>();
259        CHECK(p2 == value.get_ptr<const test_type*>());
260        CHECK(*p2 == value.get<test_type>());
261
262        const test_type* const p3 = value.get_ptr<const test_type* const>();
263        CHECK(p3 == value.get_ptr<const test_type* const>());
264        CHECK(*p3 == value.get<test_type>());
265
266        // check if null pointers are returned correctly
267        CHECK(value.get_ptr<json::object_t*>() == nullptr);
268        CHECK(value.get_ptr<json::array_t*>() == nullptr);
269        CHECK(value.get_ptr<json::string_t*>() == nullptr);
270        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
271        CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
272        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
273        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
274        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
275    }
276
277    SECTION("pointer access to const number_integer_t")
278    {
279        using test_type = const json::number_integer_t;
280        const json value = 23;
281
282        // check if pointers are returned correctly
283        test_type* p1 = value.get_ptr<test_type*>();
284        CHECK(p1 == value.get_ptr<test_type*>());
285        CHECK(*p1 == value.get<test_type>());
286
287        const test_type* p2 = value.get_ptr<const test_type*>();
288        CHECK(p2 == value.get_ptr<const test_type*>());
289        CHECK(*p2 == value.get<test_type>());
290
291        const test_type* const p3 = value.get_ptr<const test_type* const>();
292        CHECK(p3 == value.get_ptr<const test_type* const>());
293        CHECK(*p3 == value.get<test_type>());
294
295        // check if null pointers are returned correctly
296        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
297        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
298        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
299        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
300        CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
301        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
302        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
303        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
304    }
305
306    SECTION("pointer access to number_unsigned_t")
307    {
308        using test_type = json::number_unsigned_t;
309        json value = 23u;
310
311        // check if pointers are returned correctly
312        test_type* p1 = value.get_ptr<test_type*>();
313        CHECK(p1 == value.get_ptr<test_type*>());
314        CHECK(*p1 == value.get<test_type>());
315
316        const test_type* p2 = value.get_ptr<const test_type*>();
317        CHECK(p2 == value.get_ptr<const test_type*>());
318        CHECK(*p2 == value.get<test_type>());
319
320        const test_type* const p3 = value.get_ptr<const test_type* const>();
321        CHECK(p3 == value.get_ptr<const test_type* const>());
322        CHECK(*p3 == value.get<test_type>());
323
324        // check if null pointers are returned correctly
325        CHECK(value.get_ptr<json::object_t*>() == nullptr);
326        CHECK(value.get_ptr<json::array_t*>() == nullptr);
327        CHECK(value.get_ptr<json::string_t*>() == nullptr);
328        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
329        CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
330        CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
331        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
332        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
333    }
334
335    SECTION("pointer access to const number_unsigned_t")
336    {
337        using test_type = const json::number_unsigned_t;
338        const json value = 23u;
339
340        // check if pointers are returned correctly
341        test_type* p1 = value.get_ptr<test_type*>();
342        CHECK(p1 == value.get_ptr<test_type*>());
343        CHECK(*p1 == value.get<test_type>());
344
345        const test_type* p2 = value.get_ptr<const test_type*>();
346        CHECK(p2 == value.get_ptr<const test_type*>());
347        CHECK(*p2 == value.get<test_type>());
348
349        const test_type* const p3 = value.get_ptr<const test_type* const>();
350        CHECK(p3 == value.get_ptr<const test_type* const>());
351        CHECK(*p3 == value.get<test_type>());
352
353        // check if null pointers are returned correctly
354        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
355        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
356        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
357        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
358        CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
359        CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
360        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
361        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
362    }
363
364    SECTION("pointer access to number_float_t")
365    {
366        using test_type = json::number_float_t;
367        json value = 42.23;
368
369        // check if pointers are returned correctly
370        test_type* p1 = value.get_ptr<test_type*>();
371        CHECK(p1 == value.get_ptr<test_type*>());
372        CHECK(*p1 == Approx(value.get<test_type>()));
373
374        const test_type* p2 = value.get_ptr<const test_type*>();
375        CHECK(p2 == value.get_ptr<const test_type*>());
376        CHECK(*p2 == Approx(value.get<test_type>()));
377
378        const test_type* const p3 = value.get_ptr<const test_type* const>();
379        CHECK(p3 == value.get_ptr<const test_type* const>());
380        CHECK(*p3 == Approx(value.get<test_type>()));
381
382        // check if null pointers are returned correctly
383        CHECK(value.get_ptr<json::object_t*>() == nullptr);
384        CHECK(value.get_ptr<json::array_t*>() == nullptr);
385        CHECK(value.get_ptr<json::string_t*>() == nullptr);
386        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
387        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
388        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
389        CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
390        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
391    }
392
393    SECTION("pointer access to const number_float_t")
394    {
395        using test_type = const json::number_float_t;
396        const json value = 42.23;
397
398        // check if pointers are returned correctly
399        test_type* p1 = value.get_ptr<test_type*>();
400        CHECK(p1 == value.get_ptr<test_type*>());
401        CHECK(*p1 == Approx(value.get<test_type>()));
402
403        const test_type* p2 = value.get_ptr<const test_type*>();
404        CHECK(p2 == value.get_ptr<const test_type*>());
405        CHECK(*p2 == Approx(value.get<test_type>()));
406
407        const test_type* const p3 = value.get_ptr<const test_type* const>();
408        CHECK(p3 == value.get_ptr<const test_type* const>());
409        CHECK(*p3 == Approx(value.get<test_type>()));
410
411        // check if null pointers are returned correctly
412        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
413        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
414        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
415        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
416        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
417        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
418        CHECK(value.get_ptr<const json::number_float_t*>() != nullptr);
419        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
420    }
421
422    SECTION("pointer access to const binary_t")
423    {
424        using test_type = const json::binary_t;
425        const json value = json::binary({1, 2, 3});
426
427        // check if pointers are returned correctly
428        test_type* p1 = value.get_ptr<test_type*>();
429        CHECK(p1 == value.get_ptr<test_type*>());
430        CHECK(*p1 == value.get<test_type>());
431
432        const test_type* p2 = value.get_ptr<const test_type*>();
433        CHECK(p2 == value.get_ptr<const test_type*>());
434        CHECK(*p2 == value.get<test_type>());
435
436        const test_type* const p3 = value.get_ptr<const test_type* const>();
437        CHECK(p3 == value.get_ptr<const test_type* const>());
438        CHECK(*p3 == value.get<test_type>());
439
440        // check if null pointers are returned correctly
441        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
442        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
443        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
444        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
445        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
446        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
447        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
448        CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
449    }
450
451    SECTION("pointer access to const binary_t")
452    {
453        using test_type = const json::binary_t;
454        const json value = json::binary({});
455
456        // check if pointers are returned correctly
457        test_type* p1 = value.get_ptr<test_type*>();
458        CHECK(p1 == value.get_ptr<test_type*>());
459        CHECK(*p1 == value.get<test_type>());
460
461        const test_type* p2 = value.get_ptr<const test_type*>();
462        CHECK(p2 == value.get_ptr<const test_type*>());
463        CHECK(*p2 == value.get<test_type>());
464
465        const test_type* const p3 = value.get_ptr<const test_type* const>();
466        CHECK(p3 == value.get_ptr<const test_type* const>());
467        CHECK(*p3 == value.get<test_type>());
468
469        // check if null pointers are returned correctly
470        CHECK(value.get_ptr<const json::object_t*>() == nullptr);
471        CHECK(value.get_ptr<const json::array_t*>() == nullptr);
472        CHECK(value.get_ptr<const json::string_t*>() == nullptr);
473        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
474        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
475        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
476        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
477        CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
478    }
479}
480