| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 | //     __ _____ _____ _____//  __|  |   __|     |   | |  JSON for Modern C++// |  |  |__   |  |  | | | |  version 3.12.0// |_____|_____|_____|_|___|  https://github.com/nlohmann/json//// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>// SPDX-License-Identifier: MIT#pragma once#include <cstddef> // size_t#include <iterator> // forward_iterator_tag#include <tuple> // tuple_size, get, tuple_element#include <utility> // move#if JSON_HAS_RANGES    #include <ranges> // enable_borrowed_range#endif#include <nlohmann/detail/abi_macros.hpp>#include <nlohmann/detail/meta/type_traits.hpp>#include <nlohmann/detail/string_utils.hpp>#include <nlohmann/detail/value_t.hpp>NLOHMANN_JSON_NAMESPACE_BEGINnamespace detail{template<typename IteratorType> class iteration_proxy_value{  public:    using difference_type = std::ptrdiff_t;    using value_type = iteration_proxy_value;    using pointer = value_type *;    using reference = value_type &;    using iterator_category = std::forward_iterator_tag;    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;  private:    /// the iterator    IteratorType anchor{};    /// an index for arrays (used to create key names)    std::size_t array_index = 0;    /// last stringified array index    mutable std::size_t array_index_last = 0;    /// a string representation of the array index    mutable string_type array_index_str = "0";    /// an empty string (to return a reference for primitive values)    string_type empty_str{};  public:    explicit iteration_proxy_value() = default;    explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)    noexcept(std::is_nothrow_move_constructible<IteratorType>::value             && std::is_nothrow_default_constructible<string_type>::value)        : anchor(std::move(it))        , array_index(array_index_)    {}    iteration_proxy_value(iteration_proxy_value const&) = default;    iteration_proxy_value& operator=(iteration_proxy_value const&) = default;    // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions    iteration_proxy_value(iteration_proxy_value&&)    noexcept(std::is_nothrow_move_constructible<IteratorType>::value             && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)    iteration_proxy_value& operator=(iteration_proxy_value&&)    noexcept(std::is_nothrow_move_assignable<IteratorType>::value             && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)    ~iteration_proxy_value() = default;    /// dereference operator (needed for range-based for)    const iteration_proxy_value& operator*() const    {        return *this;    }    /// increment operator (needed for range-based for)    iteration_proxy_value& operator++()    {        ++anchor;        ++array_index;        return *this;    }    iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)    {        auto tmp = iteration_proxy_value(anchor, array_index);        ++anchor;        ++array_index;        return tmp;    }    /// equality operator (needed for InputIterator)    bool operator==(const iteration_proxy_value& o) const    {        return anchor == o.anchor;    }    /// inequality operator (needed for range-based for)    bool operator!=(const iteration_proxy_value& o) const    {        return anchor != o.anchor;    }    /// return key of the iterator    const string_type& key() const    {        JSON_ASSERT(anchor.m_object != nullptr);        switch (anchor.m_object->type())        {            // use integer array index as key            case value_t::array:            {                if (array_index != array_index_last)                {                    int_to_string( array_index_str, array_index );                    array_index_last = array_index;                }                return array_index_str;            }            // use key from the object            case value_t::object:                return anchor.key();            // use an empty key for all primitive types            case value_t::null:            case value_t::string:            case value_t::boolean:            case value_t::number_integer:            case value_t::number_unsigned:            case value_t::number_float:            case value_t::binary:            case value_t::discarded:            default:                return empty_str;        }    }    /// return value of the iterator    typename IteratorType::reference value() const    {        return anchor.value();    }};/// proxy class for the items() functiontemplate<typename IteratorType> class iteration_proxy{  private:    /// the container to iterate    typename IteratorType::pointer container = nullptr;  public:    explicit iteration_proxy() = default;    /// construct iteration proxy from a container    explicit iteration_proxy(typename IteratorType::reference cont) noexcept        : container(&cont) {}    iteration_proxy(iteration_proxy const&) = default;    iteration_proxy& operator=(iteration_proxy const&) = default;    iteration_proxy(iteration_proxy&&) noexcept = default;    iteration_proxy& operator=(iteration_proxy&&) noexcept = default;    ~iteration_proxy() = default;    /// return iterator begin (needed for range-based for)    iteration_proxy_value<IteratorType> begin() const noexcept    {        return iteration_proxy_value<IteratorType>(container->begin());    }    /// return iterator end (needed for range-based for)    iteration_proxy_value<IteratorType> end() const noexcept    {        return iteration_proxy_value<IteratorType>(container->end());    }};// Structured Bindings Support// For further reference see https://blog.tartanllama.xyz/structured-bindings/// And see https://github.com/nlohmann/json/pull/1391template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key()){    return i.key();}// Structured Bindings Support// For further reference see https://blog.tartanllama.xyz/structured-bindings/// And see https://github.com/nlohmann/json/pull/1391template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value()){    return i.value();}}  // namespace detailNLOHMANN_JSON_NAMESPACE_END// The Addition to the STD Namespace is required to add// Structured Bindings Support to the iteration_proxy_value class// For further reference see https://blog.tartanllama.xyz/structured-bindings/// And see https://github.com/nlohmann/json/pull/1391namespace std{#if defined(__clang__)    // Fix: https://github.com/nlohmann/json/issues/1401    #pragma clang diagnostic push    #pragma clang diagnostic ignored "-Wmismatched-tags"#endiftemplate<typename IteratorType>class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)    : public std::integral_constant<std::size_t, 2> {};template<std::size_t N, typename IteratorType>class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp){  public:    using type = decltype(                     get<N>(std::declval <                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));};#if defined(__clang__)    #pragma clang diagnostic pop#endif}  // namespace std#if JSON_HAS_RANGES    template <typename IteratorType>    inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;#endif
 |