// __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013-2026 Niels Lohmann // SPDX-License-Identifier: MIT #pragma once #include // max #include // size_t #include // istream, streambuf #include // basic_string, char_traits, string #include // decay, integral_constant, is_array, is_const, is_integral, is_lvalue_reference, is_pointer, is_same, remove_cv, remove_extent, remove_pointer, remove_reference #include // forward #include #include #if NLOHMANN_VIEW_HAS_CPP_17 #include // string_view #endif NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { namespace view { /// how a document takes its input enum class input_kind { move_string, ///< non-const rvalue std::string: owned without a copy c_string, ///< pointer to single-byte characters (NUL-terminated): borrowed char_array, ///< array of single-byte characters (e.g. a string literal): borrowed borrow_range, ///< lvalue contiguous byte container, or std::string_view: borrowed copy_range, ///< rvalue contiguous byte container (a const rvalue std::string too): copied wide_c_string, ///< pointer to wide characters (NUL-terminated): converted to UTF-8 into a buffer adapter, ///< streams, FILE*, wide strings and arrays, and the rest of what the library's input adapter reads: read into a buffer }; /// a single-byte character type (char, signed/unsigned char, char8_t, std::uint8_t, ...) template struct is_byte_char : std::integral_constant < bool, std::is_integral::value && sizeof(T) == 1 > {}; // NOLINT(bugprone-sizeof-expression): T is any pointee or element type /// a character type the library's input adapter converts to UTF-8 template struct is_wide_char : std::integral_constant < bool, std::is_same::value || std::is_same::value || std::is_same::value > {}; template struct classify_input { using R = typename std::remove_reference::type; using D = typename std::decay::type; using element = typename std::remove_cv::type>::type; using pointee = typename std::remove_cv::type>::type; static constexpr bool is_rvalue = !std::is_lvalue_reference::value; static constexpr bool is_bytes = is_contiguous_byte_container::value; #if NLOHMANN_VIEW_HAS_CPP_17 static constexpr bool is_string_view = std::is_same::value; #else static constexpr bool is_string_view = false; #endif // NOLINTBEGIN(readability-avoid-nested-conditional-operator): a constant expression of C++11 // (arrays and pointers of other types, such as wide-character arrays and // FILE*, go to the library's input adapter) static constexpr input_kind value = (std::is_array::value && is_byte_char::value) ? input_kind::char_array : std::is_array::value ? input_kind::adapter : (std::is_pointer::value && is_byte_char::value) ? input_kind::c_string : (std::is_pointer::value && is_wide_char::value) ? input_kind::wide_c_string : std::is_pointer::value ? input_kind::adapter : (is_rvalue && !std::is_const::value && std::is_same::value) ? input_kind::move_string : (is_bytes && (!is_rvalue || is_string_view)) ? input_kind::borrow_range : is_bytes ? input_kind::copy_range : input_kind::adapter; // NOLINTEND(readability-avoid-nested-conditional-operator) }; /// an integer type other than bool: a length passed where a flag is expected template struct is_integer_not_bool : std::is_integral {}; template<> struct is_integer_not_bool : std::false_type {}; /// std::basic_string guarantees a NUL at data()[size()] (the parser's sentinel) template struct is_std_string : std::false_type {}; template struct is_std_string> : std::true_type {}; /// append what a json input adapter yields (UTF-16/32 inputs arrive as UTF-8) template void append_adapter(std::string& buf, Adapter ia) { for (;;) { const auto ch = ia.get_character(); if (ch == std::char_traits::eof()) { break; } buf.push_back(static_cast(ch)); } } /// an input adapter made by the document for an input that the library's /// input_adapter() does not take as one argument (an iterator range, a wide C /// string), to be appended with append_adapter() template struct adapter_input { Adapter ia; }; template struct is_adapter_input : std::false_type {}; template struct is_adapter_input> : std::true_type {}; template adapter_input::type> make_adapter_input(Adapter&& ia) { return {std::forward(ia)}; } /// append the rest of a stream: its characters need no conversion, so they are /// read in blocks from the stream buffer, straight into buf (reusing its /// capacity). As the library's stream adapter, this reads the stream buffer /// directly and sets eofbit at the end. inline void append_stream(std::string& buf, std::istream& is) { std::streambuf* const sb = is.rdbuf(); if (sb == nullptr) { return; } for (;;) { const std::size_t used = buf.size(); const std::size_t room = (std::max)(buf.capacity() - used, std::size_t{4096}); buf.resize(used + room); const std::streamsize got = sb->sgetn(&buf[used], static_cast(room)); buf.resize(used + static_cast(got > 0 ? got : 0)); if (got <= 0) { break; } } is.clear(is.rdstate() | std::ios::eofbit); } } // namespace view } // namespace detail NLOHMANN_JSON_NAMESPACE_END