1c5f01b2fSopenharmony_ci//     __ _____ _____ _____
2c5f01b2fSopenharmony_ci//  __|  |   __|     |   | |  JSON for Modern C++
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#pragma once
10c5f01b2fSopenharmony_ci
11c5f01b2fSopenharmony_ci#include <functional> // equal_to, less
12c5f01b2fSopenharmony_ci#include <initializer_list> // initializer_list
13c5f01b2fSopenharmony_ci#include <iterator> // input_iterator_tag, iterator_traits
14c5f01b2fSopenharmony_ci#include <memory> // allocator
15c5f01b2fSopenharmony_ci#include <stdexcept> // for out_of_range
16c5f01b2fSopenharmony_ci#include <type_traits> // enable_if, is_convertible
17c5f01b2fSopenharmony_ci#include <utility> // pair
18c5f01b2fSopenharmony_ci#include <vector> // vector
19c5f01b2fSopenharmony_ci
20c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp>
21c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/type_traits.hpp>
22c5f01b2fSopenharmony_ci
23c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN
24c5f01b2fSopenharmony_ci
25c5f01b2fSopenharmony_ci/// ordered_map: a minimal map-like container that preserves insertion order
26c5f01b2fSopenharmony_ci/// for use within nlohmann::basic_json<ordered_map>
27c5f01b2fSopenharmony_citemplate <class Key, class T, class IgnoredLess = std::less<Key>,
28c5f01b2fSopenharmony_ci          class Allocator = std::allocator<std::pair<const Key, T>>>
29c5f01b2fSopenharmony_ci                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
30c5f01b2fSopenharmony_ci{
31c5f01b2fSopenharmony_ci    using key_type = Key;
32c5f01b2fSopenharmony_ci    using mapped_type = T;
33c5f01b2fSopenharmony_ci    using Container = std::vector<std::pair<const Key, T>, Allocator>;
34c5f01b2fSopenharmony_ci    using iterator = typename Container::iterator;
35c5f01b2fSopenharmony_ci    using const_iterator = typename Container::const_iterator;
36c5f01b2fSopenharmony_ci    using size_type = typename Container::size_type;
37c5f01b2fSopenharmony_ci    using value_type = typename Container::value_type;
38c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_14
39c5f01b2fSopenharmony_ci    using key_compare = std::equal_to<>;
40c5f01b2fSopenharmony_ci#else
41c5f01b2fSopenharmony_ci    using key_compare = std::equal_to<Key>;
42c5f01b2fSopenharmony_ci#endif
43c5f01b2fSopenharmony_ci
44c5f01b2fSopenharmony_ci    // Explicit constructors instead of `using Container::Container`
45c5f01b2fSopenharmony_ci    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
46c5f01b2fSopenharmony_ci    ordered_map() noexcept(noexcept(Container())) : Container{} {}
47c5f01b2fSopenharmony_ci    explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
48c5f01b2fSopenharmony_ci    template <class It>
49c5f01b2fSopenharmony_ci    ordered_map(It first, It last, const Allocator& alloc = Allocator())
50c5f01b2fSopenharmony_ci        : Container{first, last, alloc} {}
51c5f01b2fSopenharmony_ci    ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
52c5f01b2fSopenharmony_ci        : Container{init, alloc} {}
53c5f01b2fSopenharmony_ci
54c5f01b2fSopenharmony_ci    std::pair<iterator, bool> emplace(const key_type& key, T&& t)
55c5f01b2fSopenharmony_ci    {
56c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
57c5f01b2fSopenharmony_ci        {
58c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
59c5f01b2fSopenharmony_ci            {
60c5f01b2fSopenharmony_ci                return {it, false};
61c5f01b2fSopenharmony_ci            }
62c5f01b2fSopenharmony_ci        }
63c5f01b2fSopenharmony_ci        Container::emplace_back(key, std::forward<T>(t));
64c5f01b2fSopenharmony_ci        return {std::prev(this->end()), true};
65c5f01b2fSopenharmony_ci    }
66c5f01b2fSopenharmony_ci
67c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
68c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
69c5f01b2fSopenharmony_ci    std::pair<iterator, bool> emplace(KeyType && key, T && t)
70c5f01b2fSopenharmony_ci    {
71c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
72c5f01b2fSopenharmony_ci        {
73c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
74c5f01b2fSopenharmony_ci            {
75c5f01b2fSopenharmony_ci                return {it, false};
76c5f01b2fSopenharmony_ci            }
77c5f01b2fSopenharmony_ci        }
78c5f01b2fSopenharmony_ci        Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
79c5f01b2fSopenharmony_ci        return {std::prev(this->end()), true};
80c5f01b2fSopenharmony_ci    }
81c5f01b2fSopenharmony_ci
82c5f01b2fSopenharmony_ci    T& operator[](const key_type& key)
83c5f01b2fSopenharmony_ci    {
84c5f01b2fSopenharmony_ci        return emplace(key, T{}).first->second;
85c5f01b2fSopenharmony_ci    }
86c5f01b2fSopenharmony_ci
87c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
88c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
89c5f01b2fSopenharmony_ci    T & operator[](KeyType && key)
90c5f01b2fSopenharmony_ci    {
91c5f01b2fSopenharmony_ci        return emplace(std::forward<KeyType>(key), T{}).first->second;
92c5f01b2fSopenharmony_ci    }
93c5f01b2fSopenharmony_ci
94c5f01b2fSopenharmony_ci    const T& operator[](const key_type& key) const
95c5f01b2fSopenharmony_ci    {
96c5f01b2fSopenharmony_ci        return at(key);
97c5f01b2fSopenharmony_ci    }
98c5f01b2fSopenharmony_ci
99c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
100c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
101c5f01b2fSopenharmony_ci    const T & operator[](KeyType && key) const
102c5f01b2fSopenharmony_ci    {
103c5f01b2fSopenharmony_ci        return at(std::forward<KeyType>(key));
104c5f01b2fSopenharmony_ci    }
105c5f01b2fSopenharmony_ci
106c5f01b2fSopenharmony_ci    T& at(const key_type& key)
107c5f01b2fSopenharmony_ci    {
108c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
109c5f01b2fSopenharmony_ci        {
110c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
111c5f01b2fSopenharmony_ci            {
112c5f01b2fSopenharmony_ci                return it->second;
113c5f01b2fSopenharmony_ci            }
114c5f01b2fSopenharmony_ci        }
115c5f01b2fSopenharmony_ci
116c5f01b2fSopenharmony_ci        JSON_THROW(std::out_of_range("key not found"));
117c5f01b2fSopenharmony_ci    }
118c5f01b2fSopenharmony_ci
119c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
120c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
121c5f01b2fSopenharmony_ci    T & at(KeyType && key)
122c5f01b2fSopenharmony_ci    {
123c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
124c5f01b2fSopenharmony_ci        {
125c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
126c5f01b2fSopenharmony_ci            {
127c5f01b2fSopenharmony_ci                return it->second;
128c5f01b2fSopenharmony_ci            }
129c5f01b2fSopenharmony_ci        }
130c5f01b2fSopenharmony_ci
131c5f01b2fSopenharmony_ci        JSON_THROW(std::out_of_range("key not found"));
132c5f01b2fSopenharmony_ci    }
133c5f01b2fSopenharmony_ci
134c5f01b2fSopenharmony_ci    const T& at(const key_type& key) const
135c5f01b2fSopenharmony_ci    {
136c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
137c5f01b2fSopenharmony_ci        {
138c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
139c5f01b2fSopenharmony_ci            {
140c5f01b2fSopenharmony_ci                return it->second;
141c5f01b2fSopenharmony_ci            }
142c5f01b2fSopenharmony_ci        }
143c5f01b2fSopenharmony_ci
144c5f01b2fSopenharmony_ci        JSON_THROW(std::out_of_range("key not found"));
145c5f01b2fSopenharmony_ci    }
146c5f01b2fSopenharmony_ci
147c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
148c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
149c5f01b2fSopenharmony_ci    const T & at(KeyType && key) const
150c5f01b2fSopenharmony_ci    {
151c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
152c5f01b2fSopenharmony_ci        {
153c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
154c5f01b2fSopenharmony_ci            {
155c5f01b2fSopenharmony_ci                return it->second;
156c5f01b2fSopenharmony_ci            }
157c5f01b2fSopenharmony_ci        }
158c5f01b2fSopenharmony_ci
159c5f01b2fSopenharmony_ci        JSON_THROW(std::out_of_range("key not found"));
160c5f01b2fSopenharmony_ci    }
161c5f01b2fSopenharmony_ci
162c5f01b2fSopenharmony_ci    size_type erase(const key_type& key)
163c5f01b2fSopenharmony_ci    {
164c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
165c5f01b2fSopenharmony_ci        {
166c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
167c5f01b2fSopenharmony_ci            {
168c5f01b2fSopenharmony_ci                // Since we cannot move const Keys, re-construct them in place
169c5f01b2fSopenharmony_ci                for (auto next = it; ++next != this->end(); ++it)
170c5f01b2fSopenharmony_ci                {
171c5f01b2fSopenharmony_ci                    it->~value_type(); // Destroy but keep allocation
172c5f01b2fSopenharmony_ci                    new (&*it) value_type{std::move(*next)};
173c5f01b2fSopenharmony_ci                }
174c5f01b2fSopenharmony_ci                Container::pop_back();
175c5f01b2fSopenharmony_ci                return 1;
176c5f01b2fSopenharmony_ci            }
177c5f01b2fSopenharmony_ci        }
178c5f01b2fSopenharmony_ci        return 0;
179c5f01b2fSopenharmony_ci    }
180c5f01b2fSopenharmony_ci
181c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
182c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
183c5f01b2fSopenharmony_ci    size_type erase(KeyType && key)
184c5f01b2fSopenharmony_ci    {
185c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
186c5f01b2fSopenharmony_ci        {
187c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
188c5f01b2fSopenharmony_ci            {
189c5f01b2fSopenharmony_ci                // Since we cannot move const Keys, re-construct them in place
190c5f01b2fSopenharmony_ci                for (auto next = it; ++next != this->end(); ++it)
191c5f01b2fSopenharmony_ci                {
192c5f01b2fSopenharmony_ci                    it->~value_type(); // Destroy but keep allocation
193c5f01b2fSopenharmony_ci                    new (&*it) value_type{std::move(*next)};
194c5f01b2fSopenharmony_ci                }
195c5f01b2fSopenharmony_ci                Container::pop_back();
196c5f01b2fSopenharmony_ci                return 1;
197c5f01b2fSopenharmony_ci            }
198c5f01b2fSopenharmony_ci        }
199c5f01b2fSopenharmony_ci        return 0;
200c5f01b2fSopenharmony_ci    }
201c5f01b2fSopenharmony_ci
202c5f01b2fSopenharmony_ci    iterator erase(iterator pos)
203c5f01b2fSopenharmony_ci    {
204c5f01b2fSopenharmony_ci        return erase(pos, std::next(pos));
205c5f01b2fSopenharmony_ci    }
206c5f01b2fSopenharmony_ci
207c5f01b2fSopenharmony_ci    iterator erase(iterator first, iterator last)
208c5f01b2fSopenharmony_ci    {
209c5f01b2fSopenharmony_ci        if (first == last)
210c5f01b2fSopenharmony_ci        {
211c5f01b2fSopenharmony_ci            return first;
212c5f01b2fSopenharmony_ci        }
213c5f01b2fSopenharmony_ci
214c5f01b2fSopenharmony_ci        const auto elements_affected = std::distance(first, last);
215c5f01b2fSopenharmony_ci        const auto offset = std::distance(Container::begin(), first);
216c5f01b2fSopenharmony_ci
217c5f01b2fSopenharmony_ci        // This is the start situation. We need to delete elements_affected
218c5f01b2fSopenharmony_ci        // elements (3 in this example: e, f, g), and need to return an
219c5f01b2fSopenharmony_ci        // iterator past the last deleted element (h in this example).
220c5f01b2fSopenharmony_ci        // Note that offset is the distance from the start of the vector
221c5f01b2fSopenharmony_ci        // to first. We will need this later.
222c5f01b2fSopenharmony_ci
223c5f01b2fSopenharmony_ci        // [ a, b, c, d, e, f, g, h, i, j ]
224c5f01b2fSopenharmony_ci        //               ^        ^
225c5f01b2fSopenharmony_ci        //             first    last
226c5f01b2fSopenharmony_ci
227c5f01b2fSopenharmony_ci        // Since we cannot move const Keys, we re-construct them in place.
228c5f01b2fSopenharmony_ci        // We start at first and re-construct (viz. copy) the elements from
229c5f01b2fSopenharmony_ci        // the back of the vector. Example for first iteration:
230c5f01b2fSopenharmony_ci
231c5f01b2fSopenharmony_ci        //               ,--------.
232c5f01b2fSopenharmony_ci        //               v        |   destroy e and re-construct with h
233c5f01b2fSopenharmony_ci        // [ a, b, c, d, e, f, g, h, i, j ]
234c5f01b2fSopenharmony_ci        //               ^        ^
235c5f01b2fSopenharmony_ci        //               it       it + elements_affected
236c5f01b2fSopenharmony_ci
237c5f01b2fSopenharmony_ci        for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
238c5f01b2fSopenharmony_ci        {
239c5f01b2fSopenharmony_ci            it->~value_type(); // destroy but keep allocation
240c5f01b2fSopenharmony_ci            new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
241c5f01b2fSopenharmony_ci        }
242c5f01b2fSopenharmony_ci
243c5f01b2fSopenharmony_ci        // [ a, b, c, d, h, i, j, h, i, j ]
244c5f01b2fSopenharmony_ci        //               ^        ^
245c5f01b2fSopenharmony_ci        //             first    last
246c5f01b2fSopenharmony_ci
247c5f01b2fSopenharmony_ci        // remove the unneeded elements at the end of the vector
248c5f01b2fSopenharmony_ci        Container::resize(this->size() - static_cast<size_type>(elements_affected));
249c5f01b2fSopenharmony_ci
250c5f01b2fSopenharmony_ci        // [ a, b, c, d, h, i, j ]
251c5f01b2fSopenharmony_ci        //               ^        ^
252c5f01b2fSopenharmony_ci        //             first    last
253c5f01b2fSopenharmony_ci
254c5f01b2fSopenharmony_ci        // first is now pointing past the last deleted element, but we cannot
255c5f01b2fSopenharmony_ci        // use this iterator, because it may have been invalidated by the
256c5f01b2fSopenharmony_ci        // resize call. Instead, we can return begin() + offset.
257c5f01b2fSopenharmony_ci        return Container::begin() + offset;
258c5f01b2fSopenharmony_ci    }
259c5f01b2fSopenharmony_ci
260c5f01b2fSopenharmony_ci    size_type count(const key_type& key) const
261c5f01b2fSopenharmony_ci    {
262c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
263c5f01b2fSopenharmony_ci        {
264c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
265c5f01b2fSopenharmony_ci            {
266c5f01b2fSopenharmony_ci                return 1;
267c5f01b2fSopenharmony_ci            }
268c5f01b2fSopenharmony_ci        }
269c5f01b2fSopenharmony_ci        return 0;
270c5f01b2fSopenharmony_ci    }
271c5f01b2fSopenharmony_ci
272c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
273c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
274c5f01b2fSopenharmony_ci    size_type count(KeyType && key) const
275c5f01b2fSopenharmony_ci    {
276c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
277c5f01b2fSopenharmony_ci        {
278c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
279c5f01b2fSopenharmony_ci            {
280c5f01b2fSopenharmony_ci                return 1;
281c5f01b2fSopenharmony_ci            }
282c5f01b2fSopenharmony_ci        }
283c5f01b2fSopenharmony_ci        return 0;
284c5f01b2fSopenharmony_ci    }
285c5f01b2fSopenharmony_ci
286c5f01b2fSopenharmony_ci    iterator find(const key_type& key)
287c5f01b2fSopenharmony_ci    {
288c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
289c5f01b2fSopenharmony_ci        {
290c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
291c5f01b2fSopenharmony_ci            {
292c5f01b2fSopenharmony_ci                return it;
293c5f01b2fSopenharmony_ci            }
294c5f01b2fSopenharmony_ci        }
295c5f01b2fSopenharmony_ci        return Container::end();
296c5f01b2fSopenharmony_ci    }
297c5f01b2fSopenharmony_ci
298c5f01b2fSopenharmony_ci    template<class KeyType, detail::enable_if_t<
299c5f01b2fSopenharmony_ci                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
300c5f01b2fSopenharmony_ci    iterator find(KeyType && key)
301c5f01b2fSopenharmony_ci    {
302c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
303c5f01b2fSopenharmony_ci        {
304c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
305c5f01b2fSopenharmony_ci            {
306c5f01b2fSopenharmony_ci                return it;
307c5f01b2fSopenharmony_ci            }
308c5f01b2fSopenharmony_ci        }
309c5f01b2fSopenharmony_ci        return Container::end();
310c5f01b2fSopenharmony_ci    }
311c5f01b2fSopenharmony_ci
312c5f01b2fSopenharmony_ci    const_iterator find(const key_type& key) const
313c5f01b2fSopenharmony_ci    {
314c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
315c5f01b2fSopenharmony_ci        {
316c5f01b2fSopenharmony_ci            if (m_compare(it->first, key))
317c5f01b2fSopenharmony_ci            {
318c5f01b2fSopenharmony_ci                return it;
319c5f01b2fSopenharmony_ci            }
320c5f01b2fSopenharmony_ci        }
321c5f01b2fSopenharmony_ci        return Container::end();
322c5f01b2fSopenharmony_ci    }
323c5f01b2fSopenharmony_ci
324c5f01b2fSopenharmony_ci    std::pair<iterator, bool> insert( value_type&& value )
325c5f01b2fSopenharmony_ci    {
326c5f01b2fSopenharmony_ci        return emplace(value.first, std::move(value.second));
327c5f01b2fSopenharmony_ci    }
328c5f01b2fSopenharmony_ci
329c5f01b2fSopenharmony_ci    std::pair<iterator, bool> insert( const value_type& value )
330c5f01b2fSopenharmony_ci    {
331c5f01b2fSopenharmony_ci        for (auto it = this->begin(); it != this->end(); ++it)
332c5f01b2fSopenharmony_ci        {
333c5f01b2fSopenharmony_ci            if (m_compare(it->first, value.first))
334c5f01b2fSopenharmony_ci            {
335c5f01b2fSopenharmony_ci                return {it, false};
336c5f01b2fSopenharmony_ci            }
337c5f01b2fSopenharmony_ci        }
338c5f01b2fSopenharmony_ci        Container::push_back(value);
339c5f01b2fSopenharmony_ci        return {--this->end(), true};
340c5f01b2fSopenharmony_ci    }
341c5f01b2fSopenharmony_ci
342c5f01b2fSopenharmony_ci    template<typename InputIt>
343c5f01b2fSopenharmony_ci    using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
344c5f01b2fSopenharmony_ci            std::input_iterator_tag>::value>::type;
345c5f01b2fSopenharmony_ci
346c5f01b2fSopenharmony_ci    template<typename InputIt, typename = require_input_iter<InputIt>>
347c5f01b2fSopenharmony_ci    void insert(InputIt first, InputIt last)
348c5f01b2fSopenharmony_ci    {
349c5f01b2fSopenharmony_ci        for (auto it = first; it != last; ++it)
350c5f01b2fSopenharmony_ci        {
351c5f01b2fSopenharmony_ci            insert(*it);
352c5f01b2fSopenharmony_ci        }
353c5f01b2fSopenharmony_ci    }
354c5f01b2fSopenharmony_ci
355c5f01b2fSopenharmony_ciprivate:
356c5f01b2fSopenharmony_ci    JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
357c5f01b2fSopenharmony_ci};
358c5f01b2fSopenharmony_ci
359c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END
360