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 <array> // array
12c5f01b2fSopenharmony_ci#include <cstddef> // size_t
13c5f01b2fSopenharmony_ci#include <cstring> // strlen
14c5f01b2fSopenharmony_ci#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
15c5f01b2fSopenharmony_ci#include <memory> // shared_ptr, make_shared, addressof
16c5f01b2fSopenharmony_ci#include <numeric> // accumulate
17c5f01b2fSopenharmony_ci#include <string> // string, char_traits
18c5f01b2fSopenharmony_ci#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
19c5f01b2fSopenharmony_ci#include <utility> // pair, declval
20c5f01b2fSopenharmony_ci
21c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO
22c5f01b2fSopenharmony_ci    #include <cstdio>   // FILE *
23c5f01b2fSopenharmony_ci    #include <istream>  // istream
24c5f01b2fSopenharmony_ci#endif                  // JSON_NO_IO
25c5f01b2fSopenharmony_ci
26c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/iterator_traits.hpp>
27c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp>
28c5f01b2fSopenharmony_ci
29c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN
30c5f01b2fSopenharmony_cinamespace detail
31c5f01b2fSopenharmony_ci{
32c5f01b2fSopenharmony_ci
33c5f01b2fSopenharmony_ci/// the supported input formats
34c5f01b2fSopenharmony_cienum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
35c5f01b2fSopenharmony_ci
36c5f01b2fSopenharmony_ci////////////////////
37c5f01b2fSopenharmony_ci// input adapters //
38c5f01b2fSopenharmony_ci////////////////////
39c5f01b2fSopenharmony_ci
40c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO
41c5f01b2fSopenharmony_ci/*!
42c5f01b2fSopenharmony_ciInput adapter for stdio file access. This adapter read only 1 byte and do not use any
43c5f01b2fSopenharmony_ci buffer. This adapter is a very low level adapter.
44c5f01b2fSopenharmony_ci*/
45c5f01b2fSopenharmony_ciclass file_input_adapter
46c5f01b2fSopenharmony_ci{
47c5f01b2fSopenharmony_ci  public:
48c5f01b2fSopenharmony_ci    using char_type = char;
49c5f01b2fSopenharmony_ci
50c5f01b2fSopenharmony_ci    JSON_HEDLEY_NON_NULL(2)
51c5f01b2fSopenharmony_ci    explicit file_input_adapter(std::FILE* f) noexcept
52c5f01b2fSopenharmony_ci        : m_file(f)
53c5f01b2fSopenharmony_ci    {
54c5f01b2fSopenharmony_ci        JSON_ASSERT(m_file != nullptr);
55c5f01b2fSopenharmony_ci    }
56c5f01b2fSopenharmony_ci
57c5f01b2fSopenharmony_ci    // make class move-only
58c5f01b2fSopenharmony_ci    file_input_adapter(const file_input_adapter&) = delete;
59c5f01b2fSopenharmony_ci    file_input_adapter(file_input_adapter&&) noexcept = default;
60c5f01b2fSopenharmony_ci    file_input_adapter& operator=(const file_input_adapter&) = delete;
61c5f01b2fSopenharmony_ci    file_input_adapter& operator=(file_input_adapter&&) = delete;
62c5f01b2fSopenharmony_ci    ~file_input_adapter() = default;
63c5f01b2fSopenharmony_ci
64c5f01b2fSopenharmony_ci    std::char_traits<char>::int_type get_character() noexcept
65c5f01b2fSopenharmony_ci    {
66c5f01b2fSopenharmony_ci        return std::fgetc(m_file);
67c5f01b2fSopenharmony_ci    }
68c5f01b2fSopenharmony_ci
69c5f01b2fSopenharmony_ci  private:
70c5f01b2fSopenharmony_ci    /// the file pointer to read from
71c5f01b2fSopenharmony_ci    std::FILE* m_file;
72c5f01b2fSopenharmony_ci};
73c5f01b2fSopenharmony_ci
74c5f01b2fSopenharmony_ci
75c5f01b2fSopenharmony_ci/*!
76c5f01b2fSopenharmony_ciInput adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
77c5f01b2fSopenharmony_cibeginning of input. Does not support changing the underlying std::streambuf
78c5f01b2fSopenharmony_ciin mid-input. Maintains underlying std::istream and std::streambuf to support
79c5f01b2fSopenharmony_cisubsequent use of standard std::istream operations to process any input
80c5f01b2fSopenharmony_cicharacters following those used in parsing the JSON input.  Clears the
81c5f01b2fSopenharmony_cistd::istream flags; any input errors (e.g., EOF) will be detected by the first
82c5f01b2fSopenharmony_cisubsequent call for input from the std::istream.
83c5f01b2fSopenharmony_ci*/
84c5f01b2fSopenharmony_ciclass input_stream_adapter
85c5f01b2fSopenharmony_ci{
86c5f01b2fSopenharmony_ci  public:
87c5f01b2fSopenharmony_ci    using char_type = char;
88c5f01b2fSopenharmony_ci
89c5f01b2fSopenharmony_ci    ~input_stream_adapter()
90c5f01b2fSopenharmony_ci    {
91c5f01b2fSopenharmony_ci        // clear stream flags; we use underlying streambuf I/O, do not
92c5f01b2fSopenharmony_ci        // maintain ifstream flags, except eof
93c5f01b2fSopenharmony_ci        if (is != nullptr)
94c5f01b2fSopenharmony_ci        {
95c5f01b2fSopenharmony_ci            is->clear(is->rdstate() & std::ios::eofbit);
96c5f01b2fSopenharmony_ci        }
97c5f01b2fSopenharmony_ci    }
98c5f01b2fSopenharmony_ci
99c5f01b2fSopenharmony_ci    explicit input_stream_adapter(std::istream& i)
100c5f01b2fSopenharmony_ci        : is(&i), sb(i.rdbuf())
101c5f01b2fSopenharmony_ci    {}
102c5f01b2fSopenharmony_ci
103c5f01b2fSopenharmony_ci    // delete because of pointer members
104c5f01b2fSopenharmony_ci    input_stream_adapter(const input_stream_adapter&) = delete;
105c5f01b2fSopenharmony_ci    input_stream_adapter& operator=(input_stream_adapter&) = delete;
106c5f01b2fSopenharmony_ci    input_stream_adapter& operator=(input_stream_adapter&&) = delete;
107c5f01b2fSopenharmony_ci
108c5f01b2fSopenharmony_ci    input_stream_adapter(input_stream_adapter&& rhs) noexcept
109c5f01b2fSopenharmony_ci        : is(rhs.is), sb(rhs.sb)
110c5f01b2fSopenharmony_ci    {
111c5f01b2fSopenharmony_ci        rhs.is = nullptr;
112c5f01b2fSopenharmony_ci        rhs.sb = nullptr;
113c5f01b2fSopenharmony_ci    }
114c5f01b2fSopenharmony_ci
115c5f01b2fSopenharmony_ci    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
116c5f01b2fSopenharmony_ci    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
117c5f01b2fSopenharmony_ci    // end up as the same value, e.g. 0xFFFFFFFF.
118c5f01b2fSopenharmony_ci    std::char_traits<char>::int_type get_character()
119c5f01b2fSopenharmony_ci    {
120c5f01b2fSopenharmony_ci        auto res = sb->sbumpc();
121c5f01b2fSopenharmony_ci        // set eof manually, as we don't use the istream interface.
122c5f01b2fSopenharmony_ci        if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
123c5f01b2fSopenharmony_ci        {
124c5f01b2fSopenharmony_ci            is->clear(is->rdstate() | std::ios::eofbit);
125c5f01b2fSopenharmony_ci        }
126c5f01b2fSopenharmony_ci        return res;
127c5f01b2fSopenharmony_ci    }
128c5f01b2fSopenharmony_ci
129c5f01b2fSopenharmony_ci  private:
130c5f01b2fSopenharmony_ci    /// the associated input stream
131c5f01b2fSopenharmony_ci    std::istream* is = nullptr;
132c5f01b2fSopenharmony_ci    std::streambuf* sb = nullptr;
133c5f01b2fSopenharmony_ci};
134c5f01b2fSopenharmony_ci#endif  // JSON_NO_IO
135c5f01b2fSopenharmony_ci
136c5f01b2fSopenharmony_ci// General-purpose iterator-based adapter. It might not be as fast as
137c5f01b2fSopenharmony_ci// theoretically possible for some containers, but it is extremely versatile.
138c5f01b2fSopenharmony_citemplate<typename IteratorType>
139c5f01b2fSopenharmony_ciclass iterator_input_adapter
140c5f01b2fSopenharmony_ci{
141c5f01b2fSopenharmony_ci  public:
142c5f01b2fSopenharmony_ci    using char_type = typename std::iterator_traits<IteratorType>::value_type;
143c5f01b2fSopenharmony_ci
144c5f01b2fSopenharmony_ci    iterator_input_adapter(IteratorType first, IteratorType last)
145c5f01b2fSopenharmony_ci        : current(std::move(first)), end(std::move(last))
146c5f01b2fSopenharmony_ci    {}
147c5f01b2fSopenharmony_ci
148c5f01b2fSopenharmony_ci    typename std::char_traits<char_type>::int_type get_character()
149c5f01b2fSopenharmony_ci    {
150c5f01b2fSopenharmony_ci        if (JSON_HEDLEY_LIKELY(current != end))
151c5f01b2fSopenharmony_ci        {
152c5f01b2fSopenharmony_ci            auto result = std::char_traits<char_type>::to_int_type(*current);
153c5f01b2fSopenharmony_ci            std::advance(current, 1);
154c5f01b2fSopenharmony_ci            return result;
155c5f01b2fSopenharmony_ci        }
156c5f01b2fSopenharmony_ci
157c5f01b2fSopenharmony_ci        return std::char_traits<char_type>::eof();
158c5f01b2fSopenharmony_ci    }
159c5f01b2fSopenharmony_ci
160c5f01b2fSopenharmony_ci  private:
161c5f01b2fSopenharmony_ci    IteratorType current;
162c5f01b2fSopenharmony_ci    IteratorType end;
163c5f01b2fSopenharmony_ci
164c5f01b2fSopenharmony_ci    template<typename BaseInputAdapter, size_t T>
165c5f01b2fSopenharmony_ci    friend struct wide_string_input_helper;
166c5f01b2fSopenharmony_ci
167c5f01b2fSopenharmony_ci    bool empty() const
168c5f01b2fSopenharmony_ci    {
169c5f01b2fSopenharmony_ci        return current == end;
170c5f01b2fSopenharmony_ci    }
171c5f01b2fSopenharmony_ci};
172c5f01b2fSopenharmony_ci
173c5f01b2fSopenharmony_ci
174c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter, size_t T>
175c5f01b2fSopenharmony_cistruct wide_string_input_helper;
176c5f01b2fSopenharmony_ci
177c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter>
178c5f01b2fSopenharmony_cistruct wide_string_input_helper<BaseInputAdapter, 4>
179c5f01b2fSopenharmony_ci{
180c5f01b2fSopenharmony_ci    // UTF-32
181c5f01b2fSopenharmony_ci    static void fill_buffer(BaseInputAdapter& input,
182c5f01b2fSopenharmony_ci                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
183c5f01b2fSopenharmony_ci                            size_t& utf8_bytes_index,
184c5f01b2fSopenharmony_ci                            size_t& utf8_bytes_filled)
185c5f01b2fSopenharmony_ci    {
186c5f01b2fSopenharmony_ci        utf8_bytes_index = 0;
187c5f01b2fSopenharmony_ci
188c5f01b2fSopenharmony_ci        if (JSON_HEDLEY_UNLIKELY(input.empty()))
189c5f01b2fSopenharmony_ci        {
190c5f01b2fSopenharmony_ci            utf8_bytes[0] = std::char_traits<char>::eof();
191c5f01b2fSopenharmony_ci            utf8_bytes_filled = 1;
192c5f01b2fSopenharmony_ci        }
193c5f01b2fSopenharmony_ci        else
194c5f01b2fSopenharmony_ci        {
195c5f01b2fSopenharmony_ci            // get the current character
196c5f01b2fSopenharmony_ci            const auto wc = input.get_character();
197c5f01b2fSopenharmony_ci
198c5f01b2fSopenharmony_ci            // UTF-32 to UTF-8 encoding
199c5f01b2fSopenharmony_ci            if (wc < 0x80)
200c5f01b2fSopenharmony_ci            {
201c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
202c5f01b2fSopenharmony_ci                utf8_bytes_filled = 1;
203c5f01b2fSopenharmony_ci            }
204c5f01b2fSopenharmony_ci            else if (wc <= 0x7FF)
205c5f01b2fSopenharmony_ci            {
206c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
207c5f01b2fSopenharmony_ci                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
208c5f01b2fSopenharmony_ci                utf8_bytes_filled = 2;
209c5f01b2fSopenharmony_ci            }
210c5f01b2fSopenharmony_ci            else if (wc <= 0xFFFF)
211c5f01b2fSopenharmony_ci            {
212c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
213c5f01b2fSopenharmony_ci                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
214c5f01b2fSopenharmony_ci                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
215c5f01b2fSopenharmony_ci                utf8_bytes_filled = 3;
216c5f01b2fSopenharmony_ci            }
217c5f01b2fSopenharmony_ci            else if (wc <= 0x10FFFF)
218c5f01b2fSopenharmony_ci            {
219c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
220c5f01b2fSopenharmony_ci                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
221c5f01b2fSopenharmony_ci                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
222c5f01b2fSopenharmony_ci                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
223c5f01b2fSopenharmony_ci                utf8_bytes_filled = 4;
224c5f01b2fSopenharmony_ci            }
225c5f01b2fSopenharmony_ci            else
226c5f01b2fSopenharmony_ci            {
227c5f01b2fSopenharmony_ci                // unknown character
228c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
229c5f01b2fSopenharmony_ci                utf8_bytes_filled = 1;
230c5f01b2fSopenharmony_ci            }
231c5f01b2fSopenharmony_ci        }
232c5f01b2fSopenharmony_ci    }
233c5f01b2fSopenharmony_ci};
234c5f01b2fSopenharmony_ci
235c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter>
236c5f01b2fSopenharmony_cistruct wide_string_input_helper<BaseInputAdapter, 2>
237c5f01b2fSopenharmony_ci{
238c5f01b2fSopenharmony_ci    // UTF-16
239c5f01b2fSopenharmony_ci    static void fill_buffer(BaseInputAdapter& input,
240c5f01b2fSopenharmony_ci                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
241c5f01b2fSopenharmony_ci                            size_t& utf8_bytes_index,
242c5f01b2fSopenharmony_ci                            size_t& utf8_bytes_filled)
243c5f01b2fSopenharmony_ci    {
244c5f01b2fSopenharmony_ci        utf8_bytes_index = 0;
245c5f01b2fSopenharmony_ci
246c5f01b2fSopenharmony_ci        if (JSON_HEDLEY_UNLIKELY(input.empty()))
247c5f01b2fSopenharmony_ci        {
248c5f01b2fSopenharmony_ci            utf8_bytes[0] = std::char_traits<char>::eof();
249c5f01b2fSopenharmony_ci            utf8_bytes_filled = 1;
250c5f01b2fSopenharmony_ci        }
251c5f01b2fSopenharmony_ci        else
252c5f01b2fSopenharmony_ci        {
253c5f01b2fSopenharmony_ci            // get the current character
254c5f01b2fSopenharmony_ci            const auto wc = input.get_character();
255c5f01b2fSopenharmony_ci
256c5f01b2fSopenharmony_ci            // UTF-16 to UTF-8 encoding
257c5f01b2fSopenharmony_ci            if (wc < 0x80)
258c5f01b2fSopenharmony_ci            {
259c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
260c5f01b2fSopenharmony_ci                utf8_bytes_filled = 1;
261c5f01b2fSopenharmony_ci            }
262c5f01b2fSopenharmony_ci            else if (wc <= 0x7FF)
263c5f01b2fSopenharmony_ci            {
264c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
265c5f01b2fSopenharmony_ci                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
266c5f01b2fSopenharmony_ci                utf8_bytes_filled = 2;
267c5f01b2fSopenharmony_ci            }
268c5f01b2fSopenharmony_ci            else if (0xD800 > wc || wc >= 0xE000)
269c5f01b2fSopenharmony_ci            {
270c5f01b2fSopenharmony_ci                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
271c5f01b2fSopenharmony_ci                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
272c5f01b2fSopenharmony_ci                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
273c5f01b2fSopenharmony_ci                utf8_bytes_filled = 3;
274c5f01b2fSopenharmony_ci            }
275c5f01b2fSopenharmony_ci            else
276c5f01b2fSopenharmony_ci            {
277c5f01b2fSopenharmony_ci                if (JSON_HEDLEY_UNLIKELY(!input.empty()))
278c5f01b2fSopenharmony_ci                {
279c5f01b2fSopenharmony_ci                    const auto wc2 = static_cast<unsigned int>(input.get_character());
280c5f01b2fSopenharmony_ci                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
281c5f01b2fSopenharmony_ci                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
282c5f01b2fSopenharmony_ci                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
283c5f01b2fSopenharmony_ci                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
284c5f01b2fSopenharmony_ci                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
285c5f01b2fSopenharmony_ci                    utf8_bytes_filled = 4;
286c5f01b2fSopenharmony_ci                }
287c5f01b2fSopenharmony_ci                else
288c5f01b2fSopenharmony_ci                {
289c5f01b2fSopenharmony_ci                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
290c5f01b2fSopenharmony_ci                    utf8_bytes_filled = 1;
291c5f01b2fSopenharmony_ci                }
292c5f01b2fSopenharmony_ci            }
293c5f01b2fSopenharmony_ci        }
294c5f01b2fSopenharmony_ci    }
295c5f01b2fSopenharmony_ci};
296c5f01b2fSopenharmony_ci
297c5f01b2fSopenharmony_ci// Wraps another input apdater to convert wide character types into individual bytes.
298c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter, typename WideCharType>
299c5f01b2fSopenharmony_ciclass wide_string_input_adapter
300c5f01b2fSopenharmony_ci{
301c5f01b2fSopenharmony_ci  public:
302c5f01b2fSopenharmony_ci    using char_type = char;
303c5f01b2fSopenharmony_ci
304c5f01b2fSopenharmony_ci    wide_string_input_adapter(BaseInputAdapter base)
305c5f01b2fSopenharmony_ci        : base_adapter(base) {}
306c5f01b2fSopenharmony_ci
307c5f01b2fSopenharmony_ci    typename std::char_traits<char>::int_type get_character() noexcept
308c5f01b2fSopenharmony_ci    {
309c5f01b2fSopenharmony_ci        // check if buffer needs to be filled
310c5f01b2fSopenharmony_ci        if (utf8_bytes_index == utf8_bytes_filled)
311c5f01b2fSopenharmony_ci        {
312c5f01b2fSopenharmony_ci            fill_buffer<sizeof(WideCharType)>();
313c5f01b2fSopenharmony_ci
314c5f01b2fSopenharmony_ci            JSON_ASSERT(utf8_bytes_filled > 0);
315c5f01b2fSopenharmony_ci            JSON_ASSERT(utf8_bytes_index == 0);
316c5f01b2fSopenharmony_ci        }
317c5f01b2fSopenharmony_ci
318c5f01b2fSopenharmony_ci        // use buffer
319c5f01b2fSopenharmony_ci        JSON_ASSERT(utf8_bytes_filled > 0);
320c5f01b2fSopenharmony_ci        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
321c5f01b2fSopenharmony_ci        return utf8_bytes[utf8_bytes_index++];
322c5f01b2fSopenharmony_ci    }
323c5f01b2fSopenharmony_ci
324c5f01b2fSopenharmony_ci  private:
325c5f01b2fSopenharmony_ci    BaseInputAdapter base_adapter;
326c5f01b2fSopenharmony_ci
327c5f01b2fSopenharmony_ci    template<size_t T>
328c5f01b2fSopenharmony_ci    void fill_buffer()
329c5f01b2fSopenharmony_ci    {
330c5f01b2fSopenharmony_ci        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
331c5f01b2fSopenharmony_ci    }
332c5f01b2fSopenharmony_ci
333c5f01b2fSopenharmony_ci    /// a buffer for UTF-8 bytes
334c5f01b2fSopenharmony_ci    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
335c5f01b2fSopenharmony_ci
336c5f01b2fSopenharmony_ci    /// index to the utf8_codes array for the next valid byte
337c5f01b2fSopenharmony_ci    std::size_t utf8_bytes_index = 0;
338c5f01b2fSopenharmony_ci    /// number of valid bytes in the utf8_codes array
339c5f01b2fSopenharmony_ci    std::size_t utf8_bytes_filled = 0;
340c5f01b2fSopenharmony_ci};
341c5f01b2fSopenharmony_ci
342c5f01b2fSopenharmony_ci
343c5f01b2fSopenharmony_citemplate<typename IteratorType, typename Enable = void>
344c5f01b2fSopenharmony_cistruct iterator_input_adapter_factory
345c5f01b2fSopenharmony_ci{
346c5f01b2fSopenharmony_ci    using iterator_type = IteratorType;
347c5f01b2fSopenharmony_ci    using char_type = typename std::iterator_traits<iterator_type>::value_type;
348c5f01b2fSopenharmony_ci    using adapter_type = iterator_input_adapter<iterator_type>;
349c5f01b2fSopenharmony_ci
350c5f01b2fSopenharmony_ci    static adapter_type create(IteratorType first, IteratorType last)
351c5f01b2fSopenharmony_ci    {
352c5f01b2fSopenharmony_ci        return adapter_type(std::move(first), std::move(last));
353c5f01b2fSopenharmony_ci    }
354c5f01b2fSopenharmony_ci};
355c5f01b2fSopenharmony_ci
356c5f01b2fSopenharmony_citemplate<typename T>
357c5f01b2fSopenharmony_cistruct is_iterator_of_multibyte
358c5f01b2fSopenharmony_ci{
359c5f01b2fSopenharmony_ci    using value_type = typename std::iterator_traits<T>::value_type;
360c5f01b2fSopenharmony_ci    enum
361c5f01b2fSopenharmony_ci    {
362c5f01b2fSopenharmony_ci        value = sizeof(value_type) > 1
363c5f01b2fSopenharmony_ci    };
364c5f01b2fSopenharmony_ci};
365c5f01b2fSopenharmony_ci
366c5f01b2fSopenharmony_citemplate<typename IteratorType>
367c5f01b2fSopenharmony_cistruct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
368c5f01b2fSopenharmony_ci{
369c5f01b2fSopenharmony_ci    using iterator_type = IteratorType;
370c5f01b2fSopenharmony_ci    using char_type = typename std::iterator_traits<iterator_type>::value_type;
371c5f01b2fSopenharmony_ci    using base_adapter_type = iterator_input_adapter<iterator_type>;
372c5f01b2fSopenharmony_ci    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
373c5f01b2fSopenharmony_ci
374c5f01b2fSopenharmony_ci    static adapter_type create(IteratorType first, IteratorType last)
375c5f01b2fSopenharmony_ci    {
376c5f01b2fSopenharmony_ci        return adapter_type(base_adapter_type(std::move(first), std::move(last)));
377c5f01b2fSopenharmony_ci    }
378c5f01b2fSopenharmony_ci};
379c5f01b2fSopenharmony_ci
380c5f01b2fSopenharmony_ci// General purpose iterator-based input
381c5f01b2fSopenharmony_citemplate<typename IteratorType>
382c5f01b2fSopenharmony_citypename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
383c5f01b2fSopenharmony_ci{
384c5f01b2fSopenharmony_ci    using factory_type = iterator_input_adapter_factory<IteratorType>;
385c5f01b2fSopenharmony_ci    return factory_type::create(first, last);
386c5f01b2fSopenharmony_ci}
387c5f01b2fSopenharmony_ci
388c5f01b2fSopenharmony_ci// Convenience shorthand from container to iterator
389c5f01b2fSopenharmony_ci// Enables ADL on begin(container) and end(container)
390c5f01b2fSopenharmony_ci// Encloses the using declarations in namespace for not to leak them to outside scope
391c5f01b2fSopenharmony_ci
392c5f01b2fSopenharmony_cinamespace container_input_adapter_factory_impl
393c5f01b2fSopenharmony_ci{
394c5f01b2fSopenharmony_ci
395c5f01b2fSopenharmony_ciusing std::begin;
396c5f01b2fSopenharmony_ciusing std::end;
397c5f01b2fSopenharmony_ci
398c5f01b2fSopenharmony_citemplate<typename ContainerType, typename Enable = void>
399c5f01b2fSopenharmony_cistruct container_input_adapter_factory {};
400c5f01b2fSopenharmony_ci
401c5f01b2fSopenharmony_citemplate<typename ContainerType>
402c5f01b2fSopenharmony_cistruct container_input_adapter_factory< ContainerType,
403c5f01b2fSopenharmony_ci       void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
404c5f01b2fSopenharmony_ci       {
405c5f01b2fSopenharmony_ci           using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
406c5f01b2fSopenharmony_ci
407c5f01b2fSopenharmony_ci           static adapter_type create(const ContainerType& container)
408c5f01b2fSopenharmony_ci{
409c5f01b2fSopenharmony_ci    return input_adapter(begin(container), end(container));
410c5f01b2fSopenharmony_ci}
411c5f01b2fSopenharmony_ci       };
412c5f01b2fSopenharmony_ci
413c5f01b2fSopenharmony_ci}  // namespace container_input_adapter_factory_impl
414c5f01b2fSopenharmony_ci
415c5f01b2fSopenharmony_citemplate<typename ContainerType>
416c5f01b2fSopenharmony_citypename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
417c5f01b2fSopenharmony_ci{
418c5f01b2fSopenharmony_ci    return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
419c5f01b2fSopenharmony_ci}
420c5f01b2fSopenharmony_ci
421c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO
422c5f01b2fSopenharmony_ci// Special cases with fast paths
423c5f01b2fSopenharmony_ciinline file_input_adapter input_adapter(std::FILE* file)
424c5f01b2fSopenharmony_ci{
425c5f01b2fSopenharmony_ci    return file_input_adapter(file);
426c5f01b2fSopenharmony_ci}
427c5f01b2fSopenharmony_ci
428c5f01b2fSopenharmony_ciinline input_stream_adapter input_adapter(std::istream& stream)
429c5f01b2fSopenharmony_ci{
430c5f01b2fSopenharmony_ci    return input_stream_adapter(stream);
431c5f01b2fSopenharmony_ci}
432c5f01b2fSopenharmony_ci
433c5f01b2fSopenharmony_ciinline input_stream_adapter input_adapter(std::istream&& stream)
434c5f01b2fSopenharmony_ci{
435c5f01b2fSopenharmony_ci    return input_stream_adapter(stream);
436c5f01b2fSopenharmony_ci}
437c5f01b2fSopenharmony_ci#endif  // JSON_NO_IO
438c5f01b2fSopenharmony_ci
439c5f01b2fSopenharmony_ciusing contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
440c5f01b2fSopenharmony_ci
441c5f01b2fSopenharmony_ci// Null-delimited strings, and the like.
442c5f01b2fSopenharmony_citemplate < typename CharT,
443c5f01b2fSopenharmony_ci           typename std::enable_if <
444c5f01b2fSopenharmony_ci               std::is_pointer<CharT>::value&&
445c5f01b2fSopenharmony_ci               !std::is_array<CharT>::value&&
446c5f01b2fSopenharmony_ci               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
447c5f01b2fSopenharmony_ci               sizeof(typename std::remove_pointer<CharT>::type) == 1,
448c5f01b2fSopenharmony_ci               int >::type = 0 >
449c5f01b2fSopenharmony_cicontiguous_bytes_input_adapter input_adapter(CharT b)
450c5f01b2fSopenharmony_ci{
451c5f01b2fSopenharmony_ci    auto length = std::strlen(reinterpret_cast<const char*>(b));
452c5f01b2fSopenharmony_ci    const auto* ptr = reinterpret_cast<const char*>(b);
453c5f01b2fSopenharmony_ci    return input_adapter(ptr, ptr + length);
454c5f01b2fSopenharmony_ci}
455c5f01b2fSopenharmony_ci
456c5f01b2fSopenharmony_citemplate<typename T, std::size_t N>
457c5f01b2fSopenharmony_ciauto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
458c5f01b2fSopenharmony_ci{
459c5f01b2fSopenharmony_ci    return input_adapter(array, array + N);
460c5f01b2fSopenharmony_ci}
461c5f01b2fSopenharmony_ci
462c5f01b2fSopenharmony_ci// This class only handles inputs of input_buffer_adapter type.
463c5f01b2fSopenharmony_ci// It's required so that expressions like {ptr, len} can be implicitly cast
464c5f01b2fSopenharmony_ci// to the correct adapter.
465c5f01b2fSopenharmony_ciclass span_input_adapter
466c5f01b2fSopenharmony_ci{
467c5f01b2fSopenharmony_ci  public:
468c5f01b2fSopenharmony_ci    template < typename CharT,
469c5f01b2fSopenharmony_ci               typename std::enable_if <
470c5f01b2fSopenharmony_ci                   std::is_pointer<CharT>::value&&
471c5f01b2fSopenharmony_ci                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
472c5f01b2fSopenharmony_ci                   sizeof(typename std::remove_pointer<CharT>::type) == 1,
473c5f01b2fSopenharmony_ci                   int >::type = 0 >
474c5f01b2fSopenharmony_ci    span_input_adapter(CharT b, std::size_t l)
475c5f01b2fSopenharmony_ci        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
476c5f01b2fSopenharmony_ci
477c5f01b2fSopenharmony_ci    template<class IteratorType,
478c5f01b2fSopenharmony_ci             typename std::enable_if<
479c5f01b2fSopenharmony_ci                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
480c5f01b2fSopenharmony_ci                 int>::type = 0>
481c5f01b2fSopenharmony_ci    span_input_adapter(IteratorType first, IteratorType last)
482c5f01b2fSopenharmony_ci        : ia(input_adapter(first, last)) {}
483c5f01b2fSopenharmony_ci
484c5f01b2fSopenharmony_ci    contiguous_bytes_input_adapter&& get()
485c5f01b2fSopenharmony_ci    {
486c5f01b2fSopenharmony_ci        return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
487c5f01b2fSopenharmony_ci    }
488c5f01b2fSopenharmony_ci
489c5f01b2fSopenharmony_ci  private:
490c5f01b2fSopenharmony_ci    contiguous_bytes_input_adapter ia;
491c5f01b2fSopenharmony_ci};
492c5f01b2fSopenharmony_ci
493c5f01b2fSopenharmony_ci}  // namespace detail
494c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END
495