1c5f01b2fSopenharmony_ci//     __ _____ _____ _____
2c5f01b2fSopenharmony_ci//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3c5f01b2fSopenharmony_ci// |  |  |__   |  |  | | | |  version 3.11.2
4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5c5f01b2fSopenharmony_ci//
6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT
8c5f01b2fSopenharmony_ci
9c5f01b2fSopenharmony_ci#include "doctest_compatibility.h"
10c5f01b2fSopenharmony_ci
11c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp>
12c5f01b2fSopenharmony_ciusing nlohmann::json;
13c5f01b2fSopenharmony_ci
14c5f01b2fSopenharmony_ciTEST_CASE("reference access")
15c5f01b2fSopenharmony_ci{
16c5f01b2fSopenharmony_ci    // create a JSON value with different types
17c5f01b2fSopenharmony_ci    json json_types =
18c5f01b2fSopenharmony_ci    {
19c5f01b2fSopenharmony_ci        {"boolean", true},
20c5f01b2fSopenharmony_ci        {
21c5f01b2fSopenharmony_ci            "number", {
22c5f01b2fSopenharmony_ci                {"integer", 42},
23c5f01b2fSopenharmony_ci                {"floating-point", 17.23}
24c5f01b2fSopenharmony_ci            }
25c5f01b2fSopenharmony_ci        },
26c5f01b2fSopenharmony_ci        {"string", "Hello, world!"},
27c5f01b2fSopenharmony_ci        {"array", {1, 2, 3, 4, 5}},
28c5f01b2fSopenharmony_ci        {"null", nullptr}
29c5f01b2fSopenharmony_ci    };
30c5f01b2fSopenharmony_ci
31c5f01b2fSopenharmony_ci    SECTION("reference access to object_t")
32c5f01b2fSopenharmony_ci    {
33c5f01b2fSopenharmony_ci        using test_type = json::object_t;
34c5f01b2fSopenharmony_ci        json value = {{"one", 1}, {"two", 2}};
35c5f01b2fSopenharmony_ci
36c5f01b2fSopenharmony_ci        // check if references are returned correctly
37c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
38c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
39c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
40c5f01b2fSopenharmony_ci
41c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
42c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
43c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
44c5f01b2fSopenharmony_ci
45c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
46c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::object_t&>());
47c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
48c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
49c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
50c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
51c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
52c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
53c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
54c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
55c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
56c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
57c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
58c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
59c5f01b2fSopenharmony_ci    }
60c5f01b2fSopenharmony_ci
61c5f01b2fSopenharmony_ci    SECTION("const reference access to const object_t")
62c5f01b2fSopenharmony_ci    {
63c5f01b2fSopenharmony_ci        using test_type = json::object_t;
64c5f01b2fSopenharmony_ci        const json value = {{"one", 1}, {"two", 2}};
65c5f01b2fSopenharmony_ci
66c5f01b2fSopenharmony_ci        // this should not compile
67c5f01b2fSopenharmony_ci        // test_type& p1 = value.get_ref<test_type&>();
68c5f01b2fSopenharmony_ci
69c5f01b2fSopenharmony_ci        // check if references are returned correctly
70c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
71c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
72c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
73c5f01b2fSopenharmony_ci    }
74c5f01b2fSopenharmony_ci
75c5f01b2fSopenharmony_ci    SECTION("reference access to array_t")
76c5f01b2fSopenharmony_ci    {
77c5f01b2fSopenharmony_ci        using test_type = json::array_t;
78c5f01b2fSopenharmony_ci        json value = {1, 2, 3, 4};
79c5f01b2fSopenharmony_ci
80c5f01b2fSopenharmony_ci        // check if references are returned correctly
81c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
82c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
83c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
84c5f01b2fSopenharmony_ci
85c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
86c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
87c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
88c5f01b2fSopenharmony_ci
89c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
90c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
91c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
92c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::array_t&>());
93c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
94c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
95c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
96c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
97c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
98c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
99c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
100c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
101c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
102c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
103c5f01b2fSopenharmony_ci    }
104c5f01b2fSopenharmony_ci
105c5f01b2fSopenharmony_ci    SECTION("reference access to string_t")
106c5f01b2fSopenharmony_ci    {
107c5f01b2fSopenharmony_ci        using test_type = json::string_t;
108c5f01b2fSopenharmony_ci        json value = "hello";
109c5f01b2fSopenharmony_ci
110c5f01b2fSopenharmony_ci        // check if references are returned correctly
111c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
112c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
113c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
114c5f01b2fSopenharmony_ci
115c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
116c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
117c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
118c5f01b2fSopenharmony_ci
119c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
120c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
121c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
122c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
123c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
124c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::string_t&>());
125c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
126c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
127c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
128c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
129c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
130c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
131c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
132c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
133c5f01b2fSopenharmony_ci    }
134c5f01b2fSopenharmony_ci
135c5f01b2fSopenharmony_ci    SECTION("reference access to boolean_t")
136c5f01b2fSopenharmony_ci    {
137c5f01b2fSopenharmony_ci        using test_type = json::boolean_t;
138c5f01b2fSopenharmony_ci        json value = false;
139c5f01b2fSopenharmony_ci
140c5f01b2fSopenharmony_ci        // check if references are returned correctly
141c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
142c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
143c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
144c5f01b2fSopenharmony_ci
145c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
146c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
147c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
148c5f01b2fSopenharmony_ci
149c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
150c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
151c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
152c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
153c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
154c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
155c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
156c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
157c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
158c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
159c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
160c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
161c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
162c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
163c5f01b2fSopenharmony_ci    }
164c5f01b2fSopenharmony_ci
165c5f01b2fSopenharmony_ci    SECTION("reference access to number_integer_t")
166c5f01b2fSopenharmony_ci    {
167c5f01b2fSopenharmony_ci        using test_type = json::number_integer_t;
168c5f01b2fSopenharmony_ci        json value = -23;
169c5f01b2fSopenharmony_ci
170c5f01b2fSopenharmony_ci        // check if references are returned correctly
171c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
172c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
173c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
174c5f01b2fSopenharmony_ci
175c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
176c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
177c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
178c5f01b2fSopenharmony_ci
179c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
180c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
181c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
182c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
183c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
184c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
185c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
186c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
187c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
188c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
189c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
190c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
191c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
192c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
193c5f01b2fSopenharmony_ci    }
194c5f01b2fSopenharmony_ci
195c5f01b2fSopenharmony_ci    SECTION("reference access to number_unsigned_t")
196c5f01b2fSopenharmony_ci    {
197c5f01b2fSopenharmony_ci        using test_type = json::number_unsigned_t;
198c5f01b2fSopenharmony_ci        json value = 23u;
199c5f01b2fSopenharmony_ci
200c5f01b2fSopenharmony_ci        // check if references are returned correctly
201c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
202c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
203c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
204c5f01b2fSopenharmony_ci
205c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
206c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
207c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
208c5f01b2fSopenharmony_ci
209c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
210c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
211c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
212c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
213c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
214c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
215c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
216c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
217c5f01b2fSopenharmony_ci                             "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
218c5f01b2fSopenharmony_ci        //CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
219c5f01b2fSopenharmony_ci        //    "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
220c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
221c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
222c5f01b2fSopenharmony_ci    }
223c5f01b2fSopenharmony_ci
224c5f01b2fSopenharmony_ci    SECTION("reference access to number_float_t")
225c5f01b2fSopenharmony_ci    {
226c5f01b2fSopenharmony_ci        using test_type = json::number_float_t;
227c5f01b2fSopenharmony_ci        json value = 42.23;
228c5f01b2fSopenharmony_ci
229c5f01b2fSopenharmony_ci        // check if references are returned correctly
230c5f01b2fSopenharmony_ci        auto& p1 = value.get_ref<test_type&>();
231c5f01b2fSopenharmony_ci        CHECK(&p1 == value.get_ptr<test_type*>());
232c5f01b2fSopenharmony_ci        CHECK(p1 == value.get<test_type>());
233c5f01b2fSopenharmony_ci
234c5f01b2fSopenharmony_ci        const auto& p2 = value.get_ref<const test_type&>();
235c5f01b2fSopenharmony_ci        CHECK(&p2 == value.get_ptr<const test_type*>());
236c5f01b2fSopenharmony_ci        CHECK(p2 == value.get<test_type>());
237c5f01b2fSopenharmony_ci
238c5f01b2fSopenharmony_ci        // check if mismatching references throw correctly
239c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
240c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
241c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
242c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
243c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
244c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
245c5f01b2fSopenharmony_ci        CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
246c5f01b2fSopenharmony_ci    }
247c5f01b2fSopenharmony_ci}
248