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// cmake/test.cmake selects the C++ standard versions with which to build a
10c5f01b2fSopenharmony_ci// unit test based on the presence of JSON_HAS_CPP_<VERSION> macros.
11c5f01b2fSopenharmony_ci// When using macros that are only defined for particular versions of the standard
12c5f01b2fSopenharmony_ci// (e.g., JSON_HAS_FILESYSTEM for C++17 and up), please mention the corresponding
13c5f01b2fSopenharmony_ci// version macro in a comment close by, like this:
14c5f01b2fSopenharmony_ci// JSON_HAS_CPP_<VERSION> (do not remove; see note at top of file)
15c5f01b2fSopenharmony_ci
16c5f01b2fSopenharmony_ci#include "doctest_compatibility.h"
17c5f01b2fSopenharmony_ci
18c5f01b2fSopenharmony_ci// for some reason including this after the json header leads to linker errors with VS 2017...
19c5f01b2fSopenharmony_ci#include <locale>
20c5f01b2fSopenharmony_ci
21c5f01b2fSopenharmony_ci#define JSON_TESTS_PRIVATE
22c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp>
23c5f01b2fSopenharmony_ciusing json = nlohmann::json;
24c5f01b2fSopenharmony_ciusing ordered_json = nlohmann::ordered_json;
25c5f01b2fSopenharmony_ci#ifdef JSON_TEST_NO_GLOBAL_UDLS
26c5f01b2fSopenharmony_ci    using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
27c5f01b2fSopenharmony_ci#endif
28c5f01b2fSopenharmony_ci
29c5f01b2fSopenharmony_ci#include <cstdio>
30c5f01b2fSopenharmony_ci#include <list>
31c5f01b2fSopenharmony_ci#include <type_traits>
32c5f01b2fSopenharmony_ci#include <utility>
33c5f01b2fSopenharmony_ci
34c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_17
35c5f01b2fSopenharmony_ci    #include <any>
36c5f01b2fSopenharmony_ci    #include <variant>
37c5f01b2fSopenharmony_ci#endif
38c5f01b2fSopenharmony_ci
39c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_20
40c5f01b2fSopenharmony_ci    #include <span>
41c5f01b2fSopenharmony_ci#endif
42c5f01b2fSopenharmony_ci
43c5f01b2fSopenharmony_ci// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
44c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING_PUSH
45c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
46c5f01b2fSopenharmony_ci
47c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
48c5f01b2fSopenharmony_ci// for #1021
49c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
50c5f01b2fSopenharmony_ci
51c5f01b2fSopenharmony_ciusing float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
52c5f01b2fSopenharmony_ci
53c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
54c5f01b2fSopenharmony_ci// for #1647
55c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
56c5f01b2fSopenharmony_cinamespace
57c5f01b2fSopenharmony_ci{
58c5f01b2fSopenharmony_cistruct NonDefaultFromJsonStruct
59c5f01b2fSopenharmony_ci{};
60c5f01b2fSopenharmony_ci
61c5f01b2fSopenharmony_ciinline bool operator==(NonDefaultFromJsonStruct const& /*unused*/, NonDefaultFromJsonStruct const& /*unused*/)
62c5f01b2fSopenharmony_ci{
63c5f01b2fSopenharmony_ci    return true;
64c5f01b2fSopenharmony_ci}
65c5f01b2fSopenharmony_ci
66c5f01b2fSopenharmony_cienum class for_1647
67c5f01b2fSopenharmony_ci{
68c5f01b2fSopenharmony_ci    one,
69c5f01b2fSopenharmony_ci    two
70c5f01b2fSopenharmony_ci};
71c5f01b2fSopenharmony_ci
72c5f01b2fSopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive
73c5f01b2fSopenharmony_ciNLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
74c5f01b2fSopenharmony_ci{
75c5f01b2fSopenharmony_ci    {for_1647::one, "one"},
76c5f01b2fSopenharmony_ci    {for_1647::two, "two"},
77c5f01b2fSopenharmony_ci})
78c5f01b2fSopenharmony_ci}  // namespace
79c5f01b2fSopenharmony_ci
80c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
81c5f01b2fSopenharmony_ci// for #1299
82c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
83c5f01b2fSopenharmony_ci
84c5f01b2fSopenharmony_cistruct Data
85c5f01b2fSopenharmony_ci{
86c5f01b2fSopenharmony_ci    Data() = default;
87c5f01b2fSopenharmony_ci    Data(std::string a_, std::string b_)
88c5f01b2fSopenharmony_ci        : a(std::move(a_))
89c5f01b2fSopenharmony_ci        , b(std::move(b_))
90c5f01b2fSopenharmony_ci    {}
91c5f01b2fSopenharmony_ci    std::string a{};
92c5f01b2fSopenharmony_ci    std::string b{};
93c5f01b2fSopenharmony_ci};
94c5f01b2fSopenharmony_ci
95c5f01b2fSopenharmony_civoid from_json(const json& j, Data& data);
96c5f01b2fSopenharmony_civoid from_json(const json& j, Data& data)
97c5f01b2fSopenharmony_ci{
98c5f01b2fSopenharmony_ci    j["a"].get_to(data.a);
99c5f01b2fSopenharmony_ci    j["b"].get_to(data.b);
100c5f01b2fSopenharmony_ci}
101c5f01b2fSopenharmony_ci
102c5f01b2fSopenharmony_cibool operator==(Data const& lhs, Data const& rhs);
103c5f01b2fSopenharmony_cibool operator==(Data const& lhs, Data const& rhs)
104c5f01b2fSopenharmony_ci{
105c5f01b2fSopenharmony_ci    return lhs.a == rhs.a && lhs.b == rhs.b;
106c5f01b2fSopenharmony_ci}
107c5f01b2fSopenharmony_ci
108c5f01b2fSopenharmony_ci//bool operator!=(Data const& lhs, Data const& rhs)
109c5f01b2fSopenharmony_ci//{
110c5f01b2fSopenharmony_ci//    return !(lhs == rhs);
111c5f01b2fSopenharmony_ci//}
112c5f01b2fSopenharmony_ci
113c5f01b2fSopenharmony_cinamespace nlohmann
114c5f01b2fSopenharmony_ci{
115c5f01b2fSopenharmony_citemplate<>
116c5f01b2fSopenharmony_cistruct adl_serializer<NonDefaultFromJsonStruct>
117c5f01b2fSopenharmony_ci{
118c5f01b2fSopenharmony_ci    static NonDefaultFromJsonStruct from_json(json const& /*unused*/) noexcept
119c5f01b2fSopenharmony_ci    {
120c5f01b2fSopenharmony_ci        return {};
121c5f01b2fSopenharmony_ci    }
122c5f01b2fSopenharmony_ci};
123c5f01b2fSopenharmony_ci}  // namespace nlohmann
124c5f01b2fSopenharmony_ci
125c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
126c5f01b2fSopenharmony_ci// for #1805
127c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
128c5f01b2fSopenharmony_ci
129c5f01b2fSopenharmony_cistruct NotSerializableData
130c5f01b2fSopenharmony_ci{
131c5f01b2fSopenharmony_ci    int mydata;
132c5f01b2fSopenharmony_ci    float myfloat;
133c5f01b2fSopenharmony_ci};
134c5f01b2fSopenharmony_ci
135c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
136c5f01b2fSopenharmony_ci// for #2574
137c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
138c5f01b2fSopenharmony_ci
139c5f01b2fSopenharmony_cistruct NonDefaultConstructible
140c5f01b2fSopenharmony_ci{
141c5f01b2fSopenharmony_ci    explicit NonDefaultConstructible(int a)
142c5f01b2fSopenharmony_ci        : x(a)
143c5f01b2fSopenharmony_ci    {}
144c5f01b2fSopenharmony_ci    int x;
145c5f01b2fSopenharmony_ci};
146c5f01b2fSopenharmony_ci
147c5f01b2fSopenharmony_cinamespace nlohmann
148c5f01b2fSopenharmony_ci{
149c5f01b2fSopenharmony_citemplate<>
150c5f01b2fSopenharmony_cistruct adl_serializer<NonDefaultConstructible>
151c5f01b2fSopenharmony_ci{
152c5f01b2fSopenharmony_ci    static NonDefaultConstructible from_json(json const& j)
153c5f01b2fSopenharmony_ci    {
154c5f01b2fSopenharmony_ci        return NonDefaultConstructible(j.get<int>());
155c5f01b2fSopenharmony_ci    }
156c5f01b2fSopenharmony_ci};
157c5f01b2fSopenharmony_ci}  // namespace nlohmann
158c5f01b2fSopenharmony_ci
159c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
160c5f01b2fSopenharmony_ci// for #2824
161c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
162c5f01b2fSopenharmony_ci
163c5f01b2fSopenharmony_ciclass sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
164c5f01b2fSopenharmony_ci{
165c5f01b2fSopenharmony_ci  public:
166c5f01b2fSopenharmony_ci    explicit sax_no_exception(json& j)
167c5f01b2fSopenharmony_ci        : nlohmann::detail::json_sax_dom_parser<json>(j, false)
168c5f01b2fSopenharmony_ci    {}
169c5f01b2fSopenharmony_ci
170c5f01b2fSopenharmony_ci    static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
171c5f01b2fSopenharmony_ci    {
172c5f01b2fSopenharmony_ci        error_string = new std::string(ex.what());  // NOLINT(cppcoreguidelines-owning-memory)
173c5f01b2fSopenharmony_ci        return false;
174c5f01b2fSopenharmony_ci    }
175c5f01b2fSopenharmony_ci
176c5f01b2fSopenharmony_ci    static std::string* error_string;
177c5f01b2fSopenharmony_ci};
178c5f01b2fSopenharmony_ci
179c5f01b2fSopenharmony_cistd::string* sax_no_exception::error_string = nullptr;
180c5f01b2fSopenharmony_ci
181c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
182c5f01b2fSopenharmony_ci// for #2982
183c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
184c5f01b2fSopenharmony_ci
185c5f01b2fSopenharmony_citemplate<class T>
186c5f01b2fSopenharmony_ciclass my_allocator : public std::allocator<T>
187c5f01b2fSopenharmony_ci{
188c5f01b2fSopenharmony_ci  public:
189c5f01b2fSopenharmony_ci    using std::allocator<T>::allocator;
190c5f01b2fSopenharmony_ci};
191c5f01b2fSopenharmony_ci
192c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
193c5f01b2fSopenharmony_ci// for #3077
194c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
195c5f01b2fSopenharmony_ci
196c5f01b2fSopenharmony_ciclass FooAlloc
197c5f01b2fSopenharmony_ci{};
198c5f01b2fSopenharmony_ci
199c5f01b2fSopenharmony_ciclass Foo
200c5f01b2fSopenharmony_ci{
201c5f01b2fSopenharmony_ci  public:
202c5f01b2fSopenharmony_ci    explicit Foo(const FooAlloc& /* unused */ = FooAlloc()) {}
203c5f01b2fSopenharmony_ci
204c5f01b2fSopenharmony_ci    bool value = false;
205c5f01b2fSopenharmony_ci};
206c5f01b2fSopenharmony_ci
207c5f01b2fSopenharmony_ciclass FooBar
208c5f01b2fSopenharmony_ci{
209c5f01b2fSopenharmony_ci  public:
210c5f01b2fSopenharmony_ci    Foo foo{};
211c5f01b2fSopenharmony_ci};
212c5f01b2fSopenharmony_ci
213c5f01b2fSopenharmony_ciinline void from_json(const nlohmann::json& j, FooBar& fb)
214c5f01b2fSopenharmony_ci{
215c5f01b2fSopenharmony_ci    j.at("value").get_to(fb.foo.value);
216c5f01b2fSopenharmony_ci}
217c5f01b2fSopenharmony_ci
218c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
219c5f01b2fSopenharmony_ci// for #3171
220c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
221c5f01b2fSopenharmony_ci
222c5f01b2fSopenharmony_cistruct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
223c5f01b2fSopenharmony_ci{
224c5f01b2fSopenharmony_ci    for_3171_base(const std::string& /*unused*/ = {}) {}
225c5f01b2fSopenharmony_ci    virtual ~for_3171_base() = default;
226c5f01b2fSopenharmony_ci
227c5f01b2fSopenharmony_ci    virtual void _from_json(const json& j)
228c5f01b2fSopenharmony_ci    {
229c5f01b2fSopenharmony_ci        j.at("str").get_to(str);
230c5f01b2fSopenharmony_ci    }
231c5f01b2fSopenharmony_ci
232c5f01b2fSopenharmony_ci    std::string str{};
233c5f01b2fSopenharmony_ci};
234c5f01b2fSopenharmony_ci
235c5f01b2fSopenharmony_cistruct for_3171_derived : public for_3171_base
236c5f01b2fSopenharmony_ci{
237c5f01b2fSopenharmony_ci    for_3171_derived() = default;
238c5f01b2fSopenharmony_ci    explicit for_3171_derived(const std::string& /*unused*/) { }
239c5f01b2fSopenharmony_ci};
240c5f01b2fSopenharmony_ci
241c5f01b2fSopenharmony_ciinline void from_json(const json& j, for_3171_base& tb)
242c5f01b2fSopenharmony_ci{
243c5f01b2fSopenharmony_ci    tb._from_json(j);
244c5f01b2fSopenharmony_ci}
245c5f01b2fSopenharmony_ci
246c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
247c5f01b2fSopenharmony_ci// for #3312
248c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
249c5f01b2fSopenharmony_ci
250c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_20
251c5f01b2fSopenharmony_cistruct for_3312
252c5f01b2fSopenharmony_ci{
253c5f01b2fSopenharmony_ci    std::string name;
254c5f01b2fSopenharmony_ci};
255c5f01b2fSopenharmony_ci
256c5f01b2fSopenharmony_ciinline void from_json(const json& j, for_3312& obj)
257c5f01b2fSopenharmony_ci{
258c5f01b2fSopenharmony_ci    j.at("name").get_to(obj.name);
259c5f01b2fSopenharmony_ci}
260c5f01b2fSopenharmony_ci#endif
261c5f01b2fSopenharmony_ci
262c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
263c5f01b2fSopenharmony_ci// for #3204
264c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
265c5f01b2fSopenharmony_ci
266c5f01b2fSopenharmony_cistruct for_3204_foo
267c5f01b2fSopenharmony_ci{
268c5f01b2fSopenharmony_ci    for_3204_foo() = default;
269c5f01b2fSopenharmony_ci    explicit for_3204_foo(std::string /*unused*/) {} // NOLINT(performance-unnecessary-value-param)
270c5f01b2fSopenharmony_ci};
271c5f01b2fSopenharmony_ci
272c5f01b2fSopenharmony_cistruct for_3204_bar
273c5f01b2fSopenharmony_ci{
274c5f01b2fSopenharmony_ci    enum constructed_from_t
275c5f01b2fSopenharmony_ci    {
276c5f01b2fSopenharmony_ci        constructed_from_none = 0,
277c5f01b2fSopenharmony_ci        constructed_from_foo = 1,
278c5f01b2fSopenharmony_ci        constructed_from_json = 2
279c5f01b2fSopenharmony_ci    };
280c5f01b2fSopenharmony_ci
281c5f01b2fSopenharmony_ci    explicit for_3204_bar(std::function<void(for_3204_foo)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
282c5f01b2fSopenharmony_ci        : constructed_from(constructed_from_foo) {}
283c5f01b2fSopenharmony_ci    explicit for_3204_bar(std::function<void(json)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
284c5f01b2fSopenharmony_ci        : constructed_from(constructed_from_json) {}
285c5f01b2fSopenharmony_ci
286c5f01b2fSopenharmony_ci    constructed_from_t constructed_from = constructed_from_none;
287c5f01b2fSopenharmony_ci};
288c5f01b2fSopenharmony_ci
289c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
290c5f01b2fSopenharmony_ci// for #3333
291c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
292c5f01b2fSopenharmony_ci
293c5f01b2fSopenharmony_cistruct for_3333 final
294c5f01b2fSopenharmony_ci{
295c5f01b2fSopenharmony_ci    for_3333(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}
296c5f01b2fSopenharmony_ci
297c5f01b2fSopenharmony_ci    template <class T>
298c5f01b2fSopenharmony_ci    for_3333(const T& /*unused*/)
299c5f01b2fSopenharmony_ci    {
300c5f01b2fSopenharmony_ci        CHECK(false);
301c5f01b2fSopenharmony_ci    }
302c5f01b2fSopenharmony_ci
303c5f01b2fSopenharmony_ci    int x = 0;
304c5f01b2fSopenharmony_ci    int y = 0;
305c5f01b2fSopenharmony_ci};
306c5f01b2fSopenharmony_ci
307c5f01b2fSopenharmony_citemplate <>
308c5f01b2fSopenharmony_ciinline for_3333::for_3333(const json& j)
309c5f01b2fSopenharmony_ci    : for_3333(j.value("x", 0), j.value("y", 0))
310c5f01b2fSopenharmony_ci{}
311c5f01b2fSopenharmony_ci
312c5f01b2fSopenharmony_ciTEST_CASE("regression tests 2")
313c5f01b2fSopenharmony_ci{
314c5f01b2fSopenharmony_ci    SECTION("issue #1001 - Fix memory leak during parser callback")
315c5f01b2fSopenharmony_ci    {
316c5f01b2fSopenharmony_ci        const auto* geojsonExample = R"(
317c5f01b2fSopenharmony_ci          { "type": "FeatureCollection",
318c5f01b2fSopenharmony_ci            "features": [
319c5f01b2fSopenharmony_ci              { "type": "Feature",
320c5f01b2fSopenharmony_ci                "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
321c5f01b2fSopenharmony_ci                "properties": {"prop0": "value0"}
322c5f01b2fSopenharmony_ci                },
323c5f01b2fSopenharmony_ci              { "type": "Feature",
324c5f01b2fSopenharmony_ci                "geometry": {
325c5f01b2fSopenharmony_ci                  "type": "LineString",
326c5f01b2fSopenharmony_ci                  "coordinates": [
327c5f01b2fSopenharmony_ci                    [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
328c5f01b2fSopenharmony_ci                    ]
329c5f01b2fSopenharmony_ci                  },
330c5f01b2fSopenharmony_ci                "properties": {
331c5f01b2fSopenharmony_ci                  "prop0": "value0",
332c5f01b2fSopenharmony_ci                  "prop1": 0.0
333c5f01b2fSopenharmony_ci                  }
334c5f01b2fSopenharmony_ci                },
335c5f01b2fSopenharmony_ci              { "type": "Feature",
336c5f01b2fSopenharmony_ci                 "geometry": {
337c5f01b2fSopenharmony_ci                   "type": "Polygon",
338c5f01b2fSopenharmony_ci                   "coordinates": [
339c5f01b2fSopenharmony_ci                     [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
340c5f01b2fSopenharmony_ci                       [100.0, 1.0], [100.0, 0.0] ]
341c5f01b2fSopenharmony_ci                     ]
342c5f01b2fSopenharmony_ci                 },
343c5f01b2fSopenharmony_ci                 "properties": {
344c5f01b2fSopenharmony_ci                   "prop0": "value0",
345c5f01b2fSopenharmony_ci                   "prop1": {"this": "that"}
346c5f01b2fSopenharmony_ci                   }
347c5f01b2fSopenharmony_ci                 }
348c5f01b2fSopenharmony_ci               ]
349c5f01b2fSopenharmony_ci             })";
350c5f01b2fSopenharmony_ci
351c5f01b2fSopenharmony_ci        json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed) noexcept
352c5f01b2fSopenharmony_ci        {
353c5f01b2fSopenharmony_ci            // skip uninteresting events
354c5f01b2fSopenharmony_ci            if (event == json::parse_event_t::value && !parsed.is_primitive())
355c5f01b2fSopenharmony_ci            {
356c5f01b2fSopenharmony_ci                return false;
357c5f01b2fSopenharmony_ci            }
358c5f01b2fSopenharmony_ci
359c5f01b2fSopenharmony_ci            switch (event)
360c5f01b2fSopenharmony_ci            {
361c5f01b2fSopenharmony_ci                case json::parse_event_t::key:
362c5f01b2fSopenharmony_ci                {
363c5f01b2fSopenharmony_ci                    return true;
364c5f01b2fSopenharmony_ci                }
365c5f01b2fSopenharmony_ci                case json::parse_event_t::value:
366c5f01b2fSopenharmony_ci                {
367c5f01b2fSopenharmony_ci                    return false;
368c5f01b2fSopenharmony_ci                }
369c5f01b2fSopenharmony_ci                case json::parse_event_t::object_start:
370c5f01b2fSopenharmony_ci                {
371c5f01b2fSopenharmony_ci                    return true;
372c5f01b2fSopenharmony_ci                }
373c5f01b2fSopenharmony_ci                case json::parse_event_t::object_end:
374c5f01b2fSopenharmony_ci                {
375c5f01b2fSopenharmony_ci                    return false;
376c5f01b2fSopenharmony_ci                }
377c5f01b2fSopenharmony_ci                case json::parse_event_t::array_start:
378c5f01b2fSopenharmony_ci                {
379c5f01b2fSopenharmony_ci                    return true;
380c5f01b2fSopenharmony_ci                }
381c5f01b2fSopenharmony_ci                case json::parse_event_t::array_end:
382c5f01b2fSopenharmony_ci                {
383c5f01b2fSopenharmony_ci                    return false;
384c5f01b2fSopenharmony_ci                }
385c5f01b2fSopenharmony_ci
386c5f01b2fSopenharmony_ci                default:
387c5f01b2fSopenharmony_ci                {
388c5f01b2fSopenharmony_ci                    return true;
389c5f01b2fSopenharmony_ci                }
390c5f01b2fSopenharmony_ci            }
391c5f01b2fSopenharmony_ci        };
392c5f01b2fSopenharmony_ci
393c5f01b2fSopenharmony_ci        auto j = json::parse(geojsonExample, cb, true);
394c5f01b2fSopenharmony_ci        CHECK(j == json());
395c5f01b2fSopenharmony_ci    }
396c5f01b2fSopenharmony_ci
397c5f01b2fSopenharmony_ci    SECTION("issue #1021 - to/from_msgpack only works with standard typization")
398c5f01b2fSopenharmony_ci    {
399c5f01b2fSopenharmony_ci        float_json j = 1000.0;
400c5f01b2fSopenharmony_ci        CHECK(float_json::from_cbor(float_json::to_cbor(j)) == j);
401c5f01b2fSopenharmony_ci        CHECK(float_json::from_msgpack(float_json::to_msgpack(j)) == j);
402c5f01b2fSopenharmony_ci        CHECK(float_json::from_ubjson(float_json::to_ubjson(j)) == j);
403c5f01b2fSopenharmony_ci
404c5f01b2fSopenharmony_ci        float_json j2 = {1000.0, 2000.0, 3000.0};
405c5f01b2fSopenharmony_ci        CHECK(float_json::from_ubjson(float_json::to_ubjson(j2, true, true)) == j2);
406c5f01b2fSopenharmony_ci    }
407c5f01b2fSopenharmony_ci
408c5f01b2fSopenharmony_ci    SECTION("issue #1045 - Using STL algorithms with JSON containers with expected results?")
409c5f01b2fSopenharmony_ci    {
410c5f01b2fSopenharmony_ci        json diffs = nlohmann::json::array();
411c5f01b2fSopenharmony_ci        json m1{{"key1", 42}};
412c5f01b2fSopenharmony_ci        json m2{{"key2", 42}};
413c5f01b2fSopenharmony_ci        auto p1 = m1.items();
414c5f01b2fSopenharmony_ci        auto p2 = m2.items();
415c5f01b2fSopenharmony_ci
416c5f01b2fSopenharmony_ci        using it_type = decltype(p1.begin());
417c5f01b2fSopenharmony_ci
418c5f01b2fSopenharmony_ci        std::set_difference(
419c5f01b2fSopenharmony_ci            p1.begin(),
420c5f01b2fSopenharmony_ci            p1.end(),
421c5f01b2fSopenharmony_ci            p2.begin(),
422c5f01b2fSopenharmony_ci            p2.end(),
423c5f01b2fSopenharmony_ci            std::inserter(diffs, diffs.end()),
424c5f01b2fSopenharmony_ci            [&](const it_type & e1, const it_type & e2) -> bool
425c5f01b2fSopenharmony_ci        {
426c5f01b2fSopenharmony_ci            using comper_pair = std::pair<std::string, decltype(e1.value())>;              // Trying to avoid unneeded copy
427c5f01b2fSopenharmony_ci            return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value());  // Using pair comper
428c5f01b2fSopenharmony_ci        });
429c5f01b2fSopenharmony_ci
430c5f01b2fSopenharmony_ci        CHECK(diffs.size() == 1);  // Note the change here, was 2
431c5f01b2fSopenharmony_ci    }
432c5f01b2fSopenharmony_ci
433c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_17
434c5f01b2fSopenharmony_ci    SECTION("issue #1292 - Serializing std::variant causes stack overflow")
435c5f01b2fSopenharmony_ci    {
436c5f01b2fSopenharmony_ci        static_assert(!std::is_constructible<json, std::variant<int, float>>::value, "unexpected value");
437c5f01b2fSopenharmony_ci    }
438c5f01b2fSopenharmony_ci#endif
439c5f01b2fSopenharmony_ci
440c5f01b2fSopenharmony_ci    SECTION("issue #1299 - compile error in from_json converting to container "
441c5f01b2fSopenharmony_ci            "with std::pair")
442c5f01b2fSopenharmony_ci    {
443c5f01b2fSopenharmony_ci        json j =
444c5f01b2fSopenharmony_ci        {
445c5f01b2fSopenharmony_ci            {"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
446c5f01b2fSopenharmony_ci            {"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
447c5f01b2fSopenharmony_ci            {"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
448c5f01b2fSopenharmony_ci        };
449c5f01b2fSopenharmony_ci
450c5f01b2fSopenharmony_ci        std::map<std::string, Data> expected
451c5f01b2fSopenharmony_ci        {
452c5f01b2fSopenharmony_ci            {"1", {"testa_1", "testb_1"}},
453c5f01b2fSopenharmony_ci            {"2", {"testa_2", "testb_2"}},
454c5f01b2fSopenharmony_ci            {"3", {"testa_3", "testb_3"}},
455c5f01b2fSopenharmony_ci        };
456c5f01b2fSopenharmony_ci        const auto data = j.get<decltype(expected)>();
457c5f01b2fSopenharmony_ci        CHECK(expected == data);
458c5f01b2fSopenharmony_ci    }
459c5f01b2fSopenharmony_ci
460c5f01b2fSopenharmony_ci    SECTION("issue #1445 - buffer overflow in dumping invalid utf-8 strings")
461c5f01b2fSopenharmony_ci    {
462c5f01b2fSopenharmony_ci        SECTION("a bunch of -1, ensure_ascii=true")
463c5f01b2fSopenharmony_ci        {
464c5f01b2fSopenharmony_ci            const auto length = 300;
465c5f01b2fSopenharmony_ci
466c5f01b2fSopenharmony_ci            json dump_test;
467c5f01b2fSopenharmony_ci            dump_test["1"] = std::string(length, -1);
468c5f01b2fSopenharmony_ci
469c5f01b2fSopenharmony_ci            std::string expected = R"({"1":")";
470c5f01b2fSopenharmony_ci            for (int i = 0; i < length; ++i)
471c5f01b2fSopenharmony_ci            {
472c5f01b2fSopenharmony_ci                expected += "\\ufffd";
473c5f01b2fSopenharmony_ci            }
474c5f01b2fSopenharmony_ci            expected += "\"}";
475c5f01b2fSopenharmony_ci
476c5f01b2fSopenharmony_ci            auto s = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
477c5f01b2fSopenharmony_ci            CHECK(s == expected);
478c5f01b2fSopenharmony_ci        }
479c5f01b2fSopenharmony_ci        SECTION("a bunch of -2, ensure_ascii=false")
480c5f01b2fSopenharmony_ci        {
481c5f01b2fSopenharmony_ci            const auto length = 500;
482c5f01b2fSopenharmony_ci
483c5f01b2fSopenharmony_ci            json dump_test;
484c5f01b2fSopenharmony_ci            dump_test["1"] = std::string(length, -2);
485c5f01b2fSopenharmony_ci
486c5f01b2fSopenharmony_ci            std::string expected = R"({"1":")";
487c5f01b2fSopenharmony_ci            for (int i = 0; i < length; ++i)
488c5f01b2fSopenharmony_ci            {
489c5f01b2fSopenharmony_ci                expected += "\xEF\xBF\xBD";
490c5f01b2fSopenharmony_ci            }
491c5f01b2fSopenharmony_ci            expected += "\"}";
492c5f01b2fSopenharmony_ci
493c5f01b2fSopenharmony_ci            auto s = dump_test.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);
494c5f01b2fSopenharmony_ci            CHECK(s == expected);
495c5f01b2fSopenharmony_ci        }
496c5f01b2fSopenharmony_ci        SECTION("test case in issue #1445")
497c5f01b2fSopenharmony_ci        {
498c5f01b2fSopenharmony_ci            nlohmann::json dump_test;
499c5f01b2fSopenharmony_ci            const std::array<int, 108> data =
500c5f01b2fSopenharmony_ci            {
501c5f01b2fSopenharmony_ci                {109, 108, 103, 125, -122, -53, 115, 18, 3, 0, 102, 19, 1, 15, -110, 13, -3, -1, -81, 32, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -80, 2, 0, 0, 96, -118, 46, -116, 46, 109, -84, -87, 108, 14, 109, -24, -83, 13, -18, -51, -83, -52, -115, 14, 6, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 3, 0, 0, 0, 35, -74, -73, 55, 57, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, -96, -54, -28, -26}
502c5f01b2fSopenharmony_ci            };
503c5f01b2fSopenharmony_ci            std::string s;
504c5f01b2fSopenharmony_ci            for (int i : data)
505c5f01b2fSopenharmony_ci            {
506c5f01b2fSopenharmony_ci                s += static_cast<char>(i);
507c5f01b2fSopenharmony_ci            }
508c5f01b2fSopenharmony_ci            dump_test["1"] = s;
509c5f01b2fSopenharmony_ci            dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
510c5f01b2fSopenharmony_ci        }
511c5f01b2fSopenharmony_ci    }
512c5f01b2fSopenharmony_ci
513c5f01b2fSopenharmony_ci    SECTION("issue #1447 - Integer Overflow (OSS-Fuzz 12506)")
514c5f01b2fSopenharmony_ci    {
515c5f01b2fSopenharmony_ci        json j = json::parse("[-9223372036854775808]");
516c5f01b2fSopenharmony_ci        CHECK(j.dump() == "[-9223372036854775808]");
517c5f01b2fSopenharmony_ci    }
518c5f01b2fSopenharmony_ci
519c5f01b2fSopenharmony_ci    SECTION("issue #1708 - minimum value of int64_t can be outputted")
520c5f01b2fSopenharmony_ci    {
521c5f01b2fSopenharmony_ci        constexpr auto smallest = (std::numeric_limits<int64_t>::min)();
522c5f01b2fSopenharmony_ci        json j = smallest;
523c5f01b2fSopenharmony_ci        CHECK(j.dump() == std::to_string(smallest));
524c5f01b2fSopenharmony_ci    }
525c5f01b2fSopenharmony_ci
526c5f01b2fSopenharmony_ci    SECTION("issue #1727 - Contains with non-const lvalue json_pointer picks the wrong overload")
527c5f01b2fSopenharmony_ci    {
528c5f01b2fSopenharmony_ci        json j = {{"root", {{"settings", {{"logging", true}}}}}};
529c5f01b2fSopenharmony_ci
530c5f01b2fSopenharmony_ci        auto jptr1 = "/root/settings/logging"_json_pointer;
531c5f01b2fSopenharmony_ci        auto jptr2 = json::json_pointer{"/root/settings/logging"};
532c5f01b2fSopenharmony_ci
533c5f01b2fSopenharmony_ci        CHECK(j.contains(jptr1));
534c5f01b2fSopenharmony_ci        CHECK(j.contains(jptr2));
535c5f01b2fSopenharmony_ci    }
536c5f01b2fSopenharmony_ci
537c5f01b2fSopenharmony_ci    SECTION("issue #1647 - compile error when deserializing enum if both non-default from_json and non-member operator== exists for other type")
538c5f01b2fSopenharmony_ci    {
539c5f01b2fSopenharmony_ci        // does not compile on ICPC when targeting C++20
540c5f01b2fSopenharmony_ci#if !(defined(__INTEL_COMPILER) && __cplusplus >= 202000)
541c5f01b2fSopenharmony_ci        {
542c5f01b2fSopenharmony_ci            json j;
543c5f01b2fSopenharmony_ci            NonDefaultFromJsonStruct x(j);
544c5f01b2fSopenharmony_ci            NonDefaultFromJsonStruct y;
545c5f01b2fSopenharmony_ci            CHECK(x == y);
546c5f01b2fSopenharmony_ci        }
547c5f01b2fSopenharmony_ci#endif
548c5f01b2fSopenharmony_ci
549c5f01b2fSopenharmony_ci        auto val = nlohmann::json("one").get<for_1647>();
550c5f01b2fSopenharmony_ci        CHECK(val == for_1647::one);
551c5f01b2fSopenharmony_ci        json j = val;
552c5f01b2fSopenharmony_ci    }
553c5f01b2fSopenharmony_ci
554c5f01b2fSopenharmony_ci    SECTION("issue #1715 - json::from_cbor does not respect allow_exceptions = false when input is string literal")
555c5f01b2fSopenharmony_ci    {
556c5f01b2fSopenharmony_ci        SECTION("string literal")
557c5f01b2fSopenharmony_ci        {
558c5f01b2fSopenharmony_ci            json cbor = json::from_cbor("B", true, false);
559c5f01b2fSopenharmony_ci            CHECK(cbor.is_discarded());
560c5f01b2fSopenharmony_ci        }
561c5f01b2fSopenharmony_ci
562c5f01b2fSopenharmony_ci        SECTION("string array")
563c5f01b2fSopenharmony_ci        {
564c5f01b2fSopenharmony_ci            const std::array<char, 2> input = {{'B', 0x00}};
565c5f01b2fSopenharmony_ci            json cbor = json::from_cbor(input, true, false);
566c5f01b2fSopenharmony_ci            CHECK(cbor.is_discarded());
567c5f01b2fSopenharmony_ci        }
568c5f01b2fSopenharmony_ci
569c5f01b2fSopenharmony_ci        SECTION("std::string")
570c5f01b2fSopenharmony_ci        {
571c5f01b2fSopenharmony_ci            json cbor = json::from_cbor(std::string("B"), true, false);
572c5f01b2fSopenharmony_ci            CHECK(cbor.is_discarded());
573c5f01b2fSopenharmony_ci        }
574c5f01b2fSopenharmony_ci    }
575c5f01b2fSopenharmony_ci
576c5f01b2fSopenharmony_ci    SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible")
577c5f01b2fSopenharmony_ci    {
578c5f01b2fSopenharmony_ci        static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "unexpected result");
579c5f01b2fSopenharmony_ci        static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "unexpected result");
580c5f01b2fSopenharmony_ci        static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "unexpected result");
581c5f01b2fSopenharmony_ci    }
582c5f01b2fSopenharmony_ci    SECTION("issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible")
583c5f01b2fSopenharmony_ci    {
584c5f01b2fSopenharmony_ci        static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "unexpected result");
585c5f01b2fSopenharmony_ci        static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "unexpected result");
586c5f01b2fSopenharmony_ci        static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "unexpected result");
587c5f01b2fSopenharmony_ci    }
588c5f01b2fSopenharmony_ci
589c5f01b2fSopenharmony_ci    SECTION("issue #1983 - JSON patch diff for op=add formation is not as per standard (RFC 6902)")
590c5f01b2fSopenharmony_ci    {
591c5f01b2fSopenharmony_ci        const auto source = R"({ "foo": [ "1", "2" ] })"_json;
592c5f01b2fSopenharmony_ci        const auto target = R"({"foo": [ "1", "2", "3" ]})"_json;
593c5f01b2fSopenharmony_ci        const auto result = json::diff(source, target);
594c5f01b2fSopenharmony_ci        CHECK(result.dump() == R"([{"op":"add","path":"/foo/-","value":"3"}])");
595c5f01b2fSopenharmony_ci    }
596c5f01b2fSopenharmony_ci
597c5f01b2fSopenharmony_ci    SECTION("issue #2067 - cannot serialize binary data to text JSON")
598c5f01b2fSopenharmony_ci    {
599c5f01b2fSopenharmony_ci        const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};
600c5f01b2fSopenharmony_ci        json j = json::from_msgpack(data.data(), data.size());
601c5f01b2fSopenharmony_ci        CHECK_NOTHROW(
602c5f01b2fSopenharmony_ci            j.dump(4,                             // Indent
603c5f01b2fSopenharmony_ci                   ' ',                           // Indent char
604c5f01b2fSopenharmony_ci                   false,                         // Ensure ascii
605c5f01b2fSopenharmony_ci                   json::error_handler_t::strict  // Error
606c5f01b2fSopenharmony_ci                  ));
607c5f01b2fSopenharmony_ci    }
608c5f01b2fSopenharmony_ci
609c5f01b2fSopenharmony_ci    SECTION("PR #2181 - regression bug with lvalue")
610c5f01b2fSopenharmony_ci    {
611c5f01b2fSopenharmony_ci        // see https://github.com/nlohmann/json/pull/2181#issuecomment-653326060
612c5f01b2fSopenharmony_ci        json j{{"x", "test"}};
613c5f01b2fSopenharmony_ci        std::string defval = "default value";
614c5f01b2fSopenharmony_ci        auto val = j.value("x", defval);
615c5f01b2fSopenharmony_ci        auto val2 = j.value("y", defval);
616c5f01b2fSopenharmony_ci    }
617c5f01b2fSopenharmony_ci
618c5f01b2fSopenharmony_ci    SECTION("issue #2293 - eof doesn't cause parsing to stop")
619c5f01b2fSopenharmony_ci    {
620c5f01b2fSopenharmony_ci        std::vector<uint8_t> data =
621c5f01b2fSopenharmony_ci        {
622c5f01b2fSopenharmony_ci            0x7B,
623c5f01b2fSopenharmony_ci            0x6F,
624c5f01b2fSopenharmony_ci            0x62,
625c5f01b2fSopenharmony_ci            0x6A,
626c5f01b2fSopenharmony_ci            0x65,
627c5f01b2fSopenharmony_ci            0x63,
628c5f01b2fSopenharmony_ci            0x74,
629c5f01b2fSopenharmony_ci            0x20,
630c5f01b2fSopenharmony_ci            0x4F,
631c5f01b2fSopenharmony_ci            0x42
632c5f01b2fSopenharmony_ci        };
633c5f01b2fSopenharmony_ci        json result = json::from_cbor(data, true, false);
634c5f01b2fSopenharmony_ci        CHECK(result.is_discarded());
635c5f01b2fSopenharmony_ci    }
636c5f01b2fSopenharmony_ci
637c5f01b2fSopenharmony_ci    SECTION("issue #2315 - json.update and vector<pair>does not work with ordered_json")
638c5f01b2fSopenharmony_ci    {
639c5f01b2fSopenharmony_ci        nlohmann::ordered_json jsonAnimals = {{"animal", "dog"}};
640c5f01b2fSopenharmony_ci        nlohmann::ordered_json jsonCat = {{"animal", "cat"}};
641c5f01b2fSopenharmony_ci        jsonAnimals.update(jsonCat);
642c5f01b2fSopenharmony_ci        CHECK(jsonAnimals["animal"] == "cat");
643c5f01b2fSopenharmony_ci
644c5f01b2fSopenharmony_ci        auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());
645c5f01b2fSopenharmony_ci        CHECK(jsonAnimals == jsonAnimals_parsed);
646c5f01b2fSopenharmony_ci
647c5f01b2fSopenharmony_ci        std::vector<std::pair<std::string, int64_t>> intData = {std::make_pair("aaaa", 11),
648c5f01b2fSopenharmony_ci                                                                std::make_pair("bbb", 222)
649c5f01b2fSopenharmony_ci                                                               };
650c5f01b2fSopenharmony_ci        nlohmann::ordered_json jsonObj;
651c5f01b2fSopenharmony_ci        for (const auto& data : intData)
652c5f01b2fSopenharmony_ci        {
653c5f01b2fSopenharmony_ci            jsonObj[data.first] = data.second;
654c5f01b2fSopenharmony_ci        }
655c5f01b2fSopenharmony_ci        CHECK(jsonObj["aaaa"] == 11);
656c5f01b2fSopenharmony_ci        CHECK(jsonObj["bbb"] == 222);
657c5f01b2fSopenharmony_ci    }
658c5f01b2fSopenharmony_ci
659c5f01b2fSopenharmony_ci    SECTION("issue #2330 - ignore_comment=true fails on multiple consecutive lines starting with comments")
660c5f01b2fSopenharmony_ci    {
661c5f01b2fSopenharmony_ci        std::string ss = "//\n//\n{\n}\n";
662c5f01b2fSopenharmony_ci        json j = json::parse(ss, nullptr, true, true);
663c5f01b2fSopenharmony_ci        CHECK(j.dump() == "{}");
664c5f01b2fSopenharmony_ci    }
665c5f01b2fSopenharmony_ci
666c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_20
667c5f01b2fSopenharmony_ci    SECTION("issue #2546 - parsing containers of std::byte")
668c5f01b2fSopenharmony_ci    {
669c5f01b2fSopenharmony_ci        const char DATA[] = R"("Hello, world!")"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
670c5f01b2fSopenharmony_ci        const auto s = std::as_bytes(std::span(DATA));
671c5f01b2fSopenharmony_ci        json j = json::parse(s);
672c5f01b2fSopenharmony_ci        CHECK(j.dump() == "\"Hello, world!\"");
673c5f01b2fSopenharmony_ci    }
674c5f01b2fSopenharmony_ci#endif
675c5f01b2fSopenharmony_ci
676c5f01b2fSopenharmony_ci    SECTION("issue #2574 - Deserialization to std::array, std::pair, and std::tuple with non-default constructable types fails")
677c5f01b2fSopenharmony_ci    {
678c5f01b2fSopenharmony_ci        SECTION("std::array")
679c5f01b2fSopenharmony_ci        {
680c5f01b2fSopenharmony_ci            {
681c5f01b2fSopenharmony_ci                json j = {7, 4};
682c5f01b2fSopenharmony_ci                auto arr = j.get<std::array<NonDefaultConstructible, 2>>();
683c5f01b2fSopenharmony_ci                CHECK(arr[0].x == 7);
684c5f01b2fSopenharmony_ci                CHECK(arr[1].x == 4);
685c5f01b2fSopenharmony_ci            }
686c5f01b2fSopenharmony_ci
687c5f01b2fSopenharmony_ci            {
688c5f01b2fSopenharmony_ci                json j = 7;
689c5f01b2fSopenharmony_ci                CHECK_THROWS_AS((j.get<std::array<NonDefaultConstructible, 1>>()), json::type_error);
690c5f01b2fSopenharmony_ci            }
691c5f01b2fSopenharmony_ci        }
692c5f01b2fSopenharmony_ci
693c5f01b2fSopenharmony_ci        SECTION("std::pair")
694c5f01b2fSopenharmony_ci        {
695c5f01b2fSopenharmony_ci            {
696c5f01b2fSopenharmony_ci                json j = {3, 8};
697c5f01b2fSopenharmony_ci                auto p = j.get<std::pair<NonDefaultConstructible, NonDefaultConstructible>>();
698c5f01b2fSopenharmony_ci                CHECK(p.first.x == 3);
699c5f01b2fSopenharmony_ci                CHECK(p.second.x == 8);
700c5f01b2fSopenharmony_ci            }
701c5f01b2fSopenharmony_ci
702c5f01b2fSopenharmony_ci            {
703c5f01b2fSopenharmony_ci                json j = {4, 1};
704c5f01b2fSopenharmony_ci                auto p = j.get<std::pair<int, NonDefaultConstructible>>();
705c5f01b2fSopenharmony_ci                CHECK(p.first == 4);
706c5f01b2fSopenharmony_ci                CHECK(p.second.x == 1);
707c5f01b2fSopenharmony_ci            }
708c5f01b2fSopenharmony_ci
709c5f01b2fSopenharmony_ci            {
710c5f01b2fSopenharmony_ci                json j = {6, 7};
711c5f01b2fSopenharmony_ci                auto p = j.get<std::pair<NonDefaultConstructible, int>>();
712c5f01b2fSopenharmony_ci                CHECK(p.first.x == 6);
713c5f01b2fSopenharmony_ci                CHECK(p.second == 7);
714c5f01b2fSopenharmony_ci            }
715c5f01b2fSopenharmony_ci
716c5f01b2fSopenharmony_ci            {
717c5f01b2fSopenharmony_ci                json j = 7;
718c5f01b2fSopenharmony_ci                CHECK_THROWS_AS((j.get<std::pair<NonDefaultConstructible, int>>()), json::type_error);
719c5f01b2fSopenharmony_ci            }
720c5f01b2fSopenharmony_ci        }
721c5f01b2fSopenharmony_ci
722c5f01b2fSopenharmony_ci        SECTION("std::tuple")
723c5f01b2fSopenharmony_ci        {
724c5f01b2fSopenharmony_ci            {
725c5f01b2fSopenharmony_ci                json j = {9};
726c5f01b2fSopenharmony_ci                auto t = j.get<std::tuple<NonDefaultConstructible>>();
727c5f01b2fSopenharmony_ci                CHECK(std::get<0>(t).x == 9);
728c5f01b2fSopenharmony_ci            }
729c5f01b2fSopenharmony_ci
730c5f01b2fSopenharmony_ci            {
731c5f01b2fSopenharmony_ci                json j = {9, 8, 7};
732c5f01b2fSopenharmony_ci                auto t = j.get<std::tuple<NonDefaultConstructible, int, NonDefaultConstructible>>();
733c5f01b2fSopenharmony_ci                CHECK(std::get<0>(t).x == 9);
734c5f01b2fSopenharmony_ci                CHECK(std::get<1>(t) == 8);
735c5f01b2fSopenharmony_ci                CHECK(std::get<2>(t).x == 7);
736c5f01b2fSopenharmony_ci            }
737c5f01b2fSopenharmony_ci
738c5f01b2fSopenharmony_ci            {
739c5f01b2fSopenharmony_ci                json j = 7;
740c5f01b2fSopenharmony_ci                CHECK_THROWS_AS((j.get<std::tuple<NonDefaultConstructible>>()), json::type_error);
741c5f01b2fSopenharmony_ci            }
742c5f01b2fSopenharmony_ci        }
743c5f01b2fSopenharmony_ci    }
744c5f01b2fSopenharmony_ci
745c5f01b2fSopenharmony_ci    SECTION("issue #2865 - ASAN detects memory leaks")
746c5f01b2fSopenharmony_ci    {
747c5f01b2fSopenharmony_ci        // the code below is expected to not leak memory
748c5f01b2fSopenharmony_ci        {
749c5f01b2fSopenharmony_ci            nlohmann::json o;
750c5f01b2fSopenharmony_ci            std::string s = "bar";
751c5f01b2fSopenharmony_ci
752c5f01b2fSopenharmony_ci            nlohmann::to_json(o["foo"], s);
753c5f01b2fSopenharmony_ci
754c5f01b2fSopenharmony_ci            nlohmann::json p = o;
755c5f01b2fSopenharmony_ci
756c5f01b2fSopenharmony_ci            // call to_json with a non-null JSON value
757c5f01b2fSopenharmony_ci            nlohmann::to_json(p["foo"], s);
758c5f01b2fSopenharmony_ci        }
759c5f01b2fSopenharmony_ci
760c5f01b2fSopenharmony_ci        {
761c5f01b2fSopenharmony_ci            nlohmann::json o;
762c5f01b2fSopenharmony_ci            std::string s = "bar";
763c5f01b2fSopenharmony_ci
764c5f01b2fSopenharmony_ci            nlohmann::to_json(o["foo"], s);
765c5f01b2fSopenharmony_ci
766c5f01b2fSopenharmony_ci            // call to_json with a non-null JSON value
767c5f01b2fSopenharmony_ci            nlohmann::to_json(o["foo"], s);
768c5f01b2fSopenharmony_ci        }
769c5f01b2fSopenharmony_ci    }
770c5f01b2fSopenharmony_ci
771c5f01b2fSopenharmony_ci    SECTION("issue #2824 - encoding of json::exception::what()")
772c5f01b2fSopenharmony_ci    {
773c5f01b2fSopenharmony_ci        json j;
774c5f01b2fSopenharmony_ci        sax_no_exception sax(j);
775c5f01b2fSopenharmony_ci
776c5f01b2fSopenharmony_ci        CHECK(!json::sax_parse("xyz", &sax));
777c5f01b2fSopenharmony_ci        CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
778c5f01b2fSopenharmony_ci        delete sax_no_exception::error_string;  // NOLINT(cppcoreguidelines-owning-memory)
779c5f01b2fSopenharmony_ci    }
780c5f01b2fSopenharmony_ci
781c5f01b2fSopenharmony_ci    SECTION("issue #2825 - Properly constrain the basic_json conversion operator")
782c5f01b2fSopenharmony_ci    {
783c5f01b2fSopenharmony_ci        static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "ordered_json must be copy assignable");
784c5f01b2fSopenharmony_ci    }
785c5f01b2fSopenharmony_ci
786c5f01b2fSopenharmony_ci    SECTION("issue #2958 - Inserting in unordered json using a pointer retains the leading slash")
787c5f01b2fSopenharmony_ci    {
788c5f01b2fSopenharmony_ci        std::string p = "/root";
789c5f01b2fSopenharmony_ci
790c5f01b2fSopenharmony_ci        json test1;
791c5f01b2fSopenharmony_ci        test1[json::json_pointer(p)] = json::object();
792c5f01b2fSopenharmony_ci        CHECK(test1.dump() == "{\"root\":{}}");
793c5f01b2fSopenharmony_ci
794c5f01b2fSopenharmony_ci        ordered_json test2;
795c5f01b2fSopenharmony_ci        test2[ordered_json::json_pointer(p)] = json::object();
796c5f01b2fSopenharmony_ci        CHECK(test2.dump() == "{\"root\":{}}");
797c5f01b2fSopenharmony_ci
798c5f01b2fSopenharmony_ci        // json::json_pointer and ordered_json::json_pointer are the same type; behave as above
799c5f01b2fSopenharmony_ci        ordered_json test3;
800c5f01b2fSopenharmony_ci        test3[json::json_pointer(p)] = json::object();
801c5f01b2fSopenharmony_ci        CHECK(std::is_same<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::value);
802c5f01b2fSopenharmony_ci        CHECK(test3.dump() == "{\"root\":{}}");
803c5f01b2fSopenharmony_ci    }
804c5f01b2fSopenharmony_ci
805c5f01b2fSopenharmony_ci    SECTION("issue #2982 - to_{binary format} does not provide a mechanism for specifying a custom allocator for the returned type")
806c5f01b2fSopenharmony_ci    {
807c5f01b2fSopenharmony_ci        std::vector<std::uint8_t, my_allocator<std::uint8_t>> my_vector;
808c5f01b2fSopenharmony_ci        json j = {1, 2, 3, 4};
809c5f01b2fSopenharmony_ci        json::to_cbor(j, my_vector);
810c5f01b2fSopenharmony_ci        json k = json::from_cbor(my_vector);
811c5f01b2fSopenharmony_ci        CHECK(j == k);
812c5f01b2fSopenharmony_ci    }
813c5f01b2fSopenharmony_ci
814c5f01b2fSopenharmony_ci#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
815c5f01b2fSopenharmony_ci    // JSON_HAS_CPP_17 (do not remove; see note at top of file)
816c5f01b2fSopenharmony_ci    SECTION("issue #3070 - Version 3.10.3 breaks backward-compatibility with 3.10.2 ")
817c5f01b2fSopenharmony_ci    {
818c5f01b2fSopenharmony_ci        nlohmann::detail::std_fs::path text_path("/tmp/text.txt");
819c5f01b2fSopenharmony_ci        json j(text_path);
820c5f01b2fSopenharmony_ci
821c5f01b2fSopenharmony_ci        const auto j_path = j.get<nlohmann::detail::std_fs::path>();
822c5f01b2fSopenharmony_ci        CHECK(j_path == text_path);
823c5f01b2fSopenharmony_ci
824c5f01b2fSopenharmony_ci#if DOCTEST_CLANG || DOCTEST_GCC >= DOCTEST_COMPILER(8, 4, 0)
825c5f01b2fSopenharmony_ci        // only known to work on Clang and GCC >=8.4
826c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
827c5f01b2fSopenharmony_ci#endif
828c5f01b2fSopenharmony_ci    }
829c5f01b2fSopenharmony_ci#endif
830c5f01b2fSopenharmony_ci
831c5f01b2fSopenharmony_ci    SECTION("issue #3077 - explicit constructor with default does not compile")
832c5f01b2fSopenharmony_ci    {
833c5f01b2fSopenharmony_ci        json j;
834c5f01b2fSopenharmony_ci        j[0]["value"] = true;
835c5f01b2fSopenharmony_ci        std::vector<FooBar> foo;
836c5f01b2fSopenharmony_ci        j.get_to(foo);
837c5f01b2fSopenharmony_ci    }
838c5f01b2fSopenharmony_ci
839c5f01b2fSopenharmony_ci    SECTION("issue #3108 - ordered_json doesn't support range based erase")
840c5f01b2fSopenharmony_ci    {
841c5f01b2fSopenharmony_ci        ordered_json j = {1, 2, 2, 4};
842c5f01b2fSopenharmony_ci
843c5f01b2fSopenharmony_ci        auto last = std::unique(j.begin(), j.end());
844c5f01b2fSopenharmony_ci        j.erase(last, j.end());
845c5f01b2fSopenharmony_ci
846c5f01b2fSopenharmony_ci        CHECK(j.dump() == "[1,2,4]");
847c5f01b2fSopenharmony_ci
848c5f01b2fSopenharmony_ci        j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json & val)
849c5f01b2fSopenharmony_ci        {
850c5f01b2fSopenharmony_ci            return val == 2;
851c5f01b2fSopenharmony_ci        }), j.end());
852c5f01b2fSopenharmony_ci
853c5f01b2fSopenharmony_ci        CHECK(j.dump() == "[1,4]");
854c5f01b2fSopenharmony_ci    }
855c5f01b2fSopenharmony_ci
856c5f01b2fSopenharmony_ci    SECTION("issue #3343 - json and ordered_json are not interchangable")
857c5f01b2fSopenharmony_ci    {
858c5f01b2fSopenharmony_ci        json::object_t jobj({ { "product", "one" } });
859c5f01b2fSopenharmony_ci        ordered_json::object_t ojobj({{"product", "one"}});
860c5f01b2fSopenharmony_ci
861c5f01b2fSopenharmony_ci        auto jit = jobj.begin();
862c5f01b2fSopenharmony_ci        auto ojit = ojobj.begin();
863c5f01b2fSopenharmony_ci
864c5f01b2fSopenharmony_ci        CHECK(jit->first == ojit->first);
865c5f01b2fSopenharmony_ci        CHECK(jit->second.get<std::string>() == ojit->second.get<std::string>());
866c5f01b2fSopenharmony_ci    }
867c5f01b2fSopenharmony_ci
868c5f01b2fSopenharmony_ci    SECTION("issue #3171 - if class is_constructible from std::string wrong from_json overload is being selected, compilation failed")
869c5f01b2fSopenharmony_ci    {
870c5f01b2fSopenharmony_ci        json j{{ "str", "value"}};
871c5f01b2fSopenharmony_ci
872c5f01b2fSopenharmony_ci        // failed with: error: no match for ‘operator=’ (operand types are ‘for_3171_derived’ and ‘const nlohmann::basic_json<>::string_t’
873c5f01b2fSopenharmony_ci        //                                               {aka ‘const std::__cxx11::basic_string<char>’})
874c5f01b2fSopenharmony_ci        //                  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
875c5f01b2fSopenharmony_ci        auto td = j.get<for_3171_derived>();
876c5f01b2fSopenharmony_ci
877c5f01b2fSopenharmony_ci        CHECK(td.str == "value");
878c5f01b2fSopenharmony_ci    }
879c5f01b2fSopenharmony_ci
880c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_20
881c5f01b2fSopenharmony_ci    SECTION("issue #3312 - Parse to custom class from unordered_json breaks on G++11.2.0 with C++20")
882c5f01b2fSopenharmony_ci    {
883c5f01b2fSopenharmony_ci        // see test for #3171
884c5f01b2fSopenharmony_ci        ordered_json j = {{"name", "class"}};
885c5f01b2fSopenharmony_ci        for_3312 obj{};
886c5f01b2fSopenharmony_ci
887c5f01b2fSopenharmony_ci        j.get_to(obj);
888c5f01b2fSopenharmony_ci
889c5f01b2fSopenharmony_ci        CHECK(obj.name == "class");
890c5f01b2fSopenharmony_ci    }
891c5f01b2fSopenharmony_ci#endif
892c5f01b2fSopenharmony_ci
893c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_17) && JSON_USE_IMPLICIT_CONVERSIONS
894c5f01b2fSopenharmony_ci    SECTION("issue #3428 - Error occurred when converting nlohmann::json to std::any")
895c5f01b2fSopenharmony_ci    {
896c5f01b2fSopenharmony_ci        json j;
897c5f01b2fSopenharmony_ci        std::any a1 = j;
898c5f01b2fSopenharmony_ci        std::any&& a2 = j;
899c5f01b2fSopenharmony_ci
900c5f01b2fSopenharmony_ci        CHECK(a1.type() == typeid(j));
901c5f01b2fSopenharmony_ci        CHECK(a2.type() == typeid(j));
902c5f01b2fSopenharmony_ci    }
903c5f01b2fSopenharmony_ci#endif
904c5f01b2fSopenharmony_ci
905c5f01b2fSopenharmony_ci    SECTION("issue #3204 - ambiguous regression")
906c5f01b2fSopenharmony_ci    {
907c5f01b2fSopenharmony_ci        for_3204_bar bar_from_foo([](for_3204_foo) noexcept {}); // NOLINT(performance-unnecessary-value-param)
908c5f01b2fSopenharmony_ci        for_3204_bar bar_from_json([](json) noexcept {}); // NOLINT(performance-unnecessary-value-param)
909c5f01b2fSopenharmony_ci
910c5f01b2fSopenharmony_ci        CHECK(bar_from_foo.constructed_from == for_3204_bar::constructed_from_foo);
911c5f01b2fSopenharmony_ci        CHECK(bar_from_json.constructed_from == for_3204_bar::constructed_from_json);
912c5f01b2fSopenharmony_ci    }
913c5f01b2fSopenharmony_ci
914c5f01b2fSopenharmony_ci    SECTION("issue #3333 - Ambiguous conversion from nlohmann::basic_json<> to custom class")
915c5f01b2fSopenharmony_ci    {
916c5f01b2fSopenharmony_ci        const json j
917c5f01b2fSopenharmony_ci        {
918c5f01b2fSopenharmony_ci            {"x", 1},
919c5f01b2fSopenharmony_ci            {"y", 2}
920c5f01b2fSopenharmony_ci        };
921c5f01b2fSopenharmony_ci        for_3333 p = j;
922c5f01b2fSopenharmony_ci
923c5f01b2fSopenharmony_ci        CHECK(p.x == 1);
924c5f01b2fSopenharmony_ci        CHECK(p.y == 2);
925c5f01b2fSopenharmony_ci    }
926c5f01b2fSopenharmony_ci}
927c5f01b2fSopenharmony_ci
928c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING_POP
929