commit
						5927acee7d
					
				
				 50 changed files with 49107 additions and 0 deletions
			
			
		@ -0,0 +1,21 @@ | 
				
			|||||||
 | 
					MIT License  | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2013-2022 Niels Lohmann | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions: | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all | 
				
			||||||
 | 
					copies or substantial portions of the Software. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
				
			||||||
 | 
					SOFTWARE. | 
				
			||||||
@ -0,0 +1,8 @@ | 
				
			|||||||
 | 
					.PHONY: all | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all: install | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install: | 
				
			||||||
 | 
						install -d $(DEST_DIR)/
 | 
				
			||||||
 | 
						install -d $(DEST_DIR)/include/
 | 
				
			||||||
 | 
						install -m 644 single_include/nlohmann/json.hpp $(DEST_DIR)/include/
 | 
				
			||||||
@ -0,0 +1,11 @@ | 
				
			|||||||
 | 
					#!/usr/bin/env bash | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -z "$1" ] | 
				
			||||||
 | 
					then | 
				
			||||||
 | 
					   printf "Usage: setup.sh install_directory [dependencies].\n" 1>&2 | 
				
			||||||
 | 
					   exit 1 | 
				
			||||||
 | 
					fi | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd $(dirname $0) | 
				
			||||||
 | 
					libname=$(basename $(pwd)) | 
				
			||||||
 | 
					make DEST_DIR="$1" install | 
				
			||||||
@ -0,0 +1,55 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <utility> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/conversions/from_json.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/conversions/to_json.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/identity_tag.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/adl_serializer/
 | 
				
			||||||
 | 
					template<typename ValueType, typename> | 
				
			||||||
 | 
					struct adl_serializer | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    /// @brief convert a JSON value to any value type
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
 | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename TargetType = ValueType> | 
				
			||||||
 | 
					    static auto from_json(BasicJsonType && j, TargetType& val) noexcept( | 
				
			||||||
 | 
					        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) | 
				
			||||||
 | 
					    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief convert a JSON value to any value type
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
 | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename TargetType = ValueType> | 
				
			||||||
 | 
					    static auto from_json(BasicJsonType && j) noexcept( | 
				
			||||||
 | 
					    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))) | 
				
			||||||
 | 
					    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief convert any value type to a JSON value
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
 | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename TargetType = ValueType> | 
				
			||||||
 | 
					    static auto to_json(BasicJsonType& j, TargetType && val) noexcept( | 
				
			||||||
 | 
					        noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val)))) | 
				
			||||||
 | 
					    -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        ::nlohmann::to_json(j, std::forward<TargetType>(val)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,103 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint> // uint8_t, uint64_t | 
				
			||||||
 | 
					#include <tuple> // tie | 
				
			||||||
 | 
					#include <utility> // move | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief an internal type for a backed binary type
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/
 | 
				
			||||||
 | 
					template<typename BinaryType> | 
				
			||||||
 | 
					class byte_container_with_subtype : public BinaryType | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using container_type = BinaryType; | 
				
			||||||
 | 
					    using subtype_type = std::uint64_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
 | 
				
			||||||
 | 
					    byte_container_with_subtype() noexcept(noexcept(container_type())) | 
				
			||||||
 | 
					        : container_type() | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
 | 
				
			||||||
 | 
					    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) | 
				
			||||||
 | 
					        : container_type(b) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
 | 
				
			||||||
 | 
					    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) | 
				
			||||||
 | 
					        : container_type(std::move(b)) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
 | 
				
			||||||
 | 
					    byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) | 
				
			||||||
 | 
					        : container_type(b) | 
				
			||||||
 | 
					        , m_subtype(subtype_) | 
				
			||||||
 | 
					        , m_has_subtype(true) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
 | 
				
			||||||
 | 
					    byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) | 
				
			||||||
 | 
					        : container_type(std::move(b)) | 
				
			||||||
 | 
					        , m_subtype(subtype_) | 
				
			||||||
 | 
					        , m_has_subtype(true) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool operator==(const byte_container_with_subtype& rhs) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) == | 
				
			||||||
 | 
					               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool operator!=(const byte_container_with_subtype& rhs) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return !(rhs == *this); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief sets the binary subtype
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/
 | 
				
			||||||
 | 
					    void set_subtype(subtype_type subtype_) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_subtype = subtype_; | 
				
			||||||
 | 
					        m_has_subtype = true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return the binary subtype
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/
 | 
				
			||||||
 | 
					    constexpr subtype_type subtype() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return whether the value has a subtype
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/
 | 
				
			||||||
 | 
					    constexpr bool has_subtype() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m_has_subtype; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief clears the binary subtype
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/
 | 
				
			||||||
 | 
					    void clear_subtype() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_subtype = 0; | 
				
			||||||
 | 
					        m_has_subtype = false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    subtype_type m_subtype = 0; | 
				
			||||||
 | 
					    bool m_has_subtype = false; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,100 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This file contains all macro definitions affecting or depending on the ABI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK | 
				
			||||||
 | 
					    #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) | 
				
			||||||
 | 
					        #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 | 
				
			||||||
 | 
					            #warning "Already included a different version of the library!" | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_VERSION_MAJOR 3   // NOLINT(modernize-macro-to-enum)
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_VERSION_MINOR 11  // NOLINT(modernize-macro-to-enum)
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_VERSION_PATCH 2   // NOLINT(modernize-macro-to-enum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_DIAGNOSTICS | 
				
			||||||
 | 
					    #define JSON_DIAGNOSTICS 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON | 
				
			||||||
 | 
					    #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_DIAGNOSTICS | 
				
			||||||
 | 
					    #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON | 
				
			||||||
 | 
					    #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION | 
				
			||||||
 | 
					    #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Construct the namespace ABI tags component
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b | 
				
			||||||
 | 
					#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ | 
				
			||||||
 | 
					    NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_ABI_TAGS                                       \ | 
				
			||||||
 | 
					    NLOHMANN_JSON_ABI_TAGS_CONCAT(                                   \
 | 
				
			||||||
 | 
					            NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS,                       \
 | 
				
			||||||
 | 
					            NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Construct the namespace version component
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ | 
				
			||||||
 | 
					    _v ## major ## _ ## minor ## _ ## patch | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ | 
				
			||||||
 | 
					    NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if NLOHMANN_JSON_NAMESPACE_NO_VERSION | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_VERSION | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_VERSION                                 \ | 
				
			||||||
 | 
					    NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
 | 
				
			||||||
 | 
					                                           NLOHMANN_JSON_VERSION_MINOR, \
 | 
				
			||||||
 | 
					                                           NLOHMANN_JSON_VERSION_PATCH) | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Combine namespace components
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ | 
				
			||||||
 | 
					    NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef NLOHMANN_JSON_NAMESPACE | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE               \ | 
				
			||||||
 | 
					    nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
 | 
				
			||||||
 | 
					            NLOHMANN_JSON_ABI_TAGS,           \
 | 
				
			||||||
 | 
					            NLOHMANN_JSON_NAMESPACE_VERSION) | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_BEGIN                \ | 
				
			||||||
 | 
					    namespace nlohmann                               \
 | 
				
			||||||
 | 
					    {                                                \
 | 
				
			||||||
 | 
					    inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
 | 
				
			||||||
 | 
					                NLOHMANN_JSON_ABI_TAGS,              \
 | 
				
			||||||
 | 
					                NLOHMANN_JSON_NAMESPACE_VERSION)     \
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
 | 
					#define NLOHMANN_JSON_NAMESPACE_END                                     \ | 
				
			||||||
 | 
					    }  /* namespace (inline namespace) NOLINT(readability/namespace) */ \
 | 
				
			||||||
 | 
					    }  // namespace nlohmann
 | 
				
			||||||
 | 
					#endif | 
				
			||||||
@ -0,0 +1,497 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm> // transform | 
				
			||||||
 | 
					#include <array> // array | 
				
			||||||
 | 
					#include <forward_list> // forward_list | 
				
			||||||
 | 
					#include <iterator> // inserter, front_inserter, end | 
				
			||||||
 | 
					#include <map> // map | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <tuple> // tuple, make_tuple | 
				
			||||||
 | 
					#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible | 
				
			||||||
 | 
					#include <unordered_map> // unordered_map | 
				
			||||||
 | 
					#include <utility> // pair, declval | 
				
			||||||
 | 
					#include <valarray> // valarray | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/identity_tag.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/std_fs.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_null())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    n = nullptr; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// overloads for basic_json template parameters
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename ArithmeticType, | 
				
			||||||
 | 
					           enable_if_t < std::is_arithmetic<ArithmeticType>::value&& | 
				
			||||||
 | 
					                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, | 
				
			||||||
 | 
					                         int > = 0 > | 
				
			||||||
 | 
					void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    switch (static_cast<value_t>(j)) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        case value_t::number_unsigned: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        case value_t::number_integer: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        case value_t::number_float: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case value_t::null: | 
				
			||||||
 | 
					        case value_t::object: | 
				
			||||||
 | 
					        case value_t::array: | 
				
			||||||
 | 
					        case value_t::string: | 
				
			||||||
 | 
					        case value_t::boolean: | 
				
			||||||
 | 
					        case value_t::binary: | 
				
			||||||
 | 
					        case value_t::discarded: | 
				
			||||||
 | 
					        default: | 
				
			||||||
 | 
					            JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_string())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < | 
				
			||||||
 | 
					    typename BasicJsonType, typename StringType, | 
				
			||||||
 | 
					    enable_if_t < | 
				
			||||||
 | 
					        std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value | 
				
			||||||
 | 
					        && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value | 
				
			||||||
 | 
					        && !std::is_same<typename BasicJsonType::string_t, StringType>::value | 
				
			||||||
 | 
					        && !is_json_ref<StringType>::value, int > = 0 > | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, StringType& s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_string())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    get_arithmetic_value(j, val); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    get_arithmetic_value(j, val); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    get_arithmetic_value(j, val); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !JSON_DISABLE_ENUM_SERIALIZATION | 
				
			||||||
 | 
					template<typename BasicJsonType, typename EnumType, | 
				
			||||||
 | 
					         enable_if_t<std::is_enum<EnumType>::value, int> = 0> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, EnumType& e) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    typename std::underlying_type<EnumType>::type val; | 
				
			||||||
 | 
					    get_arithmetic_value(j, val); | 
				
			||||||
 | 
					    e = static_cast<EnumType>(val); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif  // JSON_DISABLE_ENUM_SERIALIZATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// forward_list doesn't have an insert method
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, typename Allocator, | 
				
			||||||
 | 
					         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    l.clear(); | 
				
			||||||
 | 
					    std::transform(j.rbegin(), j.rend(), | 
				
			||||||
 | 
					                   std::front_inserter(l), [](const BasicJsonType & i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return i.template get<T>(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// valarray doesn't have an insert method
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, | 
				
			||||||
 | 
					         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, std::valarray<T>& l) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    l.resize(j.size()); | 
				
			||||||
 | 
					    std::transform(j.begin(), j.end(), std::begin(l), | 
				
			||||||
 | 
					                   [](const BasicJsonType & elem) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return elem.template get<T>(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, std::size_t N> | 
				
			||||||
 | 
					auto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
 | 
				
			||||||
 | 
					-> decltype(j.template get<T>(), void()) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    for (std::size_t i = 0; i < N; ++i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        arr[i] = j.at(i).template get<T>(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, std::size_t N> | 
				
			||||||
 | 
					auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, | 
				
			||||||
 | 
					                          priority_tag<2> /*unused*/) | 
				
			||||||
 | 
					-> decltype(j.template get<T>(), void()) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    for (std::size_t i = 0; i < N; ++i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        arr[i] = j.at(i).template get<T>(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType, | 
				
			||||||
 | 
					         enable_if_t< | 
				
			||||||
 | 
					             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, | 
				
			||||||
 | 
					             int> = 0> | 
				
			||||||
 | 
					auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) | 
				
			||||||
 | 
					-> decltype( | 
				
			||||||
 | 
					    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()), | 
				
			||||||
 | 
					    j.template get<typename ConstructibleArrayType::value_type>(), | 
				
			||||||
 | 
					    void()) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using std::end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConstructibleArrayType ret; | 
				
			||||||
 | 
					    ret.reserve(j.size()); | 
				
			||||||
 | 
					    std::transform(j.begin(), j.end(), | 
				
			||||||
 | 
					                   std::inserter(ret, end(ret)), [](const BasicJsonType & i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // get<BasicJsonType>() returns *this, this won't call a from_json
 | 
				
			||||||
 | 
					        // method when value_type is BasicJsonType
 | 
				
			||||||
 | 
					        return i.template get<typename ConstructibleArrayType::value_type>(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					    arr = std::move(ret); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType, | 
				
			||||||
 | 
					         enable_if_t< | 
				
			||||||
 | 
					             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, | 
				
			||||||
 | 
					             int> = 0> | 
				
			||||||
 | 
					inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, | 
				
			||||||
 | 
					                                 priority_tag<0> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using std::end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConstructibleArrayType ret; | 
				
			||||||
 | 
					    std::transform( | 
				
			||||||
 | 
					        j.begin(), j.end(), std::inserter(ret, end(ret)), | 
				
			||||||
 | 
					        [](const BasicJsonType & i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // get<BasicJsonType>() returns *this, this won't call a from_json
 | 
				
			||||||
 | 
					        // method when value_type is BasicJsonType
 | 
				
			||||||
 | 
					        return i.template get<typename ConstructibleArrayType::value_type>(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					    arr = std::move(ret); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename ConstructibleArrayType, | 
				
			||||||
 | 
					           enable_if_t < | 
				
			||||||
 | 
					               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&& | 
				
			||||||
 | 
					               !is_basic_json<ConstructibleArrayType>::value, | 
				
			||||||
 | 
					               int > = 0 > | 
				
			||||||
 | 
					auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) | 
				
			||||||
 | 
					-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), | 
				
			||||||
 | 
					j.template get<typename ConstructibleArrayType::value_type>(), | 
				
			||||||
 | 
					void()) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from_json_array_impl(j, arr, priority_tag<3> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename T, std::size_t... Idx > | 
				
			||||||
 | 
					std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j, | 
				
			||||||
 | 
					        identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename T, std::size_t N > | 
				
			||||||
 | 
					auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag) | 
				
			||||||
 | 
					-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {})) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleObjectType, | 
				
			||||||
 | 
					         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_object())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConstructibleObjectType ret; | 
				
			||||||
 | 
					    const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); | 
				
			||||||
 | 
					    using value_type = typename ConstructibleObjectType::value_type; | 
				
			||||||
 | 
					    std::transform( | 
				
			||||||
 | 
					        inner_object->begin(), inner_object->end(), | 
				
			||||||
 | 
					        std::inserter(ret, ret.begin()), | 
				
			||||||
 | 
					        [](typename BasicJsonType::object_t::value_type const & p) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>()); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					    obj = std::move(ret); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// overload for arithmetic types, not chosen for basic_json template arguments
 | 
				
			||||||
 | 
					// (BooleanType, etc..); note: Is it really necessary to provide explicit
 | 
				
			||||||
 | 
					// overloads for boolean_t etc. in case of a custom BooleanType which is not
 | 
				
			||||||
 | 
					// an arithmetic type?
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename ArithmeticType, | 
				
			||||||
 | 
					           enable_if_t < | 
				
			||||||
 | 
					               std::is_arithmetic<ArithmeticType>::value&& | 
				
			||||||
 | 
					               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&& | 
				
			||||||
 | 
					               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&& | 
				
			||||||
 | 
					               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&& | 
				
			||||||
 | 
					               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, | 
				
			||||||
 | 
					               int > = 0 > | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, ArithmeticType& val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    switch (static_cast<value_t>(j)) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        case value_t::number_unsigned: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        case value_t::number_integer: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        case value_t::number_float: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        case value_t::boolean: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>()); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case value_t::null: | 
				
			||||||
 | 
					        case value_t::object: | 
				
			||||||
 | 
					        case value_t::array: | 
				
			||||||
 | 
					        case value_t::string: | 
				
			||||||
 | 
					        case value_t::binary: | 
				
			||||||
 | 
					        case value_t::discarded: | 
				
			||||||
 | 
					        default: | 
				
			||||||
 | 
					            JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename... Args, std::size_t... Idx> | 
				
			||||||
 | 
					std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, class A1, class A2 > | 
				
			||||||
 | 
					std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return {std::forward<BasicJsonType>(j).at(0).template get<A1>(), | 
				
			||||||
 | 
					            std::forward<BasicJsonType>(j).at(1).template get<A2>()}; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename A1, typename A2> | 
				
			||||||
 | 
					inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename... Args> | 
				
			||||||
 | 
					std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename... Args> | 
				
			||||||
 | 
					inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename TupleRelated> | 
				
			||||||
 | 
					auto from_json(BasicJsonType&& j, TupleRelated&& t) | 
				
			||||||
 | 
					-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {})) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, | 
				
			||||||
 | 
					           typename = enable_if_t < !std::is_constructible < | 
				
			||||||
 | 
					                                        typename BasicJsonType::string_t, Key >::value >> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    m.clear(); | 
				
			||||||
 | 
					    for (const auto& p : j) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(!p.is_array())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, | 
				
			||||||
 | 
					           typename = enable_if_t < !std::is_constructible < | 
				
			||||||
 | 
					                                        typename BasicJsonType::string_t, Key >::value >> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_array())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    m.clear(); | 
				
			||||||
 | 
					    for (const auto& p : j) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(!p.is_array())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void from_json(const BasicJsonType& j, std_fs::path& p) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    if (JSON_HEDLEY_UNLIKELY(!j.is_string())) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    p = *j.template get_ptr<const typename BasicJsonType::string_t*>(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct from_json_fn | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					    auto operator()(const BasicJsonType& j, T&& val) const | 
				
			||||||
 | 
					    noexcept(noexcept(from_json(j, std::forward<T>(val)))) | 
				
			||||||
 | 
					    -> decltype(from_json(j, std::forward<T>(val))) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return from_json(j, std::forward<T>(val)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					/// namespace to hold default `from_json` function
 | 
				
			||||||
 | 
					/// to see why this is required:
 | 
				
			||||||
 | 
					/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
 | 
				
			||||||
 | 
					namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
 | 
				
			||||||
 | 
					    detail::static_const<detail::from_json_fn>::value; | 
				
			||||||
 | 
					#ifndef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,446 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm> // copy | 
				
			||||||
 | 
					#include <iterator> // begin, end | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <tuple> // tuple, get | 
				
			||||||
 | 
					#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type | 
				
			||||||
 | 
					#include <utility> // move, forward, declval, pair | 
				
			||||||
 | 
					#include <valarray> // valarray | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/iteration_proxy.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/std_fs.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////
 | 
				
			||||||
 | 
					// constructors //
 | 
				
			||||||
 | 
					//////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Note all external_constructor<>::construct functions need to call | 
				
			||||||
 | 
					 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an | 
				
			||||||
 | 
					 * allocated value (e.g., a string). See bug issue | 
				
			||||||
 | 
					 * https://github.com/nlohmann/json/issues/2865 for more information.
 | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<value_t> struct external_constructor; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::boolean> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::boolean; | 
				
			||||||
 | 
					        j.m_value = b; | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::string> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::string; | 
				
			||||||
 | 
					        j.m_value = s; | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::string; | 
				
			||||||
 | 
					        j.m_value = std::move(s); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template < typename BasicJsonType, typename CompatibleStringType, | 
				
			||||||
 | 
					               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value, | 
				
			||||||
 | 
					                             int > = 0 > | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const CompatibleStringType& str) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::string; | 
				
			||||||
 | 
					        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::binary> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::binary; | 
				
			||||||
 | 
					        j.m_value = typename BasicJsonType::binary_t(b); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::binary; | 
				
			||||||
 | 
					        j.m_value = typename BasicJsonType::binary_t(std::move(b)); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::number_float> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::number_float; | 
				
			||||||
 | 
					        j.m_value = val; | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::number_unsigned> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::number_unsigned; | 
				
			||||||
 | 
					        j.m_value = val; | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::number_integer> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::number_integer; | 
				
			||||||
 | 
					        j.m_value = val; | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::array> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::array; | 
				
			||||||
 | 
					        j.m_value = arr; | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::array; | 
				
			||||||
 | 
					        j.m_value = std::move(arr); | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template < typename BasicJsonType, typename CompatibleArrayType, | 
				
			||||||
 | 
					               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value, | 
				
			||||||
 | 
					                             int > = 0 > | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const CompatibleArrayType& arr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using std::begin; | 
				
			||||||
 | 
					        using std::end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::array; | 
				
			||||||
 | 
					        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr)); | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const std::vector<bool>& arr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::array; | 
				
			||||||
 | 
					        j.m_value = value_t::array; | 
				
			||||||
 | 
					        j.m_value.array->reserve(arr.size()); | 
				
			||||||
 | 
					        for (const bool x : arr) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            j.m_value.array->push_back(x); | 
				
			||||||
 | 
					            j.set_parent(j.m_value.array->back()); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename T, | 
				
			||||||
 | 
					             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const std::valarray<T>& arr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::array; | 
				
			||||||
 | 
					        j.m_value = value_t::array; | 
				
			||||||
 | 
					        j.m_value.array->resize(arr.size()); | 
				
			||||||
 | 
					        if (arr.size() > 0) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<> | 
				
			||||||
 | 
					struct external_constructor<value_t::object> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::object; | 
				
			||||||
 | 
					        j.m_value = obj; | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::object; | 
				
			||||||
 | 
					        j.m_value = std::move(obj); | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template < typename BasicJsonType, typename CompatibleObjectType, | 
				
			||||||
 | 
					               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 > | 
				
			||||||
 | 
					    static void construct(BasicJsonType& j, const CompatibleObjectType& obj) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using std::begin; | 
				
			||||||
 | 
					        using std::end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        j.m_value.destroy(j.m_type); | 
				
			||||||
 | 
					        j.m_type = value_t::object; | 
				
			||||||
 | 
					        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj)); | 
				
			||||||
 | 
					        j.set_parents(); | 
				
			||||||
 | 
					        j.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/////////////
 | 
				
			||||||
 | 
					// to_json //
 | 
				
			||||||
 | 
					/////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, | 
				
			||||||
 | 
					         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, T b) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::boolean>::construct(j, b); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename BoolRef, | 
				
			||||||
 | 
					           enable_if_t < | 
				
			||||||
 | 
					               ((std::is_same<std::vector<bool>::reference, BoolRef>::value | 
				
			||||||
 | 
					                 && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value) | 
				
			||||||
 | 
					                || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value | 
				
			||||||
 | 
					                    && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>, | 
				
			||||||
 | 
					                                      typename BasicJsonType::boolean_t >::value)) | 
				
			||||||
 | 
					               && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 > | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleString, | 
				
			||||||
 | 
					         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const CompatibleString& s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::string>::construct(j, s); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::string>::construct(j, std::move(s)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename FloatType, | 
				
			||||||
 | 
					         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, FloatType val) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleNumberUnsignedType, | 
				
			||||||
 | 
					         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleNumberIntegerType, | 
				
			||||||
 | 
					         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !JSON_DISABLE_ENUM_SERIALIZATION | 
				
			||||||
 | 
					template<typename BasicJsonType, typename EnumType, | 
				
			||||||
 | 
					         enable_if_t<std::is_enum<EnumType>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, EnumType e) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using underlying_type = typename std::underlying_type<EnumType>::type; | 
				
			||||||
 | 
					    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif  // JSON_DISABLE_ENUM_SERIALIZATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const std::vector<bool>& e) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::array>::construct(j, e); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename CompatibleArrayType, | 
				
			||||||
 | 
					           enable_if_t < is_compatible_array_type<BasicJsonType, | 
				
			||||||
 | 
					                         CompatibleArrayType>::value&& | 
				
			||||||
 | 
					                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&& | 
				
			||||||
 | 
					                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&& | 
				
			||||||
 | 
					                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&& | 
				
			||||||
 | 
					                         !is_basic_json<CompatibleArrayType>::value, | 
				
			||||||
 | 
					                         int > = 0 > | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::array>::construct(j, arr); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::binary>::construct(j, bin); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, | 
				
			||||||
 | 
					         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const std::valarray<T>& arr) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::array>::construct(j, std::move(arr)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::array>::construct(j, std::move(arr)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename CompatibleObjectType, | 
				
			||||||
 | 
					           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 > | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::object>::construct(j, obj); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::object>::construct(j, std::move(obj)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < | 
				
			||||||
 | 
					    typename BasicJsonType, typename T, std::size_t N, | 
				
			||||||
 | 
					    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t, | 
				
			||||||
 | 
					                  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
 | 
				
			||||||
 | 
					                  int > = 0 > | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    external_constructor<value_t::array>::construct(j, arr); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 > | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    j = { p.first, p.second }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// for https://github.com/nlohmann/json/pull/1134
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, | 
				
			||||||
 | 
					         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const T& b) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    j = { {b.key(), b.value()} }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename Tuple, std::size_t... Idx> | 
				
			||||||
 | 
					inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    j = { std::get<Idx>(t)... }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const T& t) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					inline void to_json(BasicJsonType& j, const std_fs::path& p) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    j = p.string(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct to_json_fn | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val)))) | 
				
			||||||
 | 
					    -> decltype(to_json(j, std::forward<T>(val)), void()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return to_json(j, std::forward<T>(val)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					/// namespace to hold default `to_json` function
 | 
				
			||||||
 | 
					/// to see why this is required:
 | 
				
			||||||
 | 
					/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
 | 
				
			||||||
 | 
					namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
 | 
				
			||||||
 | 
					    detail::static_const<detail::to_json_fn>::value; | 
				
			||||||
 | 
					#ifndef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,255 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> // nullptr_t | 
				
			||||||
 | 
					#include <exception> // exception | 
				
			||||||
 | 
					#include <stdexcept> // runtime_error | 
				
			||||||
 | 
					#include <string> // to_string | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_escape.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/input/position_t.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////
 | 
				
			||||||
 | 
					// exceptions //
 | 
				
			||||||
 | 
					////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief general exception of the @ref basic_json class
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/exception/
 | 
				
			||||||
 | 
					class exception : public std::exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /// returns the explanatory string
 | 
				
			||||||
 | 
					    const char* what() const noexcept override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m.what(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the id of the exception
 | 
				
			||||||
 | 
					    const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected: | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(3) | 
				
			||||||
 | 
					    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static std::string name(const std::string& ename, int id_) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return concat("[json.exception.", ename, '.', std::to_string(id_), "] "); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static std::string diagnostics(std::nullptr_t /*leaf_element*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return ""; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static std::string diagnostics(const BasicJsonType* leaf_element) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					#if JSON_DIAGNOSTICS | 
				
			||||||
 | 
					        std::vector<std::string> tokens; | 
				
			||||||
 | 
					        for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (current->m_parent->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (¤t->m_parent->m_value.array->operator[](i) == current) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            tokens.emplace_back(std::to_string(i)); | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    for (const auto& element : *current->m_parent->m_value.object) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (&element.second == current) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            tokens.emplace_back(element.first.c_str()); | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case value_t::null: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::string: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::boolean: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::number_integer: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::number_unsigned: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::number_float: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::binary: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                case value_t::discarded: // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                default:   // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                    break; // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (tokens.empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return ""; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, | 
				
			||||||
 | 
					                                   [](const std::string & a, const std::string & b) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return concat(a, '/', detail::escape(b)); | 
				
			||||||
 | 
					        }); | 
				
			||||||
 | 
					        return concat('(', str, ") "); | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					        static_cast<void>(leaf_element); | 
				
			||||||
 | 
					        return ""; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// an exception object as storage for error messages
 | 
				
			||||||
 | 
					    std::runtime_error m; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief exception indicating a parse error
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/parse_error/
 | 
				
			||||||
 | 
					class parse_error : public exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief create a parse error exception | 
				
			||||||
 | 
					    @param[in] id_       the id of the exception | 
				
			||||||
 | 
					    @param[in] pos       the position where the error occurred (or with | 
				
			||||||
 | 
					                         chars_read_total=0 if the position cannot be | 
				
			||||||
 | 
					                         determined) | 
				
			||||||
 | 
					    @param[in] what_arg  the explanatory string | 
				
			||||||
 | 
					    @return parse_error object | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("parse_error", id_), "parse error", | 
				
			||||||
 | 
					                               position_string(pos), ": ", exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, pos.chars_read_total, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("parse_error", id_), "parse error", | 
				
			||||||
 | 
					                               (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""), | 
				
			||||||
 | 
					                               ": ", exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, byte_, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief byte index of the parse error | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The byte index of the last read character in the input file. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @note For an input with n bytes, 1 is the index of the first character and | 
				
			||||||
 | 
					          n+1 is the index of the terminating null byte or the end of file. | 
				
			||||||
 | 
					          This also holds true when reading a byte vector (CBOR or MessagePack). | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    const std::size_t byte; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    parse_error(int id_, std::size_t byte_, const char* what_arg) | 
				
			||||||
 | 
					        : exception(id_, what_arg), byte(byte_) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static std::string position_string(const position_t& pos) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return concat(" at line ", std::to_string(pos.lines_read + 1), | 
				
			||||||
 | 
					                      ", column ", std::to_string(pos.chars_read_current_line)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief exception indicating errors with iterators
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
 | 
				
			||||||
 | 
					class invalid_iterator : public exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(3) | 
				
			||||||
 | 
					    invalid_iterator(int id_, const char* what_arg) | 
				
			||||||
 | 
					        : exception(id_, what_arg) {} | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief exception indicating executing a member function with a wrong type
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/type_error/
 | 
				
			||||||
 | 
					class type_error : public exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static type_error create(int id_, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(3) | 
				
			||||||
 | 
					    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief exception indicating access out of the defined range
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
 | 
				
			||||||
 | 
					class out_of_range : public exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(3) | 
				
			||||||
 | 
					    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief exception indicating other library errors
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/other_error/
 | 
				
			||||||
 | 
					class other_error : public exception | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | 
				
			||||||
 | 
					    static other_error create(int id_, const std::string& what_arg, BasicJsonContext context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg); | 
				
			||||||
 | 
					        return {id_, w.c_str()}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(3) | 
				
			||||||
 | 
					    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,129 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint> // uint8_t | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <functional> // hash | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// boost::hash_combine
 | 
				
			||||||
 | 
					inline std::size_t combine(std::size_t seed, std::size_t h) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); | 
				
			||||||
 | 
					    return seed; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief hash a JSON value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The hash function tries to rely on std::hash where possible. Furthermore, the | 
				
			||||||
 | 
					type of the JSON value is taken into account to have different hash values for | 
				
			||||||
 | 
					null, 0, 0U, and false, etc. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@tparam BasicJsonType basic_json specialization | 
				
			||||||
 | 
					@param j JSON value to hash | 
				
			||||||
 | 
					@return hash value of j | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					std::size_t hash(const BasicJsonType& j) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto type = static_cast<std::size_t>(j.type()); | 
				
			||||||
 | 
					    switch (j.type()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        case BasicJsonType::value_t::null: | 
				
			||||||
 | 
					        case BasicJsonType::value_t::discarded: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return combine(type, 0); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::object: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            auto seed = combine(type, j.size()); | 
				
			||||||
 | 
					            for (const auto& element : j.items()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                const auto h = std::hash<string_t> {}(element.key()); | 
				
			||||||
 | 
					                seed = combine(seed, h); | 
				
			||||||
 | 
					                seed = combine(seed, hash(element.value())); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            return seed; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::array: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            auto seed = combine(type, j.size()); | 
				
			||||||
 | 
					            for (const auto& element : j) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                seed = combine(seed, hash(element)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            return seed; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::string: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); | 
				
			||||||
 | 
					            return combine(type, h); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::boolean: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto h = std::hash<bool> {}(j.template get<bool>()); | 
				
			||||||
 | 
					            return combine(type, h); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::number_integer: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); | 
				
			||||||
 | 
					            return combine(type, h); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::number_unsigned: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); | 
				
			||||||
 | 
					            return combine(type, h); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::number_float: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); | 
				
			||||||
 | 
					            return combine(type, h); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BasicJsonType::value_t::binary: | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            auto seed = combine(type, j.get_binary().size()); | 
				
			||||||
 | 
					            const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); | 
				
			||||||
 | 
					            seed = combine(seed, h); | 
				
			||||||
 | 
					            seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype())); | 
				
			||||||
 | 
					            for (const auto byte : j.get_binary()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                seed = combine(seed, std::hash<std::uint8_t> {}(byte)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            return seed; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:                   // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					            return 0;              // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,494 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <array> // array | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <cstring> // strlen | 
				
			||||||
 | 
					#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next | 
				
			||||||
 | 
					#include <memory> // shared_ptr, make_shared, addressof | 
				
			||||||
 | 
					#include <numeric> // accumulate | 
				
			||||||
 | 
					#include <string> // string, char_traits | 
				
			||||||
 | 
					#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer | 
				
			||||||
 | 
					#include <utility> // pair, declval | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					    #include <cstdio>   // FILE * | 
				
			||||||
 | 
					    #include <istream>  // istream | 
				
			||||||
 | 
					#endif                  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/iterator_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// the supported input formats
 | 
				
			||||||
 | 
					enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////
 | 
				
			||||||
 | 
					// input adapters //
 | 
				
			||||||
 | 
					////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					Input adapter for stdio file access. This adapter read only 1 byte and do not use any | 
				
			||||||
 | 
					 buffer. This adapter is a very low level adapter. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					class file_input_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using char_type = char; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    explicit file_input_adapter(std::FILE* f) noexcept | 
				
			||||||
 | 
					        : m_file(f) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_file != nullptr); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // make class move-only
 | 
				
			||||||
 | 
					    file_input_adapter(const file_input_adapter&) = delete; | 
				
			||||||
 | 
					    file_input_adapter(file_input_adapter&&) noexcept = default; | 
				
			||||||
 | 
					    file_input_adapter& operator=(const file_input_adapter&) = delete; | 
				
			||||||
 | 
					    file_input_adapter& operator=(file_input_adapter&&) = delete; | 
				
			||||||
 | 
					    ~file_input_adapter() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::char_traits<char>::int_type get_character() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return std::fgetc(m_file); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// the file pointer to read from
 | 
				
			||||||
 | 
					    std::FILE* m_file; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at | 
				
			||||||
 | 
					beginning of input. Does not support changing the underlying std::streambuf | 
				
			||||||
 | 
					in mid-input. Maintains underlying std::istream and std::streambuf to support | 
				
			||||||
 | 
					subsequent use of standard std::istream operations to process any input | 
				
			||||||
 | 
					characters following those used in parsing the JSON input.  Clears the | 
				
			||||||
 | 
					std::istream flags; any input errors (e.g., EOF) will be detected by the first | 
				
			||||||
 | 
					subsequent call for input from the std::istream. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					class input_stream_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using char_type = char; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~input_stream_adapter() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // clear stream flags; we use underlying streambuf I/O, do not
 | 
				
			||||||
 | 
					        // maintain ifstream flags, except eof
 | 
				
			||||||
 | 
					        if (is != nullptr) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            is->clear(is->rdstate() & std::ios::eofbit); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    explicit input_stream_adapter(std::istream& i) | 
				
			||||||
 | 
					        : is(&i), sb(i.rdbuf()) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // delete because of pointer members
 | 
				
			||||||
 | 
					    input_stream_adapter(const input_stream_adapter&) = delete; | 
				
			||||||
 | 
					    input_stream_adapter& operator=(input_stream_adapter&) = delete; | 
				
			||||||
 | 
					    input_stream_adapter& operator=(input_stream_adapter&&) = delete; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input_stream_adapter(input_stream_adapter&& rhs) noexcept | 
				
			||||||
 | 
					        : is(rhs.is), sb(rhs.sb) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        rhs.is = nullptr; | 
				
			||||||
 | 
					        rhs.sb = nullptr; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
 | 
				
			||||||
 | 
					    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
 | 
				
			||||||
 | 
					    // end up as the same value, e.g. 0xFFFFFFFF.
 | 
				
			||||||
 | 
					    std::char_traits<char>::int_type get_character() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto res = sb->sbumpc(); | 
				
			||||||
 | 
					        // set eof manually, as we don't use the istream interface.
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            is->clear(is->rdstate() | std::ios::eofbit); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return res; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// the associated input stream
 | 
				
			||||||
 | 
					    std::istream* is = nullptr; | 
				
			||||||
 | 
					    std::streambuf* sb = nullptr; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// General-purpose iterator-based adapter. It might not be as fast as
 | 
				
			||||||
 | 
					// theoretically possible for some containers, but it is extremely versatile.
 | 
				
			||||||
 | 
					template<typename IteratorType> | 
				
			||||||
 | 
					class iterator_input_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using char_type = typename std::iterator_traits<IteratorType>::value_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iterator_input_adapter(IteratorType first, IteratorType last) | 
				
			||||||
 | 
					        : current(std::move(first)), end(std::move(last)) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typename std::char_traits<char_type>::int_type get_character() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_LIKELY(current != end)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            auto result = std::char_traits<char_type>::to_int_type(*current); | 
				
			||||||
 | 
					            std::advance(current, 1); | 
				
			||||||
 | 
					            return result; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return std::char_traits<char_type>::eof(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    IteratorType current; | 
				
			||||||
 | 
					    IteratorType end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename BaseInputAdapter, size_t T> | 
				
			||||||
 | 
					    friend struct wide_string_input_helper; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool empty() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return current == end; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BaseInputAdapter, size_t T> | 
				
			||||||
 | 
					struct wide_string_input_helper; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BaseInputAdapter> | 
				
			||||||
 | 
					struct wide_string_input_helper<BaseInputAdapter, 4> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // UTF-32
 | 
				
			||||||
 | 
					    static void fill_buffer(BaseInputAdapter& input, | 
				
			||||||
 | 
					                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, | 
				
			||||||
 | 
					                            size_t& utf8_bytes_index, | 
				
			||||||
 | 
					                            size_t& utf8_bytes_filled) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        utf8_bytes_index = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(input.empty())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            utf8_bytes[0] = std::char_traits<char>::eof(); | 
				
			||||||
 | 
					            utf8_bytes_filled = 1; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // get the current character
 | 
				
			||||||
 | 
					            const auto wc = input.get_character(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // UTF-32 to UTF-8 encoding
 | 
				
			||||||
 | 
					            if (wc < 0x80) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); | 
				
			||||||
 | 
					                utf8_bytes_filled = 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else if (wc <= 0x7FF) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu)); | 
				
			||||||
 | 
					                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes_filled = 2; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else if (wc <= 0xFFFF) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu)); | 
				
			||||||
 | 
					                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes_filled = 3; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else if (wc <= 0x10FFFF) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u)); | 
				
			||||||
 | 
					                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes_filled = 4; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // unknown character
 | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); | 
				
			||||||
 | 
					                utf8_bytes_filled = 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BaseInputAdapter> | 
				
			||||||
 | 
					struct wide_string_input_helper<BaseInputAdapter, 2> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // UTF-16
 | 
				
			||||||
 | 
					    static void fill_buffer(BaseInputAdapter& input, | 
				
			||||||
 | 
					                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, | 
				
			||||||
 | 
					                            size_t& utf8_bytes_index, | 
				
			||||||
 | 
					                            size_t& utf8_bytes_filled) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        utf8_bytes_index = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(input.empty())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            utf8_bytes[0] = std::char_traits<char>::eof(); | 
				
			||||||
 | 
					            utf8_bytes_filled = 1; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // get the current character
 | 
				
			||||||
 | 
					            const auto wc = input.get_character(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // UTF-16 to UTF-8 encoding
 | 
				
			||||||
 | 
					            if (wc < 0x80) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); | 
				
			||||||
 | 
					                utf8_bytes_filled = 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else if (wc <= 0x7FF) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u))); | 
				
			||||||
 | 
					                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes_filled = 2; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else if (0xD800 > wc || wc >= 0xE000) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u))); | 
				
			||||||
 | 
					                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); | 
				
			||||||
 | 
					                utf8_bytes_filled = 3; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(!input.empty())) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    const auto wc2 = static_cast<unsigned int>(input.get_character()); | 
				
			||||||
 | 
					                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); | 
				
			||||||
 | 
					                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u)); | 
				
			||||||
 | 
					                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); | 
				
			||||||
 | 
					                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); | 
				
			||||||
 | 
					                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu)); | 
				
			||||||
 | 
					                    utf8_bytes_filled = 4; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); | 
				
			||||||
 | 
					                    utf8_bytes_filled = 1; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Wraps another input apdater to convert wide character types into individual bytes.
 | 
				
			||||||
 | 
					template<typename BaseInputAdapter, typename WideCharType> | 
				
			||||||
 | 
					class wide_string_input_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using char_type = char; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wide_string_input_adapter(BaseInputAdapter base) | 
				
			||||||
 | 
					        : base_adapter(base) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typename std::char_traits<char>::int_type get_character() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // check if buffer needs to be filled
 | 
				
			||||||
 | 
					        if (utf8_bytes_index == utf8_bytes_filled) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            fill_buffer<sizeof(WideCharType)>(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            JSON_ASSERT(utf8_bytes_filled > 0); | 
				
			||||||
 | 
					            JSON_ASSERT(utf8_bytes_index == 0); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // use buffer
 | 
				
			||||||
 | 
					        JSON_ASSERT(utf8_bytes_filled > 0); | 
				
			||||||
 | 
					        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); | 
				
			||||||
 | 
					        return utf8_bytes[utf8_bytes_index++]; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    BaseInputAdapter base_adapter; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<size_t T> | 
				
			||||||
 | 
					    void fill_buffer() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// a buffer for UTF-8 bytes
 | 
				
			||||||
 | 
					    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// index to the utf8_codes array for the next valid byte
 | 
				
			||||||
 | 
					    std::size_t utf8_bytes_index = 0; | 
				
			||||||
 | 
					    /// number of valid bytes in the utf8_codes array
 | 
				
			||||||
 | 
					    std::size_t utf8_bytes_filled = 0; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename IteratorType, typename Enable = void> | 
				
			||||||
 | 
					struct iterator_input_adapter_factory | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using iterator_type = IteratorType; | 
				
			||||||
 | 
					    using char_type = typename std::iterator_traits<iterator_type>::value_type; | 
				
			||||||
 | 
					    using adapter_type = iterator_input_adapter<iterator_type>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static adapter_type create(IteratorType first, IteratorType last) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return adapter_type(std::move(first), std::move(last)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_iterator_of_multibyte | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using value_type = typename std::iterator_traits<T>::value_type; | 
				
			||||||
 | 
					    enum
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        value = sizeof(value_type) > 1 | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename IteratorType> | 
				
			||||||
 | 
					struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using iterator_type = IteratorType; | 
				
			||||||
 | 
					    using char_type = typename std::iterator_traits<iterator_type>::value_type; | 
				
			||||||
 | 
					    using base_adapter_type = iterator_input_adapter<iterator_type>; | 
				
			||||||
 | 
					    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static adapter_type create(IteratorType first, IteratorType last) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return adapter_type(base_adapter_type(std::move(first), std::move(last))); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// General purpose iterator-based input
 | 
				
			||||||
 | 
					template<typename IteratorType> | 
				
			||||||
 | 
					typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using factory_type = iterator_input_adapter_factory<IteratorType>; | 
				
			||||||
 | 
					    return factory_type::create(first, last); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convenience shorthand from container to iterator
 | 
				
			||||||
 | 
					// Enables ADL on begin(container) and end(container)
 | 
				
			||||||
 | 
					// Encloses the using declarations in namespace for not to leak them to outside scope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace container_input_adapter_factory_impl | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using std::begin; | 
				
			||||||
 | 
					using std::end; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename ContainerType, typename Enable = void> | 
				
			||||||
 | 
					struct container_input_adapter_factory {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename ContainerType> | 
				
			||||||
 | 
					struct container_input_adapter_factory< ContainerType, | 
				
			||||||
 | 
					       void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>> | 
				
			||||||
 | 
					       { | 
				
			||||||
 | 
					           using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           static adapter_type create(const ContainerType& container) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return input_adapter(begin(container), end(container)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					       }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace container_input_adapter_factory_impl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename ContainerType> | 
				
			||||||
 | 
					typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					// Special cases with fast paths
 | 
				
			||||||
 | 
					inline file_input_adapter input_adapter(std::FILE* file) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return file_input_adapter(file); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline input_stream_adapter input_adapter(std::istream& stream) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return input_stream_adapter(stream); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline input_stream_adapter input_adapter(std::istream&& stream) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return input_stream_adapter(stream); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Null-delimited strings, and the like.
 | 
				
			||||||
 | 
					template < typename CharT, | 
				
			||||||
 | 
					           typename std::enable_if < | 
				
			||||||
 | 
					               std::is_pointer<CharT>::value&& | 
				
			||||||
 | 
					               !std::is_array<CharT>::value&& | 
				
			||||||
 | 
					               std::is_integral<typename std::remove_pointer<CharT>::type>::value&& | 
				
			||||||
 | 
					               sizeof(typename std::remove_pointer<CharT>::type) == 1, | 
				
			||||||
 | 
					               int >::type = 0 > | 
				
			||||||
 | 
					contiguous_bytes_input_adapter input_adapter(CharT b) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    auto length = std::strlen(reinterpret_cast<const char*>(b)); | 
				
			||||||
 | 
					    const auto* ptr = reinterpret_cast<const char*>(b); | 
				
			||||||
 | 
					    return input_adapter(ptr, ptr + length); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, std::size_t N> | 
				
			||||||
 | 
					auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return input_adapter(array, array + N); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This class only handles inputs of input_buffer_adapter type.
 | 
				
			||||||
 | 
					// It's required so that expressions like {ptr, len} can be implicitly cast
 | 
				
			||||||
 | 
					// to the correct adapter.
 | 
				
			||||||
 | 
					class span_input_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template < typename CharT, | 
				
			||||||
 | 
					               typename std::enable_if < | 
				
			||||||
 | 
					                   std::is_pointer<CharT>::value&& | 
				
			||||||
 | 
					                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&& | 
				
			||||||
 | 
					                   sizeof(typename std::remove_pointer<CharT>::type) == 1, | 
				
			||||||
 | 
					                   int >::type = 0 > | 
				
			||||||
 | 
					    span_input_adapter(CharT b, std::size_t l) | 
				
			||||||
 | 
					        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class IteratorType, | 
				
			||||||
 | 
					             typename std::enable_if< | 
				
			||||||
 | 
					                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, | 
				
			||||||
 | 
					                 int>::type = 0> | 
				
			||||||
 | 
					    span_input_adapter(IteratorType first, IteratorType last) | 
				
			||||||
 | 
					        : ia(input_adapter(first, last)) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contiguous_bytes_input_adapter&& get() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    contiguous_bytes_input_adapter ia; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,728 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <utility> // move | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief SAX interface | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This class describes the SAX interface used by @ref nlohmann::json::sax_parse. | 
				
			||||||
 | 
					Each function is called in different situations while the input is parsed. The | 
				
			||||||
 | 
					boolean return value informs the parser whether to continue processing the | 
				
			||||||
 | 
					input. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					struct json_sax | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a null value was read | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool null() = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a boolean value was read | 
				
			||||||
 | 
					    @param[in] val  boolean value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool boolean(bool val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief an integer number was read | 
				
			||||||
 | 
					    @param[in] val  integer value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool number_integer(number_integer_t val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief an unsigned integer number was read | 
				
			||||||
 | 
					    @param[in] val  unsigned integer value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool number_unsigned(number_unsigned_t val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a floating-point number was read | 
				
			||||||
 | 
					    @param[in] val  floating-point value | 
				
			||||||
 | 
					    @param[in] s    raw token value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool number_float(number_float_t val, const string_t& s) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a string value was read | 
				
			||||||
 | 
					    @param[in] val  string value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    @note It is safe to move the passed string value. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool string(string_t& val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a binary value was read | 
				
			||||||
 | 
					    @param[in] val  binary value | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    @note It is safe to move the passed binary value. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool binary(binary_t& val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief the beginning of an object was read | 
				
			||||||
 | 
					    @param[in] elements  number of object elements or -1 if unknown | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    @note binary formats may report the number of elements | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool start_object(std::size_t elements) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief an object key was read | 
				
			||||||
 | 
					    @param[in] val  object key | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    @note It is safe to move the passed string. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool key(string_t& val) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief the end of an object was read | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool end_object() = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief the beginning of an array was read | 
				
			||||||
 | 
					    @param[in] elements  number of array elements or -1 if unknown | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    @note binary formats may report the number of elements | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool start_array(std::size_t elements) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief the end of an array was read | 
				
			||||||
 | 
					    @return whether parsing should proceed | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool end_array() = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief a parse error occurred | 
				
			||||||
 | 
					    @param[in] position    the position in the input where the error occurs | 
				
			||||||
 | 
					    @param[in] last_token  the last read token | 
				
			||||||
 | 
					    @param[in] ex          an exception object describing the error | 
				
			||||||
 | 
					    @return whether parsing should proceed (must return false) | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    virtual bool parse_error(std::size_t position, | 
				
			||||||
 | 
					                             const std::string& last_token, | 
				
			||||||
 | 
					                             const detail::exception& ex) = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_sax() = default; | 
				
			||||||
 | 
					    json_sax(const json_sax&) = default; | 
				
			||||||
 | 
					    json_sax(json_sax&&) noexcept = default; | 
				
			||||||
 | 
					    json_sax& operator=(const json_sax&) = default; | 
				
			||||||
 | 
					    json_sax& operator=(json_sax&&) noexcept = default; | 
				
			||||||
 | 
					    virtual ~json_sax() = default; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief SAX implementation to create a JSON value from SAX events | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This class implements the @ref json_sax interface and processes the SAX events | 
				
			||||||
 | 
					to create a JSON value which makes it basically a DOM parser. The structure or | 
				
			||||||
 | 
					hierarchy of the JSON value is managed by the stack `ref_stack` which contains | 
				
			||||||
 | 
					a pointer to the respective array or object for each recursion depth. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After successful parsing, the value that is passed by reference to the | 
				
			||||||
 | 
					constructor contains the parsed value. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@tparam BasicJsonType  the JSON type | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class json_sax_dom_parser | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in,out] r  reference to a JSON value that is manipulated while | 
				
			||||||
 | 
					                       parsing | 
				
			||||||
 | 
					    @param[in] allow_exceptions_  whether parse errors yield exceptions | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) | 
				
			||||||
 | 
					        : root(r), allow_exceptions(allow_exceptions_) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // make class move-only
 | 
				
			||||||
 | 
					    json_sax_dom_parser(const json_sax_dom_parser&) = delete; | 
				
			||||||
 | 
					    json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
 | 
				
			||||||
 | 
					    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; | 
				
			||||||
 | 
					    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
 | 
				
			||||||
 | 
					    ~json_sax_dom_parser() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool null() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(nullptr); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool boolean(bool val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_integer(number_integer_t val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_unsigned(number_unsigned_t val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_float(number_float_t val, const string_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool string(string_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool binary(binary_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(std::move(val)); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_object(std::size_t len) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool key(string_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(!ref_stack.empty()); | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_object()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // add null at given key and store the reference for later
 | 
				
			||||||
 | 
					        object_element = &(ref_stack.back()->m_value.object->operator[](val)); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_object() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(!ref_stack.empty()); | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_object()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ref_stack.back()->set_parents(); | 
				
			||||||
 | 
					        ref_stack.pop_back(); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_array(std::size_t len) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_array() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(!ref_stack.empty()); | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_array()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ref_stack.back()->set_parents(); | 
				
			||||||
 | 
					        ref_stack.pop_back(); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class Exception> | 
				
			||||||
 | 
					    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, | 
				
			||||||
 | 
					                     const Exception& ex) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        errored = true; | 
				
			||||||
 | 
					        static_cast<void>(ex); | 
				
			||||||
 | 
					        if (allow_exceptions) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(ex); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constexpr bool is_errored() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return errored; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @invariant If the ref stack is empty, then the passed value will be the new | 
				
			||||||
 | 
					               root. | 
				
			||||||
 | 
					    @invariant If the ref stack contains a value, then it is an array or an | 
				
			||||||
 | 
					               object to which we can add elements | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename Value> | 
				
			||||||
 | 
					    JSON_HEDLEY_RETURNS_NON_NULL | 
				
			||||||
 | 
					    BasicJsonType* handle_value(Value&& v) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (ref_stack.empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            root = BasicJsonType(std::forward<Value>(v)); | 
				
			||||||
 | 
					            return &root; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ref_stack.back()->is_array()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v)); | 
				
			||||||
 | 
					            return &(ref_stack.back()->m_value.array->back()); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_object()); | 
				
			||||||
 | 
					        JSON_ASSERT(object_element); | 
				
			||||||
 | 
					        *object_element = BasicJsonType(std::forward<Value>(v)); | 
				
			||||||
 | 
					        return object_element; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the parsed JSON value
 | 
				
			||||||
 | 
					    BasicJsonType& root; | 
				
			||||||
 | 
					    /// stack to model hierarchy of values
 | 
				
			||||||
 | 
					    std::vector<BasicJsonType*> ref_stack {}; | 
				
			||||||
 | 
					    /// helper to hold the reference for the next object element
 | 
				
			||||||
 | 
					    BasicJsonType* object_element = nullptr; | 
				
			||||||
 | 
					    /// whether a syntax error occurred
 | 
				
			||||||
 | 
					    bool errored = false; | 
				
			||||||
 | 
					    /// whether to throw exceptions in case of errors
 | 
				
			||||||
 | 
					    const bool allow_exceptions = true; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class json_sax_dom_callback_parser | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					    using parser_callback_t = typename BasicJsonType::parser_callback_t; | 
				
			||||||
 | 
					    using parse_event_t = typename BasicJsonType::parse_event_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_sax_dom_callback_parser(BasicJsonType& r, | 
				
			||||||
 | 
					                                 const parser_callback_t cb, | 
				
			||||||
 | 
					                                 const bool allow_exceptions_ = true) | 
				
			||||||
 | 
					        : root(r), callback(cb), allow_exceptions(allow_exceptions_) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        keep_stack.push_back(true); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // make class move-only
 | 
				
			||||||
 | 
					    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; | 
				
			||||||
 | 
					    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
 | 
				
			||||||
 | 
					    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; | 
				
			||||||
 | 
					    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
 | 
				
			||||||
 | 
					    ~json_sax_dom_callback_parser() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool null() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(nullptr); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool boolean(bool val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_integer(number_integer_t val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_unsigned(number_unsigned_t val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_float(number_float_t val, const string_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool string(string_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(val); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool binary(binary_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        handle_value(std::move(val)); | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_object(std::size_t len) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // check callback for object start
 | 
				
			||||||
 | 
					        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded); | 
				
			||||||
 | 
					        keep_stack.push_back(keep); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto val = handle_value(BasicJsonType::value_t::object, true); | 
				
			||||||
 | 
					        ref_stack.push_back(val.second); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check object limit
 | 
				
			||||||
 | 
					        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool key(string_t& val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        BasicJsonType k = BasicJsonType(val); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check callback for key
 | 
				
			||||||
 | 
					        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k); | 
				
			||||||
 | 
					        key_keep_stack.push_back(keep); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // add discarded value at given key and store the reference for later
 | 
				
			||||||
 | 
					        if (keep && ref_stack.back()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_object() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (ref_stack.back()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // discard object
 | 
				
			||||||
 | 
					                *ref_stack.back() = discarded; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                ref_stack.back()->set_parents(); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(!ref_stack.empty()); | 
				
			||||||
 | 
					        JSON_ASSERT(!keep_stack.empty()); | 
				
			||||||
 | 
					        ref_stack.pop_back(); | 
				
			||||||
 | 
					        keep_stack.pop_back(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // remove discarded value
 | 
				
			||||||
 | 
					            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (it->is_discarded()) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    ref_stack.back()->erase(it); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_array(std::size_t len) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded); | 
				
			||||||
 | 
					        keep_stack.push_back(keep); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto val = handle_value(BasicJsonType::value_t::array, true); | 
				
			||||||
 | 
					        ref_stack.push_back(val.second); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check array limit
 | 
				
			||||||
 | 
					        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_array() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        bool keep = true; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ref_stack.back()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); | 
				
			||||||
 | 
					            if (keep) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                ref_stack.back()->set_parents(); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // discard array
 | 
				
			||||||
 | 
					                *ref_stack.back() = discarded; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(!ref_stack.empty()); | 
				
			||||||
 | 
					        JSON_ASSERT(!keep_stack.empty()); | 
				
			||||||
 | 
					        ref_stack.pop_back(); | 
				
			||||||
 | 
					        keep_stack.pop_back(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // remove discarded value
 | 
				
			||||||
 | 
					        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ref_stack.back()->m_value.array->pop_back(); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class Exception> | 
				
			||||||
 | 
					    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, | 
				
			||||||
 | 
					                     const Exception& ex) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        errored = true; | 
				
			||||||
 | 
					        static_cast<void>(ex); | 
				
			||||||
 | 
					        if (allow_exceptions) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(ex); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constexpr bool is_errored() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return errored; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in] v  value to add to the JSON value we build during parsing | 
				
			||||||
 | 
					    @param[in] skip_callback  whether we should skip calling the callback | 
				
			||||||
 | 
					               function; this is required after start_array() and | 
				
			||||||
 | 
					               start_object() SAX events, because otherwise we would call the | 
				
			||||||
 | 
					               callback function with an empty array or object, respectively. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @invariant If the ref stack is empty, then the passed value will be the new | 
				
			||||||
 | 
					               root. | 
				
			||||||
 | 
					    @invariant If the ref stack contains a value, then it is an array or an | 
				
			||||||
 | 
					               object to which we can add elements | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @return pair of boolean (whether value should be kept) and pointer (to the | 
				
			||||||
 | 
					            passed value in the ref_stack hierarchy; nullptr if not kept) | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename Value> | 
				
			||||||
 | 
					    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(!keep_stack.empty()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // do not handle this value if we know it would be added to a discarded
 | 
				
			||||||
 | 
					        // container
 | 
				
			||||||
 | 
					        if (!keep_stack.back()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return {false, nullptr}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // create value
 | 
				
			||||||
 | 
					        auto value = BasicJsonType(std::forward<Value>(v)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check callback
 | 
				
			||||||
 | 
					        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // do not handle this value if we just learnt it shall be discarded
 | 
				
			||||||
 | 
					        if (!keep) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return {false, nullptr}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ref_stack.empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            root = std::move(value); | 
				
			||||||
 | 
					            return {true, &root}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // skip this value if we already decided to skip the parent
 | 
				
			||||||
 | 
					        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
 | 
				
			||||||
 | 
					        if (!ref_stack.back()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return {false, nullptr}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we now only expect arrays and objects
 | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // array
 | 
				
			||||||
 | 
					        if (ref_stack.back()->is_array()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            ref_stack.back()->m_value.array->emplace_back(std::move(value)); | 
				
			||||||
 | 
					            return {true, &(ref_stack.back()->m_value.array->back())}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // object
 | 
				
			||||||
 | 
					        JSON_ASSERT(ref_stack.back()->is_object()); | 
				
			||||||
 | 
					        // check if we should store an element for the current key
 | 
				
			||||||
 | 
					        JSON_ASSERT(!key_keep_stack.empty()); | 
				
			||||||
 | 
					        const bool store_element = key_keep_stack.back(); | 
				
			||||||
 | 
					        key_keep_stack.pop_back(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!store_element) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return {false, nullptr}; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(object_element); | 
				
			||||||
 | 
					        *object_element = std::move(value); | 
				
			||||||
 | 
					        return {true, object_element}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the parsed JSON value
 | 
				
			||||||
 | 
					    BasicJsonType& root; | 
				
			||||||
 | 
					    /// stack to model hierarchy of values
 | 
				
			||||||
 | 
					    std::vector<BasicJsonType*> ref_stack {}; | 
				
			||||||
 | 
					    /// stack to manage which values to keep
 | 
				
			||||||
 | 
					    std::vector<bool> keep_stack {}; | 
				
			||||||
 | 
					    /// stack to manage which object keys to keep
 | 
				
			||||||
 | 
					    std::vector<bool> key_keep_stack {}; | 
				
			||||||
 | 
					    /// helper to hold the reference for the next object element
 | 
				
			||||||
 | 
					    BasicJsonType* object_element = nullptr; | 
				
			||||||
 | 
					    /// whether a syntax error occurred
 | 
				
			||||||
 | 
					    bool errored = false; | 
				
			||||||
 | 
					    /// callback function
 | 
				
			||||||
 | 
					    const parser_callback_t callback = nullptr; | 
				
			||||||
 | 
					    /// whether to throw exceptions in case of errors
 | 
				
			||||||
 | 
					    const bool allow_exceptions = true; | 
				
			||||||
 | 
					    /// a discarded value for the callback
 | 
				
			||||||
 | 
					    BasicJsonType discarded = BasicJsonType::value_t::discarded; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class json_sax_acceptor | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool null() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool boolean(bool /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_integer(number_integer_t /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_unsigned(number_unsigned_t /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool string(string_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool binary(binary_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1)) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool key(string_t& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_object() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1)) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool end_array() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,507 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cmath> // isfinite | 
				
			||||||
 | 
					#include <cstdint> // uint8_t | 
				
			||||||
 | 
					#include <functional> // function | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <utility> // move | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/input/input_adapters.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/input/json_sax.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/input/lexer.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/is_sax.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					////////////
 | 
				
			||||||
 | 
					// parser //
 | 
				
			||||||
 | 
					////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class parse_event_t : std::uint8_t | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    /// the parser read `{` and started to process a JSON object
 | 
				
			||||||
 | 
					    object_start, | 
				
			||||||
 | 
					    /// the parser read `}` and finished processing a JSON object
 | 
				
			||||||
 | 
					    object_end, | 
				
			||||||
 | 
					    /// the parser read `[` and started to process a JSON array
 | 
				
			||||||
 | 
					    array_start, | 
				
			||||||
 | 
					    /// the parser read `]` and finished processing a JSON array
 | 
				
			||||||
 | 
					    array_end, | 
				
			||||||
 | 
					    /// the parser read a key of a value in an object
 | 
				
			||||||
 | 
					    key, | 
				
			||||||
 | 
					    /// the parser finished reading a JSON value
 | 
				
			||||||
 | 
					    value | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					using parser_callback_t = | 
				
			||||||
 | 
					    std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief syntax analysis | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This class implements a recursive descent parser. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType, typename InputAdapterType> | 
				
			||||||
 | 
					class parser | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using lexer_t = lexer<BasicJsonType, InputAdapterType>; | 
				
			||||||
 | 
					    using token_type = typename lexer_t::token_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /// a parser reading from an input adapter
 | 
				
			||||||
 | 
					    explicit parser(InputAdapterType&& adapter, | 
				
			||||||
 | 
					                    const parser_callback_t<BasicJsonType> cb = nullptr, | 
				
			||||||
 | 
					                    const bool allow_exceptions_ = true, | 
				
			||||||
 | 
					                    const bool skip_comments = false) | 
				
			||||||
 | 
					        : callback(cb) | 
				
			||||||
 | 
					        , m_lexer(std::move(adapter), skip_comments) | 
				
			||||||
 | 
					        , allow_exceptions(allow_exceptions_) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // read first token
 | 
				
			||||||
 | 
					        get_token(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief public parser interface | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] strict      whether to expect the last token to be EOF | 
				
			||||||
 | 
					    @param[in,out] result  parsed JSON value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.101 in case of an unexpected token | 
				
			||||||
 | 
					    @throw parse_error.102 if to_unicode fails or surrogate error | 
				
			||||||
 | 
					    @throw parse_error.103 if to_unicode fails | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void parse(const bool strict, BasicJsonType& result) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (callback) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions); | 
				
			||||||
 | 
					            sax_parse_internal(&sdp); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // in strict mode, input must be completely read
 | 
				
			||||||
 | 
					            if (strict && (get_token() != token_type::end_of_input)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                sdp.parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                parse_error::create(101, m_lexer.get_position(), | 
				
			||||||
 | 
					                                                    exception_message(token_type::end_of_input, "value"), nullptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // in case of an error, return discarded value
 | 
				
			||||||
 | 
					            if (sdp.is_errored()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                result = value_t::discarded; | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // set top-level value to null if it was discarded by the callback
 | 
				
			||||||
 | 
					            // function
 | 
				
			||||||
 | 
					            if (result.is_discarded()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                result = nullptr; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions); | 
				
			||||||
 | 
					            sax_parse_internal(&sdp); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // in strict mode, input must be completely read
 | 
				
			||||||
 | 
					            if (strict && (get_token() != token_type::end_of_input)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                sdp.parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // in case of an error, return discarded value
 | 
				
			||||||
 | 
					            if (sdp.is_errored()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                result = value_t::discarded; | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result.assert_invariant(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief public accept interface | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] strict  whether to expect the last token to be EOF | 
				
			||||||
 | 
					    @return whether the input is a proper JSON text | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    bool accept(const bool strict = true) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        json_sax_acceptor<BasicJsonType> sax_acceptor; | 
				
			||||||
 | 
					        return sax_parse(&sax_acceptor, strict); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename SAX> | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    bool sax_parse(SAX* sax, const bool strict = true) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; | 
				
			||||||
 | 
					        const bool result = sax_parse_internal(sax); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // strict mode: next byte must be EOF
 | 
				
			||||||
 | 
					        if (result && strict && (get_token() != token_type::end_of_input)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                    m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    template<typename SAX> | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    bool sax_parse_internal(SAX* sax) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // stack to remember the hierarchy of structured values we are parsing
 | 
				
			||||||
 | 
					        // true = array; false = object
 | 
				
			||||||
 | 
					        std::vector<bool> states; | 
				
			||||||
 | 
					        // value to avoid a goto (see comment where set to true)
 | 
				
			||||||
 | 
					        bool skip_to_state_evaluation = false; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (true) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (!skip_to_state_evaluation) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // invariant: get_token() was called before each iteration
 | 
				
			||||||
 | 
					                switch (last_token) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    case token_type::begin_object: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1)))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // closing } -> we are done
 | 
				
			||||||
 | 
					                        if (get_token() == token_type::end_object) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                return false; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // parse key
 | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                                    m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // parse separator (:)
 | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                                    m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // remember we are now inside an object
 | 
				
			||||||
 | 
					                        states.push_back(false); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // parse values
 | 
				
			||||||
 | 
					                        get_token(); | 
				
			||||||
 | 
					                        continue; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::begin_array: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1)))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // closing ] -> we are done
 | 
				
			||||||
 | 
					                        if (get_token() == token_type::end_array) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                return false; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // remember we are now inside an array
 | 
				
			||||||
 | 
					                        states.push_back(true); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // parse values (no need to call get_token)
 | 
				
			||||||
 | 
					                        continue; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::value_float: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        const auto res = m_lexer.get_number_float(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                                    m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                                    out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr)); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::literal_false: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::literal_null: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->null())) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::literal_true: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::value_integer: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::value_string: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::value_unsigned: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        break; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::parse_error: | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // using "uninitialized" to avoid "expected" message
 | 
				
			||||||
 | 
					                        return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                                m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case token_type::uninitialized: | 
				
			||||||
 | 
					                    case token_type::end_array: | 
				
			||||||
 | 
					                    case token_type::end_object: | 
				
			||||||
 | 
					                    case token_type::name_separator: | 
				
			||||||
 | 
					                    case token_type::value_separator: | 
				
			||||||
 | 
					                    case token_type::end_of_input: | 
				
			||||||
 | 
					                    case token_type::literal_or_value: | 
				
			||||||
 | 
					                    default: // the last token was unexpected
 | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                                m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            else | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                skip_to_state_evaluation = false; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // we reached this line after we successfully parsed a value
 | 
				
			||||||
 | 
					            if (states.empty()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // empty stack: we reached the end of the hierarchy: done
 | 
				
			||||||
 | 
					                return true; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (states.back())  // array
 | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // comma -> next value
 | 
				
			||||||
 | 
					                if (get_token() == token_type::value_separator) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // parse a new value
 | 
				
			||||||
 | 
					                    get_token(); | 
				
			||||||
 | 
					                    continue; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // closing ]
 | 
				
			||||||
 | 
					                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        return false; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // We are done with this array. Before we can parse a
 | 
				
			||||||
 | 
					                    // new value, we need to evaluate the new state first.
 | 
				
			||||||
 | 
					                    // By setting skip_to_state_evaluation to false, we
 | 
				
			||||||
 | 
					                    // are effectively jumping to the beginning of this if.
 | 
				
			||||||
 | 
					                    JSON_ASSERT(!states.empty()); | 
				
			||||||
 | 
					                    states.pop_back(); | 
				
			||||||
 | 
					                    skip_to_state_evaluation = true; | 
				
			||||||
 | 
					                    continue; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                        m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // states.back() is false -> object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comma -> next value
 | 
				
			||||||
 | 
					            if (get_token() == token_type::value_separator) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // parse key
 | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                            m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return false; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // parse separator (:)
 | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                            m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // parse values
 | 
				
			||||||
 | 
					                get_token(); | 
				
			||||||
 | 
					                continue; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // closing }
 | 
				
			||||||
 | 
					            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return false; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // We are done with this object. Before we can parse a
 | 
				
			||||||
 | 
					                // new value, we need to evaluate the new state first.
 | 
				
			||||||
 | 
					                // By setting skip_to_state_evaluation to false, we
 | 
				
			||||||
 | 
					                // are effectively jumping to the beginning of this if.
 | 
				
			||||||
 | 
					                JSON_ASSERT(!states.empty()); | 
				
			||||||
 | 
					                states.pop_back(); | 
				
			||||||
 | 
					                skip_to_state_evaluation = true; | 
				
			||||||
 | 
					                continue; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return sax->parse_error(m_lexer.get_position(), | 
				
			||||||
 | 
					                                    m_lexer.get_token_string(), | 
				
			||||||
 | 
					                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// get next token from lexer
 | 
				
			||||||
 | 
					    token_type get_token() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return last_token = m_lexer.scan(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string exception_message(const token_type expected, const std::string& context) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string error_msg = "syntax error "; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!context.empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            error_msg += concat("while parsing ", context, ' '); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        error_msg += "- "; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (last_token == token_type::parse_error) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            error_msg += concat(m_lexer.get_error_message(), "; last read: '", | 
				
			||||||
 | 
					                                m_lexer.get_token_string(), '\''); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            error_msg += concat("unexpected ", lexer_t::token_type_name(last_token)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (expected != token_type::uninitialized) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            error_msg += concat("; expected ", lexer_t::token_type_name(expected)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return error_msg; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// callback function
 | 
				
			||||||
 | 
					    const parser_callback_t<BasicJsonType> callback = nullptr; | 
				
			||||||
 | 
					    /// the type of the last read token
 | 
				
			||||||
 | 
					    token_type last_token = token_type::uninitialized; | 
				
			||||||
 | 
					    /// the lexer
 | 
				
			||||||
 | 
					    lexer_t m_lexer; | 
				
			||||||
 | 
					    /// whether to throw exceptions in case of errors
 | 
				
			||||||
 | 
					    const bool allow_exceptions = true; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,37 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// struct to capture the start position of the current token
 | 
				
			||||||
 | 
					struct position_t | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    /// the total number of characters read
 | 
				
			||||||
 | 
					    std::size_t chars_read_total = 0; | 
				
			||||||
 | 
					    /// the number of characters read in the current line
 | 
				
			||||||
 | 
					    std::size_t chars_read_current_line = 0; | 
				
			||||||
 | 
					    /// the number of lines read
 | 
				
			||||||
 | 
					    std::size_t lines_read = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// conversion to size_t to preserve SAX interface
 | 
				
			||||||
 | 
					    constexpr operator size_t() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return chars_read_total; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,35 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/primitive_iterator.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief an iterator value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@note This structure could easily be a union, but MSVC currently does not allow | 
				
			||||||
 | 
					unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType> struct internal_iterator | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    /// iterator for JSON objects
 | 
				
			||||||
 | 
					    typename BasicJsonType::object_t::iterator object_iterator {}; | 
				
			||||||
 | 
					    /// iterator for JSON arrays
 | 
				
			||||||
 | 
					    typename BasicJsonType::array_t::iterator array_iterator {}; | 
				
			||||||
 | 
					    /// generic iterator for all other types
 | 
				
			||||||
 | 
					    primitive_iterator_t primitive_iterator {}; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,751 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next | 
				
			||||||
 | 
					#include <type_traits> // conditional, is_const, remove_const | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/internal_iterator.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/primitive_iterator.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// forward declare, to be able to friend it later on
 | 
				
			||||||
 | 
					template<typename IteratorType> class iteration_proxy; | 
				
			||||||
 | 
					template<typename IteratorType> class iteration_proxy_value; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief a template for a bidirectional iterator for the @ref basic_json class
 | 
				
			||||||
 | 
					This class implements a both iterators (iterator and const_iterator) for the | 
				
			||||||
 | 
					@ref basic_json class. | 
				
			||||||
 | 
					@note An iterator is called *initialized* when a pointer to a JSON value has | 
				
			||||||
 | 
					      been set (e.g., by a constructor or a copy assignment). If the iterator is | 
				
			||||||
 | 
					      default-constructed, it is *uninitialized* and most methods are undefined. | 
				
			||||||
 | 
					      **The library uses assertions to detect calls on uninitialized iterators.** | 
				
			||||||
 | 
					@requirement The class satisfies the following concept requirements: | 
				
			||||||
 | 
					- | 
				
			||||||
 | 
					[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
 | 
				
			||||||
 | 
					  The iterator that can be moved can be moved in both directions (i.e. | 
				
			||||||
 | 
					  incremented and decremented). | 
				
			||||||
 | 
					@since version 1.0.0, simplified in version 2.0.9, change to bidirectional | 
				
			||||||
 | 
					       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
 | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    /// the iterator with BasicJsonType of different const-ness
 | 
				
			||||||
 | 
					    using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>; | 
				
			||||||
 | 
					    /// allow basic_json to access private members
 | 
				
			||||||
 | 
					    friend other_iter_impl; | 
				
			||||||
 | 
					    friend BasicJsonType; | 
				
			||||||
 | 
					    friend iteration_proxy<iter_impl>; | 
				
			||||||
 | 
					    friend iteration_proxy_value<iter_impl>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    using object_t = typename BasicJsonType::object_t; | 
				
			||||||
 | 
					    using array_t = typename BasicJsonType::array_t; | 
				
			||||||
 | 
					    // make sure BasicJsonType is basic_json or const basic_json
 | 
				
			||||||
 | 
					    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value, | 
				
			||||||
 | 
					                  "iter_impl only accepts (const) basic_json"); | 
				
			||||||
 | 
					    // superficial check for the LegacyBidirectionalIterator named requirement
 | 
				
			||||||
 | 
					    static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value | 
				
			||||||
 | 
					                  &&  std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value, | 
				
			||||||
 | 
					                  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement."); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
 | 
				
			||||||
 | 
					    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
 | 
				
			||||||
 | 
					    /// A user-defined iterator should provide publicly accessible typedefs named
 | 
				
			||||||
 | 
					    /// iterator_category, value_type, difference_type, pointer, and reference.
 | 
				
			||||||
 | 
					    /// Note that value_type is required to be non-const, even for constant iterators.
 | 
				
			||||||
 | 
					    using iterator_category = std::bidirectional_iterator_tag; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the type of the values when the iterator is dereferenced
 | 
				
			||||||
 | 
					    using value_type = typename BasicJsonType::value_type; | 
				
			||||||
 | 
					    /// a type to represent differences between iterators
 | 
				
			||||||
 | 
					    using difference_type = typename BasicJsonType::difference_type; | 
				
			||||||
 | 
					    /// defines a pointer to the type iterated over (value_type)
 | 
				
			||||||
 | 
					    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value, | 
				
			||||||
 | 
					          typename BasicJsonType::const_pointer, | 
				
			||||||
 | 
					          typename BasicJsonType::pointer>::type; | 
				
			||||||
 | 
					    /// defines a reference to the type iterated over (value_type)
 | 
				
			||||||
 | 
					    using reference = | 
				
			||||||
 | 
					        typename std::conditional<std::is_const<BasicJsonType>::value, | 
				
			||||||
 | 
					        typename BasicJsonType::const_reference, | 
				
			||||||
 | 
					        typename BasicJsonType::reference>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iter_impl() = default; | 
				
			||||||
 | 
					    ~iter_impl() = default; | 
				
			||||||
 | 
					    iter_impl(iter_impl&&) noexcept = default; | 
				
			||||||
 | 
					    iter_impl& operator=(iter_impl&&) noexcept = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief constructor for a given JSON instance | 
				
			||||||
 | 
					    @param[in] object  pointer to a JSON object for this iterator | 
				
			||||||
 | 
					    @pre object != nullptr | 
				
			||||||
 | 
					    @post The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    explicit iter_impl(pointer object) noexcept : m_object(object) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.object_iterator = typename object_t::iterator(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.array_iterator = typename array_t::iterator(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.primitive_iterator = primitive_iterator_t(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @note The conventional copy constructor and copy assignment are implicitly | 
				
			||||||
 | 
					          defined. Combined with the following converting constructor and | 
				
			||||||
 | 
					          assignment, they support: (1) copy from iterator to iterator, (2) | 
				
			||||||
 | 
					          copy from const iterator to const iterator, and (3) conversion from | 
				
			||||||
 | 
					          iterator to const iterator. However conversion from const iterator | 
				
			||||||
 | 
					          to iterator is not defined. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief const copy constructor | 
				
			||||||
 | 
					    @param[in] other const iterator to copy from | 
				
			||||||
 | 
					    @note This copy constructor had to be defined explicitly to circumvent a bug | 
				
			||||||
 | 
					          occurring on msvc v19.0 compiler (VS 2015) debug build. For more | 
				
			||||||
 | 
					          information refer to: https://github.com/nlohmann/json/issues/1608
 | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept | 
				
			||||||
 | 
					        : m_object(other.m_object), m_it(other.m_it) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief converting assignment | 
				
			||||||
 | 
					    @param[in] other const iterator to copy from | 
				
			||||||
 | 
					    @return const/non-const iterator | 
				
			||||||
 | 
					    @note It is not checked whether @a other is initialized. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (&other != this) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            m_object = other.m_object; | 
				
			||||||
 | 
					            m_it = other.m_it; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief converting constructor | 
				
			||||||
 | 
					    @param[in] other  non-const iterator to copy from | 
				
			||||||
 | 
					    @note It is not checked whether @a other is initialized. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept | 
				
			||||||
 | 
					        : m_object(other.m_object), m_it(other.m_it) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief converting assignment | 
				
			||||||
 | 
					    @param[in] other  non-const iterator to copy from | 
				
			||||||
 | 
					    @return const/non-const iterator | 
				
			||||||
 | 
					    @note It is not checked whether @a other is initialized. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_object = other.m_object; | 
				
			||||||
 | 
					        m_it = other.m_it; | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  JSON_PRIVATE_UNLESS_TESTED: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief set the iterator to the first value | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void set_begin() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.object_iterator = m_object->m_value.object->begin(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.array_iterator = m_object->m_value.array->begin(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::null: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // set to end so begin()==end() is true: null is empty
 | 
				
			||||||
 | 
					                m_it.primitive_iterator.set_end(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.primitive_iterator.set_begin(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief set the iterator past the last value | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void set_end() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.object_iterator = m_object->m_value.object->end(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.array_iterator = m_object->m_value.array->end(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.primitive_iterator.set_end(); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return a reference to the value pointed to by the iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    reference operator*() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); | 
				
			||||||
 | 
					                return m_it.object_iterator->second; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); | 
				
			||||||
 | 
					                return *m_it.array_iterator; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::null: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return *m_object; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief dereference the iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    pointer operator->() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); | 
				
			||||||
 | 
					                return &(m_it.object_iterator->second); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); | 
				
			||||||
 | 
					                return &*m_it.array_iterator; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return m_object; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief post-increment (it++) | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        ++(*this); | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief pre-increment (++it) | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator++() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                std::advance(m_it.object_iterator, 1); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                std::advance(m_it.array_iterator, 1); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                ++m_it.primitive_iterator; | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief post-decrement (it--) | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        --(*this); | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief pre-decrement (--it) | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator--() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                std::advance(m_it.object_iterator, -1); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                std::advance(m_it.array_iterator, -1); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                --m_it.primitive_iterator; | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: equal | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr > | 
				
			||||||
 | 
					    bool operator==(const IterImpl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // if objects are not the same, the comparison is undefined
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					                return (m_it.object_iterator == other.m_it.object_iterator); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					                return (m_it.array_iterator == other.m_it.array_iterator); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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 (m_it.primitive_iterator == other.m_it.primitive_iterator); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: not equal | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr > | 
				
			||||||
 | 
					    bool operator!=(const IterImpl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return !operator==(other); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: smaller | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    bool operator<(const iter_impl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // if objects are not the same, the comparison is undefined
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					                return (m_it.array_iterator < other.m_it.array_iterator); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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 (m_it.primitive_iterator < other.m_it.primitive_iterator); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: less than or equal | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    bool operator<=(const iter_impl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return !other.operator < (*this); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: greater than | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    bool operator>(const iter_impl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return !operator<=(other); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief comparison: greater than or equal | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    bool operator>=(const iter_impl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return !operator<(other); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief add to iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator+=(difference_type i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                std::advance(m_it.array_iterator, i); | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                m_it.primitive_iterator += i; | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief subtract from iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl& operator-=(difference_type i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return operator+=(-i); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief add to iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl operator+(difference_type i) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        result += i; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief addition of distance and iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    friend iter_impl operator+(difference_type i, const iter_impl& it) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = it; | 
				
			||||||
 | 
					        result += i; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief subtract from iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    iter_impl operator-(difference_type i) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        result -= i; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return difference | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    difference_type operator-(const iter_impl& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					                return m_it.array_iterator - other.m_it.array_iterator; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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 m_it.primitive_iterator - other.m_it.primitive_iterator; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief access to successor | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    reference operator[](difference_type n) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (m_object->m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					                return *std::next(m_it.array_iterator, n); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::null: | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return *m_object; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return the key of an object iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    const typename object_t::key_type& key() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(m_object != nullptr); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_LIKELY(m_object->is_object())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return m_it.object_iterator->first; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return the value of an iterator | 
				
			||||||
 | 
					    @pre The iterator is initialized; i.e. `m_object != nullptr`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    reference value() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return operator*(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  JSON_PRIVATE_UNLESS_TESTED: | 
				
			||||||
 | 
					    /// associated JSON instance
 | 
				
			||||||
 | 
					    pointer m_object = nullptr; | 
				
			||||||
 | 
					    /// the actual iterator of the associated instance
 | 
				
			||||||
 | 
					    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {}; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,242 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <iterator> // input_iterator_tag | 
				
			||||||
 | 
					#include <string> // string, to_string | 
				
			||||||
 | 
					#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/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename string_type> | 
				
			||||||
 | 
					void int_to_string( string_type& target, std::size_t value ) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // For ADL
 | 
				
			||||||
 | 
					    using std::to_string; | 
				
			||||||
 | 
					    target = to_string(value); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					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::input_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; | 
				
			||||||
 | 
					    iteration_proxy_value& operator=(iteration_proxy_value&&) | 
				
			||||||
 | 
					    noexcept(std::is_nothrow_move_assignable<IteratorType>::value | 
				
			||||||
 | 
					             && std::is_nothrow_move_assignable<string_type>::value) = default; | 
				
			||||||
 | 
					    ~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() function
 | 
				
			||||||
 | 
					template<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/1391
 | 
				
			||||||
 | 
					template<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/1391
 | 
				
			||||||
 | 
					template<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 detail
 | 
				
			||||||
 | 
					NLOHMANN_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/1391
 | 
				
			||||||
 | 
					namespace std | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__clang__) | 
				
			||||||
 | 
					    // Fix: https://github.com/nlohmann/json/issues/1401
 | 
				
			||||||
 | 
					    #pragma clang diagnostic push | 
				
			||||||
 | 
					    #pragma clang diagnostic ignored "-Wmismatched-tags" | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					template<typename IteratorType> | 
				
			||||||
 | 
					class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> | 
				
			||||||
 | 
					            : 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 >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  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 | 
				
			||||||
@ -0,0 +1,61 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iterator> // random_access_iterator_tag | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/void_t.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename It, typename = void> | 
				
			||||||
 | 
					struct iterator_types {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename It> | 
				
			||||||
 | 
					struct iterator_types < | 
				
			||||||
 | 
					    It, | 
				
			||||||
 | 
					    void_t<typename It::difference_type, typename It::value_type, typename It::pointer, | 
				
			||||||
 | 
					    typename It::reference, typename It::iterator_category >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using difference_type = typename It::difference_type; | 
				
			||||||
 | 
					    using value_type = typename It::value_type; | 
				
			||||||
 | 
					    using pointer = typename It::pointer; | 
				
			||||||
 | 
					    using reference = typename It::reference; | 
				
			||||||
 | 
					    using iterator_category = typename It::iterator_category; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is required as some compilers implement std::iterator_traits in a way that
 | 
				
			||||||
 | 
					// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
 | 
				
			||||||
 | 
					template<typename T, typename = void> | 
				
			||||||
 | 
					struct iterator_traits | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> | 
				
			||||||
 | 
					            : iterator_types<T> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using iterator_category = std::random_access_iterator_tag; | 
				
			||||||
 | 
					    using value_type = T; | 
				
			||||||
 | 
					    using difference_type = ptrdiff_t; | 
				
			||||||
 | 
					    using pointer = T*; | 
				
			||||||
 | 
					    using reference = T&; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,130 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> // ptrdiff_t | 
				
			||||||
 | 
					#include <iterator> // reverse_iterator | 
				
			||||||
 | 
					#include <utility> // declval | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////////
 | 
				
			||||||
 | 
					// reverse_iterator //
 | 
				
			||||||
 | 
					//////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief a template for a reverse iterator class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@tparam Base the base iterator type to reverse. Valid types are @ref | 
				
			||||||
 | 
					iterator (to create @ref reverse_iterator) and @ref const_iterator (to | 
				
			||||||
 | 
					create @ref const_reverse_iterator). | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@requirement The class satisfies the following concept requirements: | 
				
			||||||
 | 
					- | 
				
			||||||
 | 
					[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
 | 
				
			||||||
 | 
					  The iterator that can be moved can be moved in both directions (i.e. | 
				
			||||||
 | 
					  incremented and decremented). | 
				
			||||||
 | 
					- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
 | 
				
			||||||
 | 
					  It is possible to write to the pointed-to element (only if @a Base is | 
				
			||||||
 | 
					  @ref iterator). | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@since version 1.0.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename Base> | 
				
			||||||
 | 
					class json_reverse_iterator : public std::reverse_iterator<Base> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using difference_type = std::ptrdiff_t; | 
				
			||||||
 | 
					    /// shortcut to the reverse iterator adapter
 | 
				
			||||||
 | 
					    using base_iterator = std::reverse_iterator<Base>; | 
				
			||||||
 | 
					    /// the reference type for the pointed-to element
 | 
				
			||||||
 | 
					    using reference = typename Base::reference; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// create reverse iterator from iterator
 | 
				
			||||||
 | 
					    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept | 
				
			||||||
 | 
					        : base_iterator(it) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// create reverse iterator from base class
 | 
				
			||||||
 | 
					    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// post-increment (it++)
 | 
				
			||||||
 | 
					    json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator>(base_iterator::operator++(1)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// pre-increment (++it)
 | 
				
			||||||
 | 
					    json_reverse_iterator& operator++() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator&>(base_iterator::operator++()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// post-decrement (it--)
 | 
				
			||||||
 | 
					    json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator>(base_iterator::operator--(1)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// pre-decrement (--it)
 | 
				
			||||||
 | 
					    json_reverse_iterator& operator--() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator&>(base_iterator::operator--()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// add to iterator
 | 
				
			||||||
 | 
					    json_reverse_iterator& operator+=(difference_type i) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// add to iterator
 | 
				
			||||||
 | 
					    json_reverse_iterator operator+(difference_type i) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator>(base_iterator::operator+(i)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// subtract from iterator
 | 
				
			||||||
 | 
					    json_reverse_iterator operator-(difference_type i) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return static_cast<json_reverse_iterator>(base_iterator::operator-(i)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// return difference
 | 
				
			||||||
 | 
					    difference_type operator-(const json_reverse_iterator& other) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return base_iterator(*this) - base_iterator(other); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// access to successor
 | 
				
			||||||
 | 
					    reference operator[](difference_type n) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return *(this->operator+(n)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// return the key of an object iterator
 | 
				
			||||||
 | 
					    auto key() const -> decltype(std::declval<Base>().key()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto it = --this->base(); | 
				
			||||||
 | 
					        return it.key(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// return the value of an iterator
 | 
				
			||||||
 | 
					    reference value() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto it = --this->base(); | 
				
			||||||
 | 
					        return it.operator * (); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,132 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef> // ptrdiff_t | 
				
			||||||
 | 
					#include <limits>  // numeric_limits | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					@brief an iterator for primitive JSON types | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This class models an iterator for primitive JSON types (boolean, number, | 
				
			||||||
 | 
					string). It's only purpose is to allow the iterator/const_iterator classes | 
				
			||||||
 | 
					to "iterate" over primitive values. Internally, the iterator is modeled by | 
				
			||||||
 | 
					a `difference_type` variable. Value begin_value (`0`) models the begin, | 
				
			||||||
 | 
					end_value (`1`) models past the end. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					class primitive_iterator_t | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    using difference_type = std::ptrdiff_t; | 
				
			||||||
 | 
					    static constexpr difference_type begin_value = 0; | 
				
			||||||
 | 
					    static constexpr difference_type end_value = begin_value + 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  JSON_PRIVATE_UNLESS_TESTED: | 
				
			||||||
 | 
					    /// iterator as signed integer type
 | 
				
			||||||
 | 
					    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    constexpr difference_type get_value() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m_it; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// set iterator to a defined beginning
 | 
				
			||||||
 | 
					    void set_begin() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_it = begin_value; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// set iterator to a defined past the end
 | 
				
			||||||
 | 
					    void set_end() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_it = end_value; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// return whether the iterator can be dereferenced
 | 
				
			||||||
 | 
					    constexpr bool is_begin() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m_it == begin_value; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// return whether the iterator is at end
 | 
				
			||||||
 | 
					    constexpr bool is_end() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return m_it == end_value; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return lhs.m_it == rhs.m_it; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return lhs.m_it < rhs.m_it; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t operator+(difference_type n) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        result += n; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return lhs.m_it - rhs.m_it; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t& operator++() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        ++m_it; | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        ++m_it; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t& operator--() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        --m_it; | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto result = *this; | 
				
			||||||
 | 
					        --m_it; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t& operator+=(difference_type n) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_it += n; | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    primitive_iterator_t& operator-=(difference_type n) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        m_it -= n; | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,988 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm> // all_of | 
				
			||||||
 | 
					#include <cctype> // isdigit | 
				
			||||||
 | 
					#include <cerrno> // errno, ERANGE | 
				
			||||||
 | 
					#include <cstdlib> // strtoull | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					    #include <iosfwd> // ostream | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					#include <limits> // max | 
				
			||||||
 | 
					#include <numeric> // accumulate | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <utility> // move | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_escape.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/json_pointer/
 | 
				
			||||||
 | 
					template<typename RefStringType> | 
				
			||||||
 | 
					class json_pointer | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // allow basic_json to access private members
 | 
				
			||||||
 | 
					    NLOHMANN_BASIC_JSON_TPL_DECLARATION | 
				
			||||||
 | 
					    friend class basic_json; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename> | 
				
			||||||
 | 
					    friend class json_pointer; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T> | 
				
			||||||
 | 
					    struct string_t_helper | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using type = T; | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NLOHMANN_BASIC_JSON_TPL_DECLARATION | 
				
			||||||
 | 
					    struct string_t_helper<NLOHMANN_BASIC_JSON_TPL> | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using type = StringType; | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    // for backwards compatibility accept BasicJsonType
 | 
				
			||||||
 | 
					    using string_t = typename string_t_helper<RefStringType>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief create JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/
 | 
				
			||||||
 | 
					    explicit json_pointer(const string_t& s = "") | 
				
			||||||
 | 
					        : reference_tokens(split(s)) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return a string representation of the JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/to_string/
 | 
				
			||||||
 | 
					    string_t to_string() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return std::accumulate(reference_tokens.begin(), reference_tokens.end(), | 
				
			||||||
 | 
					                               string_t{}, | 
				
			||||||
 | 
					                               [](const string_t& a, const string_t& b) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return detail::concat(a, '/', detail::escape(b)); | 
				
			||||||
 | 
					        }); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return a string representation of the JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/
 | 
				
			||||||
 | 
					    JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string()) | 
				
			||||||
 | 
					    operator string_t() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return to_string(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					    /// @brief write string representation of the JSON pointer to stream
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
 | 
				
			||||||
 | 
					    friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        o << ptr.to_string(); | 
				
			||||||
 | 
					        return o; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief append another JSON pointer at the end of this JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
 | 
				
			||||||
 | 
					    json_pointer& operator/=(const json_pointer& ptr) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        reference_tokens.insert(reference_tokens.end(), | 
				
			||||||
 | 
					                                ptr.reference_tokens.begin(), | 
				
			||||||
 | 
					                                ptr.reference_tokens.end()); | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief append an unescaped reference token at the end of this JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
 | 
				
			||||||
 | 
					    json_pointer& operator/=(string_t token) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        push_back(std::move(token)); | 
				
			||||||
 | 
					        return *this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief append an array index at the end of this JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
 | 
				
			||||||
 | 
					    json_pointer& operator/=(std::size_t array_idx) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return *this /= std::to_string(array_idx); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
 | 
				
			||||||
 | 
					    friend json_pointer operator/(const json_pointer& lhs, | 
				
			||||||
 | 
					                                  const json_pointer& rhs) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return json_pointer(lhs) /= rhs; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
 | 
				
			||||||
 | 
					    friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return json_pointer(lhs) /= std::move(token); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
 | 
				
			||||||
 | 
					    friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return json_pointer(lhs) /= array_idx; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief returns the parent of this JSON pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/
 | 
				
			||||||
 | 
					    json_pointer parent_pointer() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return *this; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        json_pointer res = *this; | 
				
			||||||
 | 
					        res.pop_back(); | 
				
			||||||
 | 
					        return res; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief remove last reference token
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
 | 
				
			||||||
 | 
					    void pop_back() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(empty())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        reference_tokens.pop_back(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return last reference token
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/back/
 | 
				
			||||||
 | 
					    const string_t& back() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(empty())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return reference_tokens.back(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief append an unescaped token at the end of the reference pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
 | 
				
			||||||
 | 
					    void push_back(const string_t& token) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        reference_tokens.push_back(token); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief append an unescaped token at the end of the reference pointer
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
 | 
				
			||||||
 | 
					    void push_back(string_t&& token) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        reference_tokens.push_back(std::move(token)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief return whether pointer points to the root document
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/empty/
 | 
				
			||||||
 | 
					    bool empty() const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return reference_tokens.empty(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in] s  reference token to be converted into an array index | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @return integer representation of @a s | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.106  if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109  if an array index begins not with a digit | 
				
			||||||
 | 
					    @throw out_of_range.404 if string @a s could not be converted to an integer | 
				
			||||||
 | 
					    @throw out_of_range.410 if an array index exceeds size_type | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static typename BasicJsonType::size_type array_index(const string_t& s) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using size_type = typename BasicJsonType::size_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // error condition (cf. RFC 6901, Sect. 4)
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // error condition (cf. RFC 6901, Sect. 4)
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const char* p = s.c_str(); | 
				
			||||||
 | 
					        char* p_end = nullptr; | 
				
			||||||
 | 
					        errno = 0; // strtoull doesn't reset errno
 | 
				
			||||||
 | 
					        unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
 | 
				
			||||||
 | 
					        if (p == p_end // invalid input or empty string
 | 
				
			||||||
 | 
					                || errno == ERANGE // out of range
 | 
				
			||||||
 | 
					                || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
 | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // only triggered on special platforms (like 32bit), see also
 | 
				
			||||||
 | 
					        // https://github.com/nlohmann/json/pull/2203
 | 
				
			||||||
 | 
					        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)
 | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));   // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return static_cast<size_type>(res); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  JSON_PRIVATE_UNLESS_TESTED: | 
				
			||||||
 | 
					    json_pointer top() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(empty())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        json_pointer result = *this; | 
				
			||||||
 | 
					        result.reference_tokens = {reference_tokens[0]}; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief create and return a reference to the pointed to value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @complexity Linear in the number of reference tokens. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.109 if array index is not a number | 
				
			||||||
 | 
					    @throw type_error.313 if value cannot be unflattened | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    BasicJsonType& get_and_create(BasicJsonType& j) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto* result = &j; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // in case no reference tokens exist, return a reference to the JSON value
 | 
				
			||||||
 | 
					        // j which will be overwritten by a primitive value
 | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (result->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (reference_token == "0") | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // start a new array if reference token is 0
 | 
				
			||||||
 | 
					                        result = &result->operator[](0); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    else | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // start a new object otherwise
 | 
				
			||||||
 | 
					                        result = &result->operator[](reference_token); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // create an entry in the object
 | 
				
			||||||
 | 
					                    result = &result->operator[](reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // create an entry in the array
 | 
				
			||||||
 | 
					                    result = &result->operator[](array_index<BasicJsonType>(reference_token)); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                The following code is only reached if there exists a reference | 
				
			||||||
 | 
					                token _and_ the current value is primitive. In this case, we have | 
				
			||||||
 | 
					                an error situation, because primitive values may only occur as | 
				
			||||||
 | 
					                single value; that is, with an empty list of reference tokens. | 
				
			||||||
 | 
					                */ | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                    JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return a reference to the pointed to value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @note This version does not throw if a value is not present, but tries to | 
				
			||||||
 | 
					          create nested values instead. For instance, calling this function | 
				
			||||||
 | 
					          with pointer `"/this/that"` on a null value is equivalent to calling | 
				
			||||||
 | 
					          `operator[]("this").operator[]("that")` on that value, effectively | 
				
			||||||
 | 
					          changing the null value to an object. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] ptr  a JSON value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @return reference to the JSON value pointed to by the JSON pointer | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @complexity Linear in the length of the JSON pointer. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.106   if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109   if an array index was not a number | 
				
			||||||
 | 
					    @throw out_of_range.404  if the JSON pointer can not be resolved | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    BasicJsonType& get_unchecked(BasicJsonType* ptr) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // convert null values to arrays or objects before continuing
 | 
				
			||||||
 | 
					            if (ptr->is_null()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // check if reference token is a number
 | 
				
			||||||
 | 
					                const bool nums = | 
				
			||||||
 | 
					                    std::all_of(reference_token.begin(), reference_token.end(), | 
				
			||||||
 | 
					                                [](const unsigned char x) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    return std::isdigit(x); | 
				
			||||||
 | 
					                }); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // change value to array for numbers or "-" or to object otherwise
 | 
				
			||||||
 | 
					                *ptr = (nums || reference_token == "-") | 
				
			||||||
 | 
					                       ? detail::value_t::array | 
				
			||||||
 | 
					                       : detail::value_t::object; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (ptr->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // use unchecked object access
 | 
				
			||||||
 | 
					                    ptr = &ptr->operator[](reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (reference_token == "-") | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // explicitly treat "-" as index beyond the end
 | 
				
			||||||
 | 
					                        ptr = &ptr->operator[](ptr->m_value.array->size()); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    else | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // convert array index to number; unchecked access
 | 
				
			||||||
 | 
					                        ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                    JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *ptr; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @throw parse_error.106   if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109   if an array index was not a number | 
				
			||||||
 | 
					    @throw out_of_range.402  if the array index '-' is used | 
				
			||||||
 | 
					    @throw out_of_range.404  if the JSON pointer can not be resolved | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    BasicJsonType& get_checked(BasicJsonType* ptr) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (ptr->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // note: at performs range check
 | 
				
			||||||
 | 
					                    ptr = &ptr->at(reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // "-" always fails the range check
 | 
				
			||||||
 | 
					                        JSON_THROW(detail::out_of_range::create(402, detail::concat( | 
				
			||||||
 | 
					                                "array index '-' (", std::to_string(ptr->m_value.array->size()), | 
				
			||||||
 | 
					                                ") is out of range"), ptr)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // note: at performs range check
 | 
				
			||||||
 | 
					                    ptr = &ptr->at(array_index<BasicJsonType>(reference_token)); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                    JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *ptr; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief return a const reference to the pointed to value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] ptr  a JSON value | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @return const reference to the JSON value pointed to by the JSON | 
				
			||||||
 | 
					    pointer | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.106   if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109   if an array index was not a number | 
				
			||||||
 | 
					    @throw out_of_range.402  if the array index '-' is used | 
				
			||||||
 | 
					    @throw out_of_range.404  if the JSON pointer can not be resolved | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (ptr->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // use unchecked object access
 | 
				
			||||||
 | 
					                    ptr = &ptr->operator[](reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // "-" cannot be used for const access
 | 
				
			||||||
 | 
					                        JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // use unchecked array access
 | 
				
			||||||
 | 
					                    ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token)); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                    JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *ptr; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @throw parse_error.106   if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109   if an array index was not a number | 
				
			||||||
 | 
					    @throw out_of_range.402  if the array index '-' is used | 
				
			||||||
 | 
					    @throw out_of_range.404  if the JSON pointer can not be resolved | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    const BasicJsonType& get_checked(const BasicJsonType* ptr) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (ptr->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // note: at performs range check
 | 
				
			||||||
 | 
					                    ptr = &ptr->at(reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // "-" always fails the range check
 | 
				
			||||||
 | 
					                        JSON_THROW(detail::out_of_range::create(402, detail::concat( | 
				
			||||||
 | 
					                                "array index '-' (", std::to_string(ptr->m_value.array->size()), | 
				
			||||||
 | 
					                                ") is out of range"), ptr)); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // note: at performs range check
 | 
				
			||||||
 | 
					                    ptr = &ptr->at(array_index<BasicJsonType>(reference_token)); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                    JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return *ptr; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @throw parse_error.106   if an array index begins with '0' | 
				
			||||||
 | 
					    @throw parse_error.109   if an array index was not a number | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    bool contains(const BasicJsonType* ptr) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (const auto& reference_token : reference_tokens) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            switch (ptr->type()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case detail::value_t::object: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (!ptr->contains(reference_token)) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // we did not find the key in the object
 | 
				
			||||||
 | 
					                        return false; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    ptr = &ptr->operator[](reference_token); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::array: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // "-" always fails the range check
 | 
				
			||||||
 | 
					                        return false; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // invalid char
 | 
				
			||||||
 | 
					                        return false; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            // first char should be between '1' and '9'
 | 
				
			||||||
 | 
					                            return false; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        for (std::size_t i = 1; i < reference_token.size(); i++) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                // other char should be between '0' and '9'
 | 
				
			||||||
 | 
					                                return false; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const auto idx = array_index<BasicJsonType>(reference_token); | 
				
			||||||
 | 
					                    if (idx >= ptr->size()) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // index out of range
 | 
				
			||||||
 | 
					                        return false; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    ptr = &ptr->operator[](idx); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case detail::value_t::null: | 
				
			||||||
 | 
					                case detail::value_t::string: | 
				
			||||||
 | 
					                case detail::value_t::boolean: | 
				
			||||||
 | 
					                case detail::value_t::number_integer: | 
				
			||||||
 | 
					                case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					                case detail::value_t::number_float: | 
				
			||||||
 | 
					                case detail::value_t::binary: | 
				
			||||||
 | 
					                case detail::value_t::discarded: | 
				
			||||||
 | 
					                default: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // we do not expect primitive values if there is still a
 | 
				
			||||||
 | 
					                    // reference token to process
 | 
				
			||||||
 | 
					                    return false; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no reference token left means we found a primitive value
 | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief split the string input to reference tokens | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @note This function is only called by the json_pointer constructor. | 
				
			||||||
 | 
					          All exceptions below are documented there. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.107  if the pointer is not empty or begins with '/' | 
				
			||||||
 | 
					    @throw parse_error.108  if character '~' is not followed by '0' or '1' | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    static std::vector<string_t> split(const string_t& reference_string) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::vector<string_t> result; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // special case: empty reference string -> no reference tokens
 | 
				
			||||||
 | 
					        if (reference_string.empty()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return result; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check if nonempty reference string begins with slash
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // extract the reference tokens:
 | 
				
			||||||
 | 
					        // - slash: position of the last read slash (or end of string)
 | 
				
			||||||
 | 
					        // - start: position after the previous slash
 | 
				
			||||||
 | 
					        for ( | 
				
			||||||
 | 
					            // search for the first slash after the first character
 | 
				
			||||||
 | 
					            std::size_t slash = reference_string.find_first_of('/', 1), | 
				
			||||||
 | 
					            // set the beginning of the first reference token
 | 
				
			||||||
 | 
					            start = 1; | 
				
			||||||
 | 
					            // we can stop if start == 0 (if slash == string_t::npos)
 | 
				
			||||||
 | 
					            start != 0; | 
				
			||||||
 | 
					            // set the beginning of the next reference token
 | 
				
			||||||
 | 
					            // (will eventually be 0 if slash == string_t::npos)
 | 
				
			||||||
 | 
					            start = (slash == string_t::npos) ? 0 : slash + 1, | 
				
			||||||
 | 
					            // find next slash
 | 
				
			||||||
 | 
					            slash = reference_string.find_first_of('/', start)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // use the text between the beginning of the reference token
 | 
				
			||||||
 | 
					            // (start) and the last slash (slash).
 | 
				
			||||||
 | 
					            auto reference_token = reference_string.substr(start, slash - start); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // check reference tokens are properly escaped
 | 
				
			||||||
 | 
					            for (std::size_t pos = reference_token.find_first_of('~'); | 
				
			||||||
 | 
					                    pos != string_t::npos; | 
				
			||||||
 | 
					                    pos = reference_token.find_first_of('~', pos + 1)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_ASSERT(reference_token[pos] == '~'); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // ~ must be followed by 0 or 1
 | 
				
			||||||
 | 
					                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || | 
				
			||||||
 | 
					                                         (reference_token[pos + 1] != '0' && | 
				
			||||||
 | 
					                                          reference_token[pos + 1] != '1'))) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr)); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // finally, store the reference token
 | 
				
			||||||
 | 
					            detail::unescape(reference_token); | 
				
			||||||
 | 
					            result.push_back(reference_token); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in] reference_string  the reference string to the current value | 
				
			||||||
 | 
					    @param[in] value             the value to consider | 
				
			||||||
 | 
					    @param[in,out] result        the result object to insert values to | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @note Empty objects or arrays are flattened to `null`. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static void flatten(const string_t& reference_string, | 
				
			||||||
 | 
					                        const BasicJsonType& value, | 
				
			||||||
 | 
					                        BasicJsonType& result) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        switch (value.type()) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case detail::value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (value.m_value.array->empty()) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // flatten empty array as null
 | 
				
			||||||
 | 
					                    result[reference_string] = nullptr; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // iterate array and use index as reference string
 | 
				
			||||||
 | 
					                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        flatten(detail::concat(reference_string, '/', std::to_string(i)), | 
				
			||||||
 | 
					                                value.m_value.array->operator[](i), result); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case detail::value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (value.m_value.object->empty()) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // flatten empty object as null
 | 
				
			||||||
 | 
					                    result[reference_string] = nullptr; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // iterate object and use keys as reference string
 | 
				
			||||||
 | 
					                    for (const auto& element : *value.m_value.object) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case detail::value_t::null: | 
				
			||||||
 | 
					            case detail::value_t::string: | 
				
			||||||
 | 
					            case detail::value_t::boolean: | 
				
			||||||
 | 
					            case detail::value_t::number_integer: | 
				
			||||||
 | 
					            case detail::value_t::number_unsigned: | 
				
			||||||
 | 
					            case detail::value_t::number_float: | 
				
			||||||
 | 
					            case detail::value_t::binary: | 
				
			||||||
 | 
					            case detail::value_t::discarded: | 
				
			||||||
 | 
					            default: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // add primitive value with its reference string
 | 
				
			||||||
 | 
					                result[reference_string] = value; | 
				
			||||||
 | 
					                break; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in] value  flattened JSON | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @return unflattened JSON | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @throw parse_error.109 if array index is not a number | 
				
			||||||
 | 
					    @throw type_error.314  if value is not an object | 
				
			||||||
 | 
					    @throw type_error.315  if object values are not primitive | 
				
			||||||
 | 
					    @throw type_error.313  if value cannot be unflattened | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template<typename BasicJsonType> | 
				
			||||||
 | 
					    static BasicJsonType | 
				
			||||||
 | 
					    unflatten(const BasicJsonType& value) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (JSON_HEDLEY_UNLIKELY(!value.is_object())) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value)); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BasicJsonType result; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // iterate the JSON object values
 | 
				
			||||||
 | 
					        for (const auto& element : *value.m_value.object) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second)); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // assign value to reference pointed to by JSON pointer; Note that if
 | 
				
			||||||
 | 
					            // the JSON pointer is "" (i.e., points to the whole value), function
 | 
				
			||||||
 | 
					            // get_and_create returns a reference to result itself. An assignment
 | 
				
			||||||
 | 
					            // will then create a primitive value.
 | 
				
			||||||
 | 
					            json_pointer(element.first).get_and_create(result) = element.second; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // can't use conversion operator because of ambiguity
 | 
				
			||||||
 | 
					    json_pointer<string_t> convert() const& | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        json_pointer<string_t> result; | 
				
			||||||
 | 
					        result.reference_tokens = reference_tokens; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_pointer<string_t> convert()&& | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        json_pointer<string_t> result; | 
				
			||||||
 | 
					        result.reference_tokens = std::move(reference_tokens); | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					#if JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    /// @brief compares two JSON pointers for equality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeRhs> | 
				
			||||||
 | 
					    bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return reference_tokens == rhs.reference_tokens; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares JSON pointer and string for equality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
 | 
				
			||||||
 | 
					    JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer)) | 
				
			||||||
 | 
					    bool operator==(const string_t& rhs) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return *this == json_pointer(rhs); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief 3-way compares two JSON pointers
 | 
				
			||||||
 | 
					    template<typename RefStringTypeRhs> | 
				
			||||||
 | 
					    std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
 | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return  reference_tokens <=> rhs.reference_tokens; // *NOPAD*
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    /// @brief compares two JSON pointers for equality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                           const json_pointer<RefStringTypeRhs>& rhs) noexcept; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares JSON pointer and string for equality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeLhs, typename StringType> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                           const StringType& rhs); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares string and JSON pointer for equality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeRhs, typename StringType> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator==(const StringType& lhs, | 
				
			||||||
 | 
					                           const json_pointer<RefStringTypeRhs>& rhs); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares two JSON pointers for inequality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                           const json_pointer<RefStringTypeRhs>& rhs) noexcept; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares JSON pointer and string for inequality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeLhs, typename StringType> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                           const StringType& rhs); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares string and JSON pointer for inequality
 | 
				
			||||||
 | 
					    /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
 | 
				
			||||||
 | 
					    template<typename RefStringTypeRhs, typename StringType> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator!=(const StringType& lhs, | 
				
			||||||
 | 
					                           const json_pointer<RefStringTypeRhs>& rhs); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @brief compares two JSON pointer for less-than
 | 
				
			||||||
 | 
					    template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					    // NOLINTNEXTLINE(readability-redundant-declaration)
 | 
				
			||||||
 | 
					    friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                          const json_pointer<RefStringTypeRhs>& rhs) noexcept; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// the reference tokens
 | 
				
			||||||
 | 
					    std::vector<string_t> reference_tokens; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					// functions cannot be defined inside class due to ODR violations
 | 
				
			||||||
 | 
					template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                       const json_pointer<RefStringTypeRhs>& rhs) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return lhs.reference_tokens == rhs.reference_tokens; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeLhs, | 
				
			||||||
 | 
					         typename StringType = typename json_pointer<RefStringTypeLhs>::string_t> | 
				
			||||||
 | 
					JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) | 
				
			||||||
 | 
					inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                       const StringType& rhs) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return lhs == json_pointer<RefStringTypeLhs>(rhs); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeRhs, | 
				
			||||||
 | 
					         typename StringType = typename json_pointer<RefStringTypeRhs>::string_t> | 
				
			||||||
 | 
					JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) | 
				
			||||||
 | 
					inline bool operator==(const StringType& lhs, | 
				
			||||||
 | 
					                       const json_pointer<RefStringTypeRhs>& rhs) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return json_pointer<RefStringTypeRhs>(lhs) == rhs; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                       const json_pointer<RefStringTypeRhs>& rhs) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return !(lhs == rhs); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeLhs, | 
				
			||||||
 | 
					         typename StringType = typename json_pointer<RefStringTypeLhs>::string_t> | 
				
			||||||
 | 
					JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) | 
				
			||||||
 | 
					inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                       const StringType& rhs) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return !(lhs == rhs); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeRhs, | 
				
			||||||
 | 
					         typename StringType = typename json_pointer<RefStringTypeRhs>::string_t> | 
				
			||||||
 | 
					JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) | 
				
			||||||
 | 
					inline bool operator!=(const StringType& lhs, | 
				
			||||||
 | 
					                       const json_pointer<RefStringTypeRhs>& rhs) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return !(lhs == rhs); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RefStringTypeLhs, typename RefStringTypeRhs> | 
				
			||||||
 | 
					inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs, | 
				
			||||||
 | 
					                      const json_pointer<RefStringTypeRhs>& rhs) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return lhs.reference_tokens < rhs.reference_tokens; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,78 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <initializer_list> | 
				
			||||||
 | 
					#include <utility> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class json_ref | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    using value_type = BasicJsonType; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_ref(value_type&& value) | 
				
			||||||
 | 
					        : owned_value(std::move(value)) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_ref(const value_type& value) | 
				
			||||||
 | 
					        : value_ref(&value) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json_ref(std::initializer_list<json_ref> init) | 
				
			||||||
 | 
					        : owned_value(init) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template < | 
				
			||||||
 | 
					        class... Args, | 
				
			||||||
 | 
					        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 > | 
				
			||||||
 | 
					    json_ref(Args && ... args) | 
				
			||||||
 | 
					        : owned_value(std::forward<Args>(args)...) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // class should be movable only
 | 
				
			||||||
 | 
					    json_ref(json_ref&&) noexcept = default; | 
				
			||||||
 | 
					    json_ref(const json_ref&) = delete; | 
				
			||||||
 | 
					    json_ref& operator=(const json_ref&) = delete; | 
				
			||||||
 | 
					    json_ref& operator=(json_ref&&) = delete; | 
				
			||||||
 | 
					    ~json_ref() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value_type moved_or_copied() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (value_ref == nullptr) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return std::move(owned_value); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return *value_ref; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value_type const& operator*() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return value_ref ? *value_ref : owned_value; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value_type const* operator->() const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return &** this; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    mutable value_type owned_value = nullptr; | 
				
			||||||
 | 
					    value_type const* value_ref = nullptr; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,468 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <utility> // declval, pair | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/detected.hpp> | 
				
			||||||
 | 
					#include <nlohmann/thirdparty/hedley/hedley.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This file contains all internal macro definitions (except those affecting ABI)
 | 
				
			||||||
 | 
					// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// exclude unsupported compilers
 | 
				
			||||||
 | 
					#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) | 
				
			||||||
 | 
					    #if defined(__clang__) | 
				
			||||||
 | 
					        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 | 
				
			||||||
 | 
					            #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
 | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) | 
				
			||||||
 | 
					        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 | 
				
			||||||
 | 
					            #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
 | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// C++ language standard detection
 | 
				
			||||||
 | 
					// if the user manually specified the used c++ version this is skipped
 | 
				
			||||||
 | 
					#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) | 
				
			||||||
 | 
					    #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_20 | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_17 | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_14 | 
				
			||||||
 | 
					    #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
 | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_17 | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_14 | 
				
			||||||
 | 
					    #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) | 
				
			||||||
 | 
					        #define JSON_HAS_CPP_14 | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					    // the cpp 11 flag is always specified because it is the minimal required version
 | 
				
			||||||
 | 
					    #define JSON_HAS_CPP_11 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __has_include | 
				
			||||||
 | 
					    #if __has_include(<version>) | 
				
			||||||
 | 
					        #include <version> | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) | 
				
			||||||
 | 
					    #ifdef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					        #if defined(__cpp_lib_filesystem) | 
				
			||||||
 | 
					            #define JSON_HAS_FILESYSTEM 1 | 
				
			||||||
 | 
					        #elif defined(__cpp_lib_experimental_filesystem) | 
				
			||||||
 | 
					            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 | 
				
			||||||
 | 
					        #elif !defined(__has_include) | 
				
			||||||
 | 
					            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 | 
				
			||||||
 | 
					        #elif __has_include(<filesystem>) | 
				
			||||||
 | 
					            #define JSON_HAS_FILESYSTEM 1 | 
				
			||||||
 | 
					        #elif __has_include(<experimental/filesystem>) | 
				
			||||||
 | 
					            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
 | 
				
			||||||
 | 
					        #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
 | 
				
			||||||
 | 
					        #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
 | 
				
			||||||
 | 
					        #if defined(__clang_major__) && __clang_major__ < 7 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
 | 
				
			||||||
 | 
					        #if defined(_MSC_VER) && _MSC_VER < 1914 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no filesystem support before iOS 13
 | 
				
			||||||
 | 
					        #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // no filesystem support before macOS Catalina
 | 
				
			||||||
 | 
					        #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 | 
				
			||||||
 | 
					            #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					        #endif | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					    #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					    #define JSON_HAS_FILESYSTEM 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ | 
				
			||||||
 | 
					        && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L | 
				
			||||||
 | 
					        #define JSON_HAS_THREE_WAY_COMPARISON 1 | 
				
			||||||
 | 
					    #else | 
				
			||||||
 | 
					        #define JSON_HAS_THREE_WAY_COMPARISON 0 | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_RANGES | 
				
			||||||
 | 
					    // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
 | 
				
			||||||
 | 
					    #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 | 
				
			||||||
 | 
					        #define JSON_HAS_RANGES 0 | 
				
			||||||
 | 
					    #elif defined(__cpp_lib_ranges) | 
				
			||||||
 | 
					        #define JSON_HAS_RANGES 1 | 
				
			||||||
 | 
					    #else | 
				
			||||||
 | 
					        #define JSON_HAS_RANGES 0 | 
				
			||||||
 | 
					    #endif | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					    #define JSON_INLINE_VARIABLE inline | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define JSON_INLINE_VARIABLE | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) | 
				
			||||||
 | 
					    #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define JSON_NO_UNIQUE_ADDRESS | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// disable documentation warnings on clang
 | 
				
			||||||
 | 
					#if defined(__clang__) | 
				
			||||||
 | 
					    #pragma clang diagnostic push | 
				
			||||||
 | 
					    #pragma clang diagnostic ignored "-Wdocumentation" | 
				
			||||||
 | 
					    #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// allow disabling exceptions
 | 
				
			||||||
 | 
					#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) | 
				
			||||||
 | 
					    #define JSON_THROW(exception) throw exception | 
				
			||||||
 | 
					    #define JSON_TRY try | 
				
			||||||
 | 
					    #define JSON_CATCH(exception) catch(exception) | 
				
			||||||
 | 
					    #define JSON_INTERNAL_CATCH(exception) catch(exception) | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #include <cstdlib> | 
				
			||||||
 | 
					    #define JSON_THROW(exception) std::abort() | 
				
			||||||
 | 
					    #define JSON_TRY if(true) | 
				
			||||||
 | 
					    #define JSON_CATCH(exception) if(false) | 
				
			||||||
 | 
					    #define JSON_INTERNAL_CATCH(exception) if(false) | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// override exception macros
 | 
				
			||||||
 | 
					#if defined(JSON_THROW_USER) | 
				
			||||||
 | 
					    #undef JSON_THROW | 
				
			||||||
 | 
					    #define JSON_THROW JSON_THROW_USER | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					#if defined(JSON_TRY_USER) | 
				
			||||||
 | 
					    #undef JSON_TRY | 
				
			||||||
 | 
					    #define JSON_TRY JSON_TRY_USER | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					#if defined(JSON_CATCH_USER) | 
				
			||||||
 | 
					    #undef JSON_CATCH | 
				
			||||||
 | 
					    #define JSON_CATCH JSON_CATCH_USER | 
				
			||||||
 | 
					    #undef JSON_INTERNAL_CATCH | 
				
			||||||
 | 
					    #define JSON_INTERNAL_CATCH JSON_CATCH_USER | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					#if defined(JSON_INTERNAL_CATCH_USER) | 
				
			||||||
 | 
					    #undef JSON_INTERNAL_CATCH | 
				
			||||||
 | 
					    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// allow overriding assert
 | 
				
			||||||
 | 
					#if !defined(JSON_ASSERT) | 
				
			||||||
 | 
					    #include <cassert> // assert | 
				
			||||||
 | 
					    #define JSON_ASSERT(x) assert(x) | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// allow to access some private functions (needed by the test suite)
 | 
				
			||||||
 | 
					#if defined(JSON_TESTS_PRIVATE) | 
				
			||||||
 | 
					    #define JSON_PRIVATE_UNLESS_TESTED public | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define JSON_PRIVATE_UNLESS_TESTED private | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief macro to briefly define a mapping between an enum and JSON | 
				
			||||||
 | 
					@def NLOHMANN_JSON_SERIALIZE_ENUM | 
				
			||||||
 | 
					@since version 3.4.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \ | 
				
			||||||
 | 
					    template<typename BasicJsonType>                                                            \
 | 
				
			||||||
 | 
					    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
 | 
				
			||||||
 | 
					    {                                                                                           \
 | 
				
			||||||
 | 
					        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
 | 
				
			||||||
 | 
					        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
 | 
				
			||||||
 | 
					        auto it = std::find_if(std::begin(m), std::end(m),                                      \
 | 
				
			||||||
 | 
					                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
 | 
				
			||||||
 | 
					        {                                                                                       \
 | 
				
			||||||
 | 
					            return ej_pair.first == e;                                                          \
 | 
				
			||||||
 | 
					        });                                                                                     \
 | 
				
			||||||
 | 
					        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
 | 
				
			||||||
 | 
					    }                                                                                           \
 | 
				
			||||||
 | 
					    template<typename BasicJsonType>                                                            \
 | 
				
			||||||
 | 
					    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
 | 
				
			||||||
 | 
					    {                                                                                           \
 | 
				
			||||||
 | 
					        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
 | 
				
			||||||
 | 
					        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
 | 
				
			||||||
 | 
					        auto it = std::find_if(std::begin(m), std::end(m),                                      \
 | 
				
			||||||
 | 
					                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
 | 
				
			||||||
 | 
					        {                                                                                       \
 | 
				
			||||||
 | 
					            return ej_pair.second == j;                                                         \
 | 
				
			||||||
 | 
					        });                                                                                     \
 | 
				
			||||||
 | 
					        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
 | 
				
			||||||
 | 
					// may be removed in the future once the class is split.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \ | 
				
			||||||
 | 
					    template<template<typename, typename, typename...> class ObjectType,   \
 | 
				
			||||||
 | 
					             template<typename, typename...> class ArrayType,              \
 | 
				
			||||||
 | 
					             class StringType, class BooleanType, class NumberIntegerType, \
 | 
				
			||||||
 | 
					             class NumberUnsignedType, class NumberFloatType,              \
 | 
				
			||||||
 | 
					             template<typename> class AllocatorType,                       \
 | 
				
			||||||
 | 
					             template<typename, typename = void> class JSONSerializer,     \
 | 
				
			||||||
 | 
					             class BinaryType> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_BASIC_JSON_TPL                                            \ | 
				
			||||||
 | 
					    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
 | 
				
			||||||
 | 
					    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
 | 
				
			||||||
 | 
					    AllocatorType, JSONSerializer, BinaryType> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Macros to simplify conversion from/to types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_EXPAND( x ) x | 
				
			||||||
 | 
					#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE64, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE63, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE62, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE61, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE60, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE59, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE58, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE57, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE56, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE55, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE54, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE53, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE52, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE51, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE50, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE49, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE48, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE47, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE46, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE45, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE44, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE43, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE42, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE41, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE40, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE39, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE38, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE37, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE36, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE35, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE34, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE33, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE32, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE31, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE30, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE29, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE28, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE27, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE26, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE25, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE24, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE23, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE22, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE21, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE20, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE19, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE18, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE17, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE16, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE15, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE14, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE13, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE12, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE11, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE10, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE9, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE8, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE7, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE6, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE5, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE4, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE3, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE2, \
 | 
				
			||||||
 | 
					        NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) | 
				
			||||||
 | 
					#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; | 
				
			||||||
 | 
					#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); | 
				
			||||||
 | 
					#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief macro | 
				
			||||||
 | 
					@def NLOHMANN_DEFINE_TYPE_INTRUSIVE | 
				
			||||||
 | 
					@since version 3.9.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \ | 
				
			||||||
 | 
					    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
 | 
				
			||||||
 | 
					    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...)  \ | 
				
			||||||
 | 
					    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
 | 
				
			||||||
 | 
					    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief macro | 
				
			||||||
 | 
					@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE | 
				
			||||||
 | 
					@since version 3.9.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \ | 
				
			||||||
 | 
					    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
 | 
				
			||||||
 | 
					    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...)  \ | 
				
			||||||
 | 
					    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
 | 
				
			||||||
 | 
					    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// inspired from https://stackoverflow.com/a/26745591
 | 
				
			||||||
 | 
					// allows to call any std function as if (e.g. with begin):
 | 
				
			||||||
 | 
					// using std::begin; begin(x);
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// it allows using the detected idiom to retrieve the return type
 | 
				
			||||||
 | 
					// of such an expression
 | 
				
			||||||
 | 
					#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \ | 
				
			||||||
 | 
					    namespace detail {                                                            \
 | 
				
			||||||
 | 
					    using std::std_name;                                                          \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    template<typename... T>                                                       \
 | 
				
			||||||
 | 
					    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
 | 
				
			||||||
 | 
					    }                                                                             \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    namespace detail2 {                                                           \
 | 
				
			||||||
 | 
					    struct std_name##_tag                                                         \
 | 
				
			||||||
 | 
					    {                                                                             \
 | 
				
			||||||
 | 
					    };                                                                            \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    template<typename... T>                                                       \
 | 
				
			||||||
 | 
					    std_name##_tag std_name(T&&...);                                              \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    template<typename... T>                                                       \
 | 
				
			||||||
 | 
					    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    template<typename... T>                                                       \
 | 
				
			||||||
 | 
					    struct would_call_std_##std_name                                              \
 | 
				
			||||||
 | 
					    {                                                                             \
 | 
				
			||||||
 | 
					        static constexpr auto const value = ::nlohmann::detail::                  \
 | 
				
			||||||
 | 
					                                            is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
 | 
				
			||||||
 | 
					    };                                                                            \
 | 
				
			||||||
 | 
					    } /* namespace detail2 */ \
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    template<typename... T>                                                       \
 | 
				
			||||||
 | 
					    struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \
 | 
				
			||||||
 | 
					    {                                                                             \
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_USE_IMPLICIT_CONVERSIONS | 
				
			||||||
 | 
					    #define JSON_USE_IMPLICIT_CONVERSIONS 1 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_USE_IMPLICIT_CONVERSIONS | 
				
			||||||
 | 
					    #define JSON_EXPLICIT | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    #define JSON_EXPLICIT explicit | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_DISABLE_ENUM_SERIALIZATION | 
				
			||||||
 | 
					    #define JSON_DISABLE_ENUM_SERIALIZATION 0 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_USE_GLOBAL_UDLS | 
				
			||||||
 | 
					    #define JSON_USE_GLOBAL_UDLS 1 | 
				
			||||||
 | 
					#endif | 
				
			||||||
@ -0,0 +1,44 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// restore clang diagnostic settings
 | 
				
			||||||
 | 
					#if defined(__clang__) | 
				
			||||||
 | 
					    #pragma clang diagnostic pop | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// clean up
 | 
				
			||||||
 | 
					#undef JSON_ASSERT | 
				
			||||||
 | 
					#undef JSON_INTERNAL_CATCH | 
				
			||||||
 | 
					#undef JSON_THROW | 
				
			||||||
 | 
					#undef JSON_PRIVATE_UNLESS_TESTED | 
				
			||||||
 | 
					#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION | 
				
			||||||
 | 
					#undef NLOHMANN_BASIC_JSON_TPL | 
				
			||||||
 | 
					#undef JSON_EXPLICIT | 
				
			||||||
 | 
					#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL | 
				
			||||||
 | 
					#undef JSON_INLINE_VARIABLE | 
				
			||||||
 | 
					#undef JSON_NO_UNIQUE_ADDRESS | 
				
			||||||
 | 
					#undef JSON_DISABLE_ENUM_SERIALIZATION | 
				
			||||||
 | 
					#undef JSON_USE_GLOBAL_UDLS | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_TEST_KEEP_MACROS | 
				
			||||||
 | 
					    #undef JSON_CATCH | 
				
			||||||
 | 
					    #undef JSON_TRY | 
				
			||||||
 | 
					    #undef JSON_HAS_CPP_11 | 
				
			||||||
 | 
					    #undef JSON_HAS_CPP_14 | 
				
			||||||
 | 
					    #undef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					    #undef JSON_HAS_CPP_20 | 
				
			||||||
 | 
					    #undef JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					    #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					    #undef JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    #undef JSON_HAS_RANGES | 
				
			||||||
 | 
					    #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/thirdparty/hedley/hedley_undef.hpp> | 
				
			||||||
@ -0,0 +1,17 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,17 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,171 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2018 The Abseil Authors
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <array> // array | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type | 
				
			||||||
 | 
					#include <utility> // index_sequence, make_index_sequence, index_sequence_for | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef JSON_HAS_CPP_14 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// the following utilities are natively available in C++14
 | 
				
			||||||
 | 
					using std::enable_if_t; | 
				
			||||||
 | 
					using std::index_sequence; | 
				
			||||||
 | 
					using std::make_index_sequence; | 
				
			||||||
 | 
					using std::index_sequence_for; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// alias templates to reduce boilerplate
 | 
				
			||||||
 | 
					template<bool B, typename T = void> | 
				
			||||||
 | 
					using enable_if_t = typename std::enable_if<B, T>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
 | 
				
			||||||
 | 
					// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//// START OF CODE FROM GOOGLE ABSEIL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// integer_sequence
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Class template representing a compile-time integer sequence. An instantiation
 | 
				
			||||||
 | 
					// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
 | 
				
			||||||
 | 
					// type through its template arguments (which is a common need when
 | 
				
			||||||
 | 
					// working with C++11 variadic templates). `absl::integer_sequence` is designed
 | 
				
			||||||
 | 
					// to be a drop-in replacement for C++14's `std::integer_sequence`.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   template< class T, T... Ints >
 | 
				
			||||||
 | 
					//   void user_function(integer_sequence<T, Ints...>);
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   int main()
 | 
				
			||||||
 | 
					//   {
 | 
				
			||||||
 | 
					//     // user_function's `T` will be deduced to `int` and `Ints...`
 | 
				
			||||||
 | 
					//     // will be deduced to `0, 1, 2, 3, 4`.
 | 
				
			||||||
 | 
					//     user_function(make_integer_sequence<int, 5>());
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					template <typename T, T... Ints> | 
				
			||||||
 | 
					struct integer_sequence | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using value_type = T; | 
				
			||||||
 | 
					    static constexpr std::size_t size() noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return sizeof...(Ints); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// index_sequence
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// A helper template for an `integer_sequence` of `size_t`,
 | 
				
			||||||
 | 
					// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
 | 
				
			||||||
 | 
					// `std::index_sequence`.
 | 
				
			||||||
 | 
					template <size_t... Ints> | 
				
			||||||
 | 
					using index_sequence = integer_sequence<size_t, Ints...>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace utility_internal | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Seq, size_t SeqSize, size_t Rem> | 
				
			||||||
 | 
					struct Extend; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
 | 
				
			||||||
 | 
					template <typename T, T... Ints, size_t SeqSize> | 
				
			||||||
 | 
					struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, T... Ints, size_t SeqSize> | 
				
			||||||
 | 
					struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Recursion helper for 'make_integer_sequence<T, N>'.
 | 
				
			||||||
 | 
					// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
 | 
				
			||||||
 | 
					template <typename T, size_t N> | 
				
			||||||
 | 
					struct Gen | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using type = | 
				
			||||||
 | 
					        typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T> | 
				
			||||||
 | 
					struct Gen<T, 0> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using type = integer_sequence<T>; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace utility_internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compile-time sequences of integers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// make_integer_sequence
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This template alias is equivalent to
 | 
				
			||||||
 | 
					// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
 | 
				
			||||||
 | 
					// replacement for C++14's `std::make_integer_sequence`.
 | 
				
			||||||
 | 
					template <typename T, T N> | 
				
			||||||
 | 
					using make_integer_sequence = typename utility_internal::Gen<T, N>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// make_index_sequence
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
 | 
				
			||||||
 | 
					// and is designed to be a drop-in replacement for C++14's
 | 
				
			||||||
 | 
					// `std::make_index_sequence`.
 | 
				
			||||||
 | 
					template <size_t N> | 
				
			||||||
 | 
					using make_index_sequence = make_integer_sequence<size_t, N>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// index_sequence_for
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Converts a typename pack into an index sequence of the same length, and
 | 
				
			||||||
 | 
					// is designed to be a drop-in replacement for C++14's
 | 
				
			||||||
 | 
					// `std::index_sequence_for()`
 | 
				
			||||||
 | 
					template <typename... Ts> | 
				
			||||||
 | 
					using index_sequence_for = make_index_sequence<sizeof...(Ts)>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//// END OF CODE FROM GOOGLE ABSEIL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dispatch utility (taken from ranges-v3)
 | 
				
			||||||
 | 
					template<unsigned N> struct priority_tag : priority_tag < N - 1 > {}; | 
				
			||||||
 | 
					template<> struct priority_tag<0> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// taken from ranges-v3
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct static_const | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static JSON_INLINE_VARIABLE constexpr T value{}; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_CPP_17 | 
				
			||||||
 | 
					    template<typename T> | 
				
			||||||
 | 
					    constexpr T static_const<T>::value; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename... Args> | 
				
			||||||
 | 
					inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}}; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,70 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <type_traits> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/void_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://en.cppreference.com/w/cpp/experimental/is_detected
 | 
				
			||||||
 | 
					struct nonesuch | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    nonesuch() = delete; | 
				
			||||||
 | 
					    ~nonesuch() = delete; | 
				
			||||||
 | 
					    nonesuch(nonesuch const&) = delete; | 
				
			||||||
 | 
					    nonesuch(nonesuch const&&) = delete; | 
				
			||||||
 | 
					    void operator=(nonesuch const&) = delete; | 
				
			||||||
 | 
					    void operator=(nonesuch&&) = delete; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Default, | 
				
			||||||
 | 
					         class AlwaysVoid, | 
				
			||||||
 | 
					         template<class...> class Op, | 
				
			||||||
 | 
					         class... Args> | 
				
			||||||
 | 
					struct detector | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using value_t = std::false_type; | 
				
			||||||
 | 
					    using type = Default; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Default, template<class...> class Op, class... Args> | 
				
			||||||
 | 
					struct detector<Default, void_t<Op<Args...>>, Op, Args...> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using value_t = std::true_type; | 
				
			||||||
 | 
					    using type = Op<Args...>; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<template<class...> class Op, class... Args> | 
				
			||||||
 | 
					struct is_detected_lazy : is_detected<Op, Args...> { }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using detected_t = typename detector<nonesuch, void, Op, Args...>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Default, template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using detected_or = detector<Default, void, Op, Args...>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Default, template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using detected_or_t = typename detected_or<Default, Op, Args...>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Expected, template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class To, template<class...> class Op, class... Args> | 
				
			||||||
 | 
					using is_detected_convertible = | 
				
			||||||
 | 
					    std::is_convertible<detected_t<Op, Args...>, To>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,21 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dispatching helper struct
 | 
				
			||||||
 | 
					template <class T> struct identity_tag {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,159 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint> // size_t | 
				
			||||||
 | 
					#include <utility> // declval | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/detected.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using null_function_t = decltype(std::declval<T&>().null()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using boolean_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().boolean(std::declval<bool>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename Integer> | 
				
			||||||
 | 
					using number_integer_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().number_integer(std::declval<Integer>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename Unsigned> | 
				
			||||||
 | 
					using number_unsigned_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename Float, typename String> | 
				
			||||||
 | 
					using number_float_function_t = decltype(std::declval<T&>().number_float( | 
				
			||||||
 | 
					                                    std::declval<Float>(), std::declval<const String&>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename String> | 
				
			||||||
 | 
					using string_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().string(std::declval<String&>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename Binary> | 
				
			||||||
 | 
					using binary_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().binary(std::declval<Binary&>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using start_object_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().start_object(std::declval<std::size_t>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename String> | 
				
			||||||
 | 
					using key_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().key(std::declval<String&>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using end_object_function_t = decltype(std::declval<T&>().end_object()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using start_array_function_t = | 
				
			||||||
 | 
					    decltype(std::declval<T&>().start_array(std::declval<std::size_t>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using end_array_function_t = decltype(std::declval<T&>().end_array()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename Exception> | 
				
			||||||
 | 
					using parse_error_function_t = decltype(std::declval<T&>().parse_error( | 
				
			||||||
 | 
					        std::declval<std::size_t>(), std::declval<const std::string&>(), | 
				
			||||||
 | 
					        std::declval<const Exception&>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename SAX, typename BasicJsonType> | 
				
			||||||
 | 
					struct is_sax | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    static_assert(is_basic_json<BasicJsonType>::value, | 
				
			||||||
 | 
					                  "BasicJsonType must be of type basic_json<...>"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					    using exception_t = typename BasicJsonType::exception; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_detected_exact<bool, null_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, boolean_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, string_function_t, SAX, string_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, start_object_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, key_function_t, SAX, string_t>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, end_object_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, start_array_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, end_array_function_t, SAX>::value && | 
				
			||||||
 | 
					        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename SAX, typename BasicJsonType> | 
				
			||||||
 | 
					struct is_sax_static_asserts | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    static_assert(is_basic_json<BasicJsonType>::value, | 
				
			||||||
 | 
					                  "BasicJsonType must be of type basic_json<...>"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using binary_t = typename BasicJsonType::binary_t; | 
				
			||||||
 | 
					    using exception_t = typename BasicJsonType::exception; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, null_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool null()"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool boolean(bool)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool boolean(bool)"); | 
				
			||||||
 | 
					    static_assert( | 
				
			||||||
 | 
					        is_detected_exact<bool, number_integer_function_t, SAX, | 
				
			||||||
 | 
					        number_integer_t>::value, | 
				
			||||||
 | 
					        "Missing/invalid function: bool number_integer(number_integer_t)"); | 
				
			||||||
 | 
					    static_assert( | 
				
			||||||
 | 
					        is_detected_exact<bool, number_unsigned_function_t, SAX, | 
				
			||||||
 | 
					        number_unsigned_t>::value, | 
				
			||||||
 | 
					        "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, number_float_function_t, SAX, | 
				
			||||||
 | 
					                  number_float_t, string_t>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); | 
				
			||||||
 | 
					    static_assert( | 
				
			||||||
 | 
					        is_detected_exact<bool, string_function_t, SAX, string_t>::value, | 
				
			||||||
 | 
					        "Missing/invalid function: bool string(string_t&)"); | 
				
			||||||
 | 
					    static_assert( | 
				
			||||||
 | 
					        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value, | 
				
			||||||
 | 
					        "Missing/invalid function: bool binary(binary_t&)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool start_object(std::size_t)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool key(string_t&)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool end_object()"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool start_array(std::size_t)"); | 
				
			||||||
 | 
					    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value, | 
				
			||||||
 | 
					                  "Missing/invalid function: bool end_array()"); | 
				
			||||||
 | 
					    static_assert( | 
				
			||||||
 | 
					        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value, | 
				
			||||||
 | 
					        "Missing/invalid function: bool parse_error(std::size_t, const " | 
				
			||||||
 | 
					        "std::string&, const exception&)"); | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,29 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if JSON_HAS_EXPERIMENTAL_FILESYSTEM | 
				
			||||||
 | 
					#include <experimental/filesystem> | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					namespace std_fs = std::experimental::filesystem; | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
 | 
					#elif JSON_HAS_FILESYSTEM | 
				
			||||||
 | 
					#include <filesystem> | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					namespace std_fs = std::filesystem; | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
 | 
					#endif | 
				
			||||||
@ -0,0 +1,740 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <limits> // numeric_limits | 
				
			||||||
 | 
					#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type | 
				
			||||||
 | 
					#include <utility> // declval | 
				
			||||||
 | 
					#include <tuple> // tuple | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/iterators/iterator_traits.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/call_std/begin.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/call_std/end.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/detected.hpp> | 
				
			||||||
 | 
					#include <nlohmann/json_fwd.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief detail namespace with internal helper functions | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This namespace collects functions that should not be exposed, | 
				
			||||||
 | 
					implementations of some @ref basic_json methods, and meta-programming helpers. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@since version 2.1.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/////////////
 | 
				
			||||||
 | 
					// helpers //
 | 
				
			||||||
 | 
					/////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note to maintainers:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Every trait in this file expects a non CV-qualified type.
 | 
				
			||||||
 | 
					// The only exceptions are in the 'aliases for detected' section
 | 
				
			||||||
 | 
					// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In this case, T has to be properly CV-qualified to constraint the function arguments
 | 
				
			||||||
 | 
					// (e.g. to_json(BasicJsonType&, const T&))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename> struct is_basic_json : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_BASIC_JSON_TPL_DECLARATION | 
				
			||||||
 | 
					struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// used by exceptions create() member functions
 | 
				
			||||||
 | 
					// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
 | 
				
			||||||
 | 
					// false_type otherwise
 | 
				
			||||||
 | 
					template<typename BasicJsonContext> | 
				
			||||||
 | 
					struct is_basic_json_context : | 
				
			||||||
 | 
					    std::integral_constant < bool, | 
				
			||||||
 | 
					    is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value | 
				
			||||||
 | 
					    || std::is_same<BasicJsonContext, std::nullptr_t>::value > | 
				
			||||||
 | 
					{}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////////
 | 
				
			||||||
 | 
					// json_ref helpers //
 | 
				
			||||||
 | 
					//////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename> | 
				
			||||||
 | 
					class json_ref; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename> | 
				
			||||||
 | 
					struct is_json_ref : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_json_ref<json_ref<T>> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////////////
 | 
				
			||||||
 | 
					// aliases for detected //
 | 
				
			||||||
 | 
					//////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using mapped_type_t = typename T::mapped_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using key_type_t = typename T::key_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using value_type_t = typename T::value_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using difference_type_t = typename T::difference_type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using pointer_t = typename T::pointer; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using reference_t = typename T::reference; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using iterator_category_t = typename T::iterator_category; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename... Args> | 
				
			||||||
 | 
					using to_json_function = decltype(T::to_json(std::declval<Args>()...)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename... Args> | 
				
			||||||
 | 
					using from_json_function = decltype(T::from_json(std::declval<Args>()...)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename U> | 
				
			||||||
 | 
					using get_template_function = decltype(std::declval<T>().template get<U>()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, typename = void> | 
				
			||||||
 | 
					struct has_from_json : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// trait checking if j.get<T> is valid
 | 
				
			||||||
 | 
					// use this trait instead of std::is_constructible or std::is_convertible,
 | 
				
			||||||
 | 
					// both rely on, or make use of implicit conversions, and thus fail when T
 | 
				
			||||||
 | 
					// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
 | 
				
			||||||
 | 
					template <typename BasicJsonType, typename T> | 
				
			||||||
 | 
					struct is_getable | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using serializer = typename BasicJsonType::template json_serializer<T, void>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_detected_exact<void, from_json_function, serializer, | 
				
			||||||
 | 
					        const BasicJsonType&, T&>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This trait checks if JSONSerializer<T>::from_json(json const&) exists
 | 
				
			||||||
 | 
					// this overload is used for non-default-constructible user-defined-types
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, typename = void> | 
				
			||||||
 | 
					struct has_non_default_from_json : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using serializer = typename BasicJsonType::template json_serializer<T, void>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_detected_exact<T, from_json_function, serializer, | 
				
			||||||
 | 
					        const BasicJsonType&>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
 | 
				
			||||||
 | 
					// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T, typename = void> | 
				
			||||||
 | 
					struct has_to_json : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using serializer = typename BasicJsonType::template json_serializer<T, void>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_detected_exact<void, to_json_function, serializer, BasicJsonType&, | 
				
			||||||
 | 
					        T>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using detect_key_compare = typename T::key_compare; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// obtains the actual object key comparator
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					struct actual_object_comparator | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using object_t = typename BasicJsonType::object_t; | 
				
			||||||
 | 
					    using object_comparator_t = typename BasicJsonType::default_object_comparator_t; | 
				
			||||||
 | 
					    using type = typename std::conditional < has_key_compare<object_t>::value, | 
				
			||||||
 | 
					          typename object_t::key_compare, object_comparator_t>::type; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					using actual_object_comparator_t = typename actual_object_comparator<BasicJsonType>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////
 | 
				
			||||||
 | 
					// is_ functions //
 | 
				
			||||||
 | 
					///////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://en.cppreference.com/w/cpp/types/conjunction
 | 
				
			||||||
 | 
					template<class...> struct conjunction : std::true_type { }; | 
				
			||||||
 | 
					template<class B> struct conjunction<B> : B { }; | 
				
			||||||
 | 
					template<class B, class... Bn> | 
				
			||||||
 | 
					struct conjunction<B, Bn...> | 
				
			||||||
 | 
					: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://en.cppreference.com/w/cpp/types/negation
 | 
				
			||||||
 | 
					template<class B> struct negation : std::integral_constant < bool, !B::value > { }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
 | 
				
			||||||
 | 
					// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
 | 
				
			||||||
 | 
					// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
 | 
				
			||||||
 | 
					template <typename T> | 
				
			||||||
 | 
					struct is_default_constructible : std::is_default_constructible<T> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T1, typename T2> | 
				
			||||||
 | 
					struct is_default_constructible<std::pair<T1, T2>> | 
				
			||||||
 | 
					            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T1, typename T2> | 
				
			||||||
 | 
					struct is_default_constructible<const std::pair<T1, T2>> | 
				
			||||||
 | 
					            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename... Ts> | 
				
			||||||
 | 
					struct is_default_constructible<std::tuple<Ts...>> | 
				
			||||||
 | 
					            : conjunction<is_default_constructible<Ts>...> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename... Ts> | 
				
			||||||
 | 
					struct is_default_constructible<const std::tuple<Ts...>> | 
				
			||||||
 | 
					            : conjunction<is_default_constructible<Ts>...> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename... Args> | 
				
			||||||
 | 
					struct is_constructible : std::is_constructible<T, Args...> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T1, typename T2> | 
				
			||||||
 | 
					struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T1, typename T2> | 
				
			||||||
 | 
					struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename... Ts> | 
				
			||||||
 | 
					struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename... Ts> | 
				
			||||||
 | 
					struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename = void> | 
				
			||||||
 | 
					struct is_iterator_traits : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_iterator_traits<iterator_traits<T>> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    using traits = iterator_traits<T>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    static constexpr auto value = | 
				
			||||||
 | 
					        is_detected<value_type_t, traits>::value && | 
				
			||||||
 | 
					        is_detected<difference_type_t, traits>::value && | 
				
			||||||
 | 
					        is_detected<pointer_t, traits>::value && | 
				
			||||||
 | 
					        is_detected<iterator_category_t, traits>::value && | 
				
			||||||
 | 
					        is_detected<reference_t, traits>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_range | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    using t_ref = typename std::add_lvalue_reference<T>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    using iterator = detected_t<result_of_begin, t_ref>; | 
				
			||||||
 | 
					    using sentinel = detected_t<result_of_end, t_ref>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
 | 
				
			||||||
 | 
					    // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
 | 
				
			||||||
 | 
					    // but reimplementing these would be too much work, as a lot of other concepts are used underneath
 | 
				
			||||||
 | 
					    static constexpr auto is_iterator_begin = | 
				
			||||||
 | 
					        is_iterator_traits<iterator_traits<iterator>>::value; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename R> | 
				
			||||||
 | 
					using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following implementation of is_complete_type is taken from
 | 
				
			||||||
 | 
					// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
 | 
				
			||||||
 | 
					// and is written by Xiang Fan who agreed to using it in this library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename = void> | 
				
			||||||
 | 
					struct is_complete_type : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleObjectType, | 
				
			||||||
 | 
					         typename = void> | 
				
			||||||
 | 
					struct is_compatible_object_type_impl : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleObjectType> | 
				
			||||||
 | 
					struct is_compatible_object_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, CompatibleObjectType, | 
				
			||||||
 | 
					    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&& | 
				
			||||||
 | 
					    is_detected<key_type_t, CompatibleObjectType>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using object_t = typename BasicJsonType::object_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // macOS's is_constructible does not play well with nonesuch...
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_constructible<typename object_t::key_type, | 
				
			||||||
 | 
					        typename CompatibleObjectType::key_type>::value && | 
				
			||||||
 | 
					        is_constructible<typename object_t::mapped_type, | 
				
			||||||
 | 
					        typename CompatibleObjectType::mapped_type>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleObjectType> | 
				
			||||||
 | 
					struct is_compatible_object_type | 
				
			||||||
 | 
					    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleObjectType, | 
				
			||||||
 | 
					         typename = void> | 
				
			||||||
 | 
					struct is_constructible_object_type_impl : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleObjectType> | 
				
			||||||
 | 
					struct is_constructible_object_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, ConstructibleObjectType, | 
				
			||||||
 | 
					    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&& | 
				
			||||||
 | 
					    is_detected<key_type_t, ConstructibleObjectType>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using object_t = typename BasicJsonType::object_t; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        (is_default_constructible<ConstructibleObjectType>::value && | 
				
			||||||
 | 
					         (std::is_move_assignable<ConstructibleObjectType>::value || | 
				
			||||||
 | 
					          std::is_copy_assignable<ConstructibleObjectType>::value) && | 
				
			||||||
 | 
					         (is_constructible<typename ConstructibleObjectType::key_type, | 
				
			||||||
 | 
					          typename object_t::key_type>::value && | 
				
			||||||
 | 
					          std::is_same < | 
				
			||||||
 | 
					          typename object_t::mapped_type, | 
				
			||||||
 | 
					          typename ConstructibleObjectType::mapped_type >::value)) || | 
				
			||||||
 | 
					        (has_from_json<BasicJsonType, | 
				
			||||||
 | 
					         typename ConstructibleObjectType::mapped_type>::value || | 
				
			||||||
 | 
					         has_non_default_from_json < | 
				
			||||||
 | 
					         BasicJsonType, | 
				
			||||||
 | 
					         typename ConstructibleObjectType::mapped_type >::value); | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleObjectType> | 
				
			||||||
 | 
					struct is_constructible_object_type | 
				
			||||||
 | 
					    : is_constructible_object_type_impl<BasicJsonType, | 
				
			||||||
 | 
					      ConstructibleObjectType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleStringType> | 
				
			||||||
 | 
					struct is_compatible_string_type | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr auto value = | 
				
			||||||
 | 
					        is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleStringType> | 
				
			||||||
 | 
					struct is_constructible_string_type | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // launder type through decltype() to fix compilation failure on ICPC
 | 
				
			||||||
 | 
					#ifdef __INTEL_COMPILER | 
				
			||||||
 | 
					    using laundered_type = decltype(std::declval<ConstructibleStringType>()); | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    using laundered_type = ConstructibleStringType; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr auto value = | 
				
			||||||
 | 
					        conjunction < | 
				
			||||||
 | 
					        is_constructible<laundered_type, typename BasicJsonType::string_t>, | 
				
			||||||
 | 
					        is_detected_exact<typename BasicJsonType::string_t::value_type, | 
				
			||||||
 | 
					        value_type_t, laundered_type >>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleArrayType, typename = void> | 
				
			||||||
 | 
					struct is_compatible_array_type_impl : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleArrayType> | 
				
			||||||
 | 
					struct is_compatible_array_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, CompatibleArrayType, | 
				
			||||||
 | 
					    enable_if_t < | 
				
			||||||
 | 
					    is_detected<iterator_t, CompatibleArrayType>::value&& | 
				
			||||||
 | 
					    is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&& | 
				
			||||||
 | 
					// special case for types like std::filesystem::path whose iterator's value_type are themselves
 | 
				
			||||||
 | 
					// c.f. https://github.com/nlohmann/json/pull/3073
 | 
				
			||||||
 | 
					    !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        is_constructible<BasicJsonType, | 
				
			||||||
 | 
					        range_value_t<CompatibleArrayType>>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleArrayType> | 
				
			||||||
 | 
					struct is_compatible_array_type | 
				
			||||||
 | 
					    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType, typename = void> | 
				
			||||||
 | 
					struct is_constructible_array_type_impl : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType> | 
				
			||||||
 | 
					struct is_constructible_array_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, ConstructibleArrayType, | 
				
			||||||
 | 
					    enable_if_t<std::is_same<ConstructibleArrayType, | 
				
			||||||
 | 
					    typename BasicJsonType::value_type>::value >> | 
				
			||||||
 | 
					            : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType> | 
				
			||||||
 | 
					struct is_constructible_array_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, ConstructibleArrayType, | 
				
			||||||
 | 
					    enable_if_t < !std::is_same<ConstructibleArrayType, | 
				
			||||||
 | 
					    typename BasicJsonType::value_type>::value&& | 
				
			||||||
 | 
					    !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					    is_default_constructible<ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					(std::is_move_assignable<ConstructibleArrayType>::value || | 
				
			||||||
 | 
					 std::is_copy_assignable<ConstructibleArrayType>::value)&& | 
				
			||||||
 | 
					is_detected<iterator_t, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&& | 
				
			||||||
 | 
					is_detected<range_value_t, ConstructibleArrayType>::value&& | 
				
			||||||
 | 
					// special case for types like std::filesystem::path whose iterator's value_type are themselves
 | 
				
			||||||
 | 
					// c.f. https://github.com/nlohmann/json/pull/3073
 | 
				
			||||||
 | 
					!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&& | 
				
			||||||
 | 
					        is_complete_type < | 
				
			||||||
 | 
					        detected_t<range_value_t, ConstructibleArrayType >>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using value_type = range_value_t<ConstructibleArrayType>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        std::is_same<value_type, | 
				
			||||||
 | 
					        typename BasicJsonType::array_t::value_type>::value || | 
				
			||||||
 | 
					        has_from_json<BasicJsonType, | 
				
			||||||
 | 
					        value_type>::value || | 
				
			||||||
 | 
					        has_non_default_from_json < | 
				
			||||||
 | 
					        BasicJsonType, | 
				
			||||||
 | 
					        value_type >::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename ConstructibleArrayType> | 
				
			||||||
 | 
					struct is_constructible_array_type | 
				
			||||||
 | 
					    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RealIntegerType, typename CompatibleNumberIntegerType, | 
				
			||||||
 | 
					         typename = void> | 
				
			||||||
 | 
					struct is_compatible_integer_type_impl : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RealIntegerType, typename CompatibleNumberIntegerType> | 
				
			||||||
 | 
					struct is_compatible_integer_type_impl < | 
				
			||||||
 | 
					    RealIntegerType, CompatibleNumberIntegerType, | 
				
			||||||
 | 
					    enable_if_t < std::is_integral<RealIntegerType>::value&& | 
				
			||||||
 | 
					    std::is_integral<CompatibleNumberIntegerType>::value&& | 
				
			||||||
 | 
					    !std::is_same<bool, CompatibleNumberIntegerType>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // is there an assert somewhere on overflows?
 | 
				
			||||||
 | 
					    using RealLimits = std::numeric_limits<RealIntegerType>; | 
				
			||||||
 | 
					    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static constexpr auto value = | 
				
			||||||
 | 
					        is_constructible<RealIntegerType, | 
				
			||||||
 | 
					        CompatibleNumberIntegerType>::value && | 
				
			||||||
 | 
					        CompatibleLimits::is_integer && | 
				
			||||||
 | 
					        RealLimits::is_signed == CompatibleLimits::is_signed; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename RealIntegerType, typename CompatibleNumberIntegerType> | 
				
			||||||
 | 
					struct is_compatible_integer_type | 
				
			||||||
 | 
					    : is_compatible_integer_type_impl<RealIntegerType, | 
				
			||||||
 | 
					      CompatibleNumberIntegerType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleType, typename = void> | 
				
			||||||
 | 
					struct is_compatible_type_impl: std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleType> | 
				
			||||||
 | 
					struct is_compatible_type_impl < | 
				
			||||||
 | 
					    BasicJsonType, CompatibleType, | 
				
			||||||
 | 
					    enable_if_t<is_complete_type<CompatibleType>::value >> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool value = | 
				
			||||||
 | 
					        has_to_json<BasicJsonType, CompatibleType>::value; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename CompatibleType> | 
				
			||||||
 | 
					struct is_compatible_type | 
				
			||||||
 | 
					    : is_compatible_type_impl<BasicJsonType, CompatibleType> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T1, typename T2> | 
				
			||||||
 | 
					struct is_constructible_tuple : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T1, typename... Args> | 
				
			||||||
 | 
					struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename T> | 
				
			||||||
 | 
					struct is_json_iterator_of : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type | 
				
			||||||
 | 
					{}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// checks if a given type T is a template specialization of Primary
 | 
				
			||||||
 | 
					template<template <typename...> class Primary, typename T> | 
				
			||||||
 | 
					struct is_specialization_of : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<template <typename...> class Primary, typename... Args> | 
				
			||||||
 | 
					struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// checks if A and B are comparable using Compare functor
 | 
				
			||||||
 | 
					template<typename Compare, typename A, typename B, typename = void> | 
				
			||||||
 | 
					struct is_comparable : std::false_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Compare, typename A, typename B> | 
				
			||||||
 | 
					struct is_comparable<Compare, A, B, void_t< | 
				
			||||||
 | 
					decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())), | 
				
			||||||
 | 
					decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>())) | 
				
			||||||
 | 
					>> : std::true_type {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using detect_is_transparent = typename T::is_transparent; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// type trait to check if KeyType can be used as object key (without a BasicJsonType)
 | 
				
			||||||
 | 
					// see is_usable_as_basic_json_key_type below
 | 
				
			||||||
 | 
					template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true, | 
				
			||||||
 | 
					         bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>> | 
				
			||||||
 | 
					using is_usable_as_key_type = typename std::conditional < | 
				
			||||||
 | 
					                              is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value | 
				
			||||||
 | 
					                              && !(ExcludeObjectKeyType && std::is_same<KeyType, | 
				
			||||||
 | 
					                                   ObjectKeyType>::value) | 
				
			||||||
 | 
					                              && (!RequireTransparentComparator | 
				
			||||||
 | 
					                                  || is_detected <detect_is_transparent, Comparator>::value) | 
				
			||||||
 | 
					                              && !is_json_pointer<KeyType>::value, | 
				
			||||||
 | 
					                              std::true_type, | 
				
			||||||
 | 
					                              std::false_type >::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// type trait to check if KeyType can be used as object key
 | 
				
			||||||
 | 
					// true if:
 | 
				
			||||||
 | 
					//   - KeyType is comparable with BasicJsonType::object_t::key_type
 | 
				
			||||||
 | 
					//   - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
 | 
				
			||||||
 | 
					//   - the comparator is transparent or RequireTransparentComparator is false
 | 
				
			||||||
 | 
					//   - KeyType is not a JSON iterator or json_pointer
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true, | 
				
			||||||
 | 
					         bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>> | 
				
			||||||
 | 
					using is_usable_as_basic_json_key_type = typename std::conditional < | 
				
			||||||
 | 
					        is_usable_as_key_type<typename BasicJsonType::object_comparator_t, | 
				
			||||||
 | 
					        typename BasicJsonType::object_t::key_type, KeyTypeCVRef, | 
				
			||||||
 | 
					        RequireTransparentComparator, ExcludeObjectKeyType>::value | 
				
			||||||
 | 
					        && !is_json_iterator_of<BasicJsonType, KeyType>::value, | 
				
			||||||
 | 
					        std::true_type, | 
				
			||||||
 | 
					        std::false_type >::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename ObjectType, typename KeyType> | 
				
			||||||
 | 
					using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// type trait to check if object_t has an erase() member functions accepting KeyType
 | 
				
			||||||
 | 
					template<typename BasicJsonType, typename KeyType> | 
				
			||||||
 | 
					using has_erase_with_key_type = typename std::conditional < | 
				
			||||||
 | 
					                                is_detected < | 
				
			||||||
 | 
					                                detect_erase_with_key_type, | 
				
			||||||
 | 
					                                typename BasicJsonType::object_t, KeyType >::value, | 
				
			||||||
 | 
					                                std::true_type, | 
				
			||||||
 | 
					                                std::false_type >::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// a naive helper to check if a type is an ordered_map (exploits the fact that
 | 
				
			||||||
 | 
					// ordered_map inherits capacity() from std::vector)
 | 
				
			||||||
 | 
					template <typename T> | 
				
			||||||
 | 
					struct is_ordered_map | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using one = char; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct two | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
 | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename C> static one test( decltype(&C::capacity) ) ; | 
				
			||||||
 | 
					    template <typename C> static two test(...); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
 | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
 | 
				
			||||||
 | 
					template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 > | 
				
			||||||
 | 
					T conditional_static_cast(U value) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return static_cast<T>(value); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0> | 
				
			||||||
 | 
					T conditional_static_cast(U value) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return value; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Types> | 
				
			||||||
 | 
					using all_integral = conjunction<std::is_integral<Types>...>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Types> | 
				
			||||||
 | 
					using all_signed = conjunction<std::is_signed<Types>...>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Types> | 
				
			||||||
 | 
					using all_unsigned = conjunction<std::is_unsigned<Types>...>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// there's a disjunction trait in another PR; replace when merged
 | 
				
			||||||
 | 
					template<typename... Types> | 
				
			||||||
 | 
					using same_sign = std::integral_constant < bool, | 
				
			||||||
 | 
					      all_signed<Types...>::value || all_unsigned<Types...>::value >; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					using never_out_of_range = std::integral_constant < bool, | 
				
			||||||
 | 
					      (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType))) | 
				
			||||||
 | 
					      || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T, | 
				
			||||||
 | 
					         bool OfTypeSigned = std::is_signed<OfType>::value, | 
				
			||||||
 | 
					         bool TSigned = std::is_signed<T>::value> | 
				
			||||||
 | 
					struct value_in_range_of_impl2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl2<OfType, T, false, false> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using CommonType = typename std::common_type<OfType, T>::type; | 
				
			||||||
 | 
					        return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl2<OfType, T, true, false> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using CommonType = typename std::common_type<OfType, T>::type; | 
				
			||||||
 | 
					        return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl2<OfType, T, false, true> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using CommonType = typename std::common_type<OfType, T>::type; | 
				
			||||||
 | 
					        return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl2<OfType, T, true, true> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        using CommonType = typename std::common_type<OfType, T>::type; | 
				
			||||||
 | 
					        return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)()) | 
				
			||||||
 | 
					               && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T, | 
				
			||||||
 | 
					         bool NeverOutOfRange = never_out_of_range<OfType, T>::value, | 
				
			||||||
 | 
					         typename = detail::enable_if_t<all_integral<OfType, T>::value>> | 
				
			||||||
 | 
					struct value_in_range_of_impl1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl1<OfType, T, false> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T val) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return value_in_range_of_impl2<OfType, T>::test(val); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					struct value_in_range_of_impl1<OfType, T, true> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr bool test(T /*val*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return true; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OfType, typename T> | 
				
			||||||
 | 
					inline constexpr bool value_in_range_of(T val) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return value_in_range_of_impl1<OfType, T>::test(val); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<bool Value> | 
				
			||||||
 | 
					using bool_constant = std::integral_constant<bool, Value>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// is_c_string
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace impl | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					inline constexpr bool is_c_string() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using TUnExt = typename std::remove_extent<T>::type; | 
				
			||||||
 | 
					    using TUnCVExt = typename std::remove_cv<TUnExt>::type; | 
				
			||||||
 | 
					    using TUnPtr = typename std::remove_pointer<T>::type; | 
				
			||||||
 | 
					    using TUnCVPtr = typename std::remove_cv<TUnPtr>::type; | 
				
			||||||
 | 
					    return | 
				
			||||||
 | 
					        (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value) | 
				
			||||||
 | 
					        || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace impl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// checks whether T is a [cv] char */[cv] char[] C string
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_c_string : bool_constant<impl::is_c_string<T>()> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					using is_c_string_uncvref = is_c_string<uncvref_t<T>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// is_transparent
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace impl | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					inline constexpr bool is_transparent() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return is_detected<detect_is_transparent, T>::value; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace impl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// checks whether T has a member named is_transparent
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					struct is_transparent : bool_constant<impl::is_transparent<T>()> {}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,24 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename ...Ts> struct make_void | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using type = void; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					template<typename ...Ts> using void_t = typename make_void<Ts...>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,147 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm> // copy | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <iterator> // back_inserter | 
				
			||||||
 | 
					#include <memory> // shared_ptr, make_shared | 
				
			||||||
 | 
					#include <string> // basic_string | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					    #include <ios>      // streamsize | 
				
			||||||
 | 
					    #include <ostream>  // basic_ostream | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// abstract output adapter interface
 | 
				
			||||||
 | 
					template<typename CharType> struct output_adapter_protocol | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    virtual void write_character(CharType c) = 0; | 
				
			||||||
 | 
					    virtual void write_characters(const CharType* s, std::size_t length) = 0; | 
				
			||||||
 | 
					    virtual ~output_adapter_protocol() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    output_adapter_protocol() = default; | 
				
			||||||
 | 
					    output_adapter_protocol(const output_adapter_protocol&) = default; | 
				
			||||||
 | 
					    output_adapter_protocol(output_adapter_protocol&&) noexcept = default; | 
				
			||||||
 | 
					    output_adapter_protocol& operator=(const output_adapter_protocol&) = default; | 
				
			||||||
 | 
					    output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// a type to simplify interfaces
 | 
				
			||||||
 | 
					template<typename CharType> | 
				
			||||||
 | 
					using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// output adapter for byte vectors
 | 
				
			||||||
 | 
					template<typename CharType, typename AllocatorType = std::allocator<CharType>> | 
				
			||||||
 | 
					class output_vector_adapter : public output_adapter_protocol<CharType> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept | 
				
			||||||
 | 
					        : v(vec) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_character(CharType c) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        v.push_back(c); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    void write_characters(const CharType* s, std::size_t length) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        v.insert(v.end(), s, s + length); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    std::vector<CharType, AllocatorType>& v; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					/// output adapter for output streams
 | 
				
			||||||
 | 
					template<typename CharType> | 
				
			||||||
 | 
					class output_stream_adapter : public output_adapter_protocol<CharType> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept | 
				
			||||||
 | 
					        : stream(s) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_character(CharType c) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        stream.put(c); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    void write_characters(const CharType* s, std::size_t length) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        stream.write(s, static_cast<std::streamsize>(length)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    std::basic_ostream<CharType>& stream; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// output adapter for basic_string
 | 
				
			||||||
 | 
					template<typename CharType, typename StringType = std::basic_string<CharType>> | 
				
			||||||
 | 
					class output_string_adapter : public output_adapter_protocol<CharType> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    explicit output_string_adapter(StringType& s) noexcept | 
				
			||||||
 | 
					        : str(s) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_character(CharType c) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        str.push_back(c); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JSON_HEDLEY_NON_NULL(2) | 
				
			||||||
 | 
					    void write_characters(const CharType* s, std::size_t length) override | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        str.append(s, length); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    StringType& str; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename CharType, typename StringType = std::basic_string<CharType>> | 
				
			||||||
 | 
					class output_adapter | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    template<typename AllocatorType = std::allocator<CharType>> | 
				
			||||||
 | 
					    output_adapter(std::vector<CharType, AllocatorType>& vec) | 
				
			||||||
 | 
					        : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_NO_IO | 
				
			||||||
 | 
					    output_adapter(std::basic_ostream<CharType>& s) | 
				
			||||||
 | 
					        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} | 
				
			||||||
 | 
					#endif  // JSON_NO_IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    output_adapter(StringType& s) | 
				
			||||||
 | 
					        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operator output_adapter_t<CharType>() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return oa; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    output_adapter_t<CharType> oa = nullptr; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,988 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm> // reverse, remove, fill, find, none_of | 
				
			||||||
 | 
					#include <array> // array | 
				
			||||||
 | 
					#include <clocale> // localeconv, lconv | 
				
			||||||
 | 
					#include <cmath> // labs, isfinite, isnan, signbit | 
				
			||||||
 | 
					#include <cstddef> // size_t, ptrdiff_t | 
				
			||||||
 | 
					#include <cstdint> // uint8_t | 
				
			||||||
 | 
					#include <cstdio> // snprintf | 
				
			||||||
 | 
					#include <limits> // numeric_limits | 
				
			||||||
 | 
					#include <string> // string, char_traits | 
				
			||||||
 | 
					#include <iomanip> // setfill, setw | 
				
			||||||
 | 
					#include <type_traits> // is_same | 
				
			||||||
 | 
					#include <utility> // move | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/conversions/to_chars.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/exceptions.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/output/binary_writer.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/output/output_adapters.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/string_concat.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/value_t.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////
 | 
				
			||||||
 | 
					// serialization //
 | 
				
			||||||
 | 
					///////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// how to treat decoding errors
 | 
				
			||||||
 | 
					enum class error_handler_t | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    strict,  ///< throw a type_error exception in case of invalid UTF-8
 | 
				
			||||||
 | 
					    replace, ///< replace invalid UTF-8 sequences with U+FFFD
 | 
				
			||||||
 | 
					    ignore   ///< ignore invalid UTF-8 sequences
 | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename BasicJsonType> | 
				
			||||||
 | 
					class serializer | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using string_t = typename BasicJsonType::string_t; | 
				
			||||||
 | 
					    using number_float_t = typename BasicJsonType::number_float_t; | 
				
			||||||
 | 
					    using number_integer_t = typename BasicJsonType::number_integer_t; | 
				
			||||||
 | 
					    using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | 
				
			||||||
 | 
					    using binary_char_t = typename BasicJsonType::binary_t::value_type; | 
				
			||||||
 | 
					    static constexpr std::uint8_t UTF8_ACCEPT = 0; | 
				
			||||||
 | 
					    static constexpr std::uint8_t UTF8_REJECT = 1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @param[in] s  output stream to serialize to | 
				
			||||||
 | 
					    @param[in] ichar  indentation character to use | 
				
			||||||
 | 
					    @param[in] error_handler_  how to react on decoding errors | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    serializer(output_adapter_t<char> s, const char ichar, | 
				
			||||||
 | 
					               error_handler_t error_handler_ = error_handler_t::strict) | 
				
			||||||
 | 
					        : o(std::move(s)) | 
				
			||||||
 | 
					        , loc(std::localeconv()) | 
				
			||||||
 | 
					        , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep))) | 
				
			||||||
 | 
					        , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point))) | 
				
			||||||
 | 
					        , indent_char(ichar) | 
				
			||||||
 | 
					        , indent_string(512, indent_char) | 
				
			||||||
 | 
					        , error_handler(error_handler_) | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // delete because of pointer members
 | 
				
			||||||
 | 
					    serializer(const serializer&) = delete; | 
				
			||||||
 | 
					    serializer& operator=(const serializer&) = delete; | 
				
			||||||
 | 
					    serializer(serializer&&) = delete; | 
				
			||||||
 | 
					    serializer& operator=(serializer&&) = delete; | 
				
			||||||
 | 
					    ~serializer() = default; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief internal implementation of the serialization function | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This function is called by the public member function dump and organizes | 
				
			||||||
 | 
					    the serialization internally. The indentation level is propagated as | 
				
			||||||
 | 
					    additional parameter. In case of arrays and objects, the function is | 
				
			||||||
 | 
					    called recursively. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - strings and object keys are escaped using `escape_string()` | 
				
			||||||
 | 
					    - integer numbers are converted implicitly via `operator<<` | 
				
			||||||
 | 
					    - floating-point numbers are converted to a string using `"%g"` format | 
				
			||||||
 | 
					    - binary values are serialized as objects containing the subtype and the | 
				
			||||||
 | 
					      byte array | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] val               value to serialize | 
				
			||||||
 | 
					    @param[in] pretty_print      whether the output shall be pretty-printed | 
				
			||||||
 | 
					    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters | 
				
			||||||
 | 
					    in the output are escaped with `\uXXXX` sequences, and the result consists | 
				
			||||||
 | 
					    of ASCII characters only. | 
				
			||||||
 | 
					    @param[in] indent_step       the indent level | 
				
			||||||
 | 
					    @param[in] current_indent    the current indent level (only used internally) | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void dump(const BasicJsonType& val, | 
				
			||||||
 | 
					              const bool pretty_print, | 
				
			||||||
 | 
					              const bool ensure_ascii, | 
				
			||||||
 | 
					              const unsigned int indent_step, | 
				
			||||||
 | 
					              const unsigned int current_indent = 0) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        switch (val.m_type) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            case value_t::object: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (val.m_value.object->empty()) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("{}", 2); | 
				
			||||||
 | 
					                    return; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (pretty_print) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("{\n", 2); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // variable to hold indentation for recursive calls
 | 
				
			||||||
 | 
					                    const auto new_indent = current_indent + indent_step; | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        indent_string.resize(indent_string.size() * 2, ' '); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // first n-1 elements
 | 
				
			||||||
 | 
					                    auto i = val.m_value.object->cbegin(); | 
				
			||||||
 | 
					                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					                        o->write_character('\"'); | 
				
			||||||
 | 
					                        dump_escaped(i->first, ensure_ascii); | 
				
			||||||
 | 
					                        o->write_characters("\": ", 3); | 
				
			||||||
 | 
					                        dump(i->second, true, ensure_ascii, indent_step, new_indent); | 
				
			||||||
 | 
					                        o->write_characters(",\n", 2); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // last element
 | 
				
			||||||
 | 
					                    JSON_ASSERT(i != val.m_value.object->cend()); | 
				
			||||||
 | 
					                    JSON_ASSERT(std::next(i) == val.m_value.object->cend()); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					                    o->write_character('\"'); | 
				
			||||||
 | 
					                    dump_escaped(i->first, ensure_ascii); | 
				
			||||||
 | 
					                    o->write_characters("\": ", 3); | 
				
			||||||
 | 
					                    dump(i->second, true, ensure_ascii, indent_step, new_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_character('\n'); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), current_indent); | 
				
			||||||
 | 
					                    o->write_character('}'); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_character('{'); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // first n-1 elements
 | 
				
			||||||
 | 
					                    auto i = val.m_value.object->cbegin(); | 
				
			||||||
 | 
					                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_character('\"'); | 
				
			||||||
 | 
					                        dump_escaped(i->first, ensure_ascii); | 
				
			||||||
 | 
					                        o->write_characters("\":", 2); | 
				
			||||||
 | 
					                        dump(i->second, false, ensure_ascii, indent_step, current_indent); | 
				
			||||||
 | 
					                        o->write_character(','); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // last element
 | 
				
			||||||
 | 
					                    JSON_ASSERT(i != val.m_value.object->cend()); | 
				
			||||||
 | 
					                    JSON_ASSERT(std::next(i) == val.m_value.object->cend()); | 
				
			||||||
 | 
					                    o->write_character('\"'); | 
				
			||||||
 | 
					                    dump_escaped(i->first, ensure_ascii); | 
				
			||||||
 | 
					                    o->write_characters("\":", 2); | 
				
			||||||
 | 
					                    dump(i->second, false, ensure_ascii, indent_step, current_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_character('}'); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::array: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (val.m_value.array->empty()) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("[]", 2); | 
				
			||||||
 | 
					                    return; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (pretty_print) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("[\n", 2); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // variable to hold indentation for recursive calls
 | 
				
			||||||
 | 
					                    const auto new_indent = current_indent + indent_step; | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        indent_string.resize(indent_string.size() * 2, ' '); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // first n-1 elements
 | 
				
			||||||
 | 
					                    for (auto i = val.m_value.array->cbegin(); | 
				
			||||||
 | 
					                            i != val.m_value.array->cend() - 1; ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					                        dump(*i, true, ensure_ascii, indent_step, new_indent); | 
				
			||||||
 | 
					                        o->write_characters(",\n", 2); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // last element
 | 
				
			||||||
 | 
					                    JSON_ASSERT(!val.m_value.array->empty()); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_character('\n'); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), current_indent); | 
				
			||||||
 | 
					                    o->write_character(']'); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_character('['); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // first n-1 elements
 | 
				
			||||||
 | 
					                    for (auto i = val.m_value.array->cbegin(); | 
				
			||||||
 | 
					                            i != val.m_value.array->cend() - 1; ++i) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        dump(*i, false, ensure_ascii, indent_step, current_indent); | 
				
			||||||
 | 
					                        o->write_character(','); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // last element
 | 
				
			||||||
 | 
					                    JSON_ASSERT(!val.m_value.array->empty()); | 
				
			||||||
 | 
					                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_character(']'); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::string: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                o->write_character('\"'); | 
				
			||||||
 | 
					                dump_escaped(*val.m_value.string, ensure_ascii); | 
				
			||||||
 | 
					                o->write_character('\"'); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::binary: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (pretty_print) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("{\n", 2); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // variable to hold indentation for recursive calls
 | 
				
			||||||
 | 
					                    const auto new_indent = current_indent + indent_step; | 
				
			||||||
 | 
					                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        indent_string.resize(indent_string.size() * 2, ' '); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_characters("\"bytes\": [", 10); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (!val.m_value.binary->empty()) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        for (auto i = val.m_value.binary->cbegin(); | 
				
			||||||
 | 
					                                i != val.m_value.binary->cend() - 1; ++i) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            dump_integer(*i); | 
				
			||||||
 | 
					                            o->write_characters(", ", 2); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        dump_integer(val.m_value.binary->back()); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_characters("],\n", 3); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), new_indent); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_characters("\"subtype\": ", 11); | 
				
			||||||
 | 
					                    if (val.m_value.binary->has_subtype()) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        dump_integer(val.m_value.binary->subtype()); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    else | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters("null", 4); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    o->write_character('\n'); | 
				
			||||||
 | 
					                    o->write_characters(indent_string.c_str(), current_indent); | 
				
			||||||
 | 
					                    o->write_character('}'); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("{\"bytes\":[", 10); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (!val.m_value.binary->empty()) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        for (auto i = val.m_value.binary->cbegin(); | 
				
			||||||
 | 
					                                i != val.m_value.binary->cend() - 1; ++i) | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            dump_integer(*i); | 
				
			||||||
 | 
					                            o->write_character(','); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                        dump_integer(val.m_value.binary->back()); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    o->write_characters("],\"subtype\":", 12); | 
				
			||||||
 | 
					                    if (val.m_value.binary->has_subtype()) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        dump_integer(val.m_value.binary->subtype()); | 
				
			||||||
 | 
					                        o->write_character('}'); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    else | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters("null}", 5); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::boolean: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                if (val.m_value.boolean) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("true", 4); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                else | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    o->write_characters("false", 5); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::number_integer: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                dump_integer(val.m_value.number_integer); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::number_unsigned: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                dump_integer(val.m_value.number_unsigned); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::number_float: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                dump_float(val.m_value.number_float); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::discarded: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                o->write_characters("<discarded>", 11); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case value_t::null: | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                o->write_characters("null", 4); | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            default:            // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  JSON_PRIVATE_UNLESS_TESTED: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief dump escaped string | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Escape a string by replacing certain special characters by a sequence of an | 
				
			||||||
 | 
					    escape character (backslash) and another character and other control | 
				
			||||||
 | 
					    characters by a sequence of "\u" followed by a four-digit hex | 
				
			||||||
 | 
					    representation. The escaped string is written to output stream @a o. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] s  the string to escape | 
				
			||||||
 | 
					    @param[in] ensure_ascii  whether to escape non-ASCII characters with | 
				
			||||||
 | 
					                             \uXXXX sequences | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @complexity Linear in the length of string @a s. | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void dump_escaped(const string_t& s, const bool ensure_ascii) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::uint32_t codepoint{}; | 
				
			||||||
 | 
					        std::uint8_t state = UTF8_ACCEPT; | 
				
			||||||
 | 
					        std::size_t bytes = 0;  // number of bytes written to string_buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // number of bytes written at the point of the last valid byte
 | 
				
			||||||
 | 
					        std::size_t bytes_after_last_accept = 0; | 
				
			||||||
 | 
					        std::size_t undumped_chars = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (std::size_t i = 0; i < s.size(); ++i) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto byte = static_cast<std::uint8_t>(s[i]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (decode(state, codepoint, byte)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case UTF8_ACCEPT:  // decode found a new code point
 | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    switch (codepoint) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        case 0x08: // backspace
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = 'b'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x09: // horizontal tab
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = 't'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x0A: // newline
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = 'n'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x0C: // formfeed
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = 'f'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x0D: // carriage return
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = 'r'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x22: // quotation mark
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\"'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case 0x5C: // reverse solidus
 | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        default: | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            // escape control characters (0x00..0x1F) or, if
 | 
				
			||||||
 | 
					                            // ensure_ascii parameter is used, non-ASCII characters
 | 
				
			||||||
 | 
					                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F))) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                if (codepoint <= 0xFFFF) | 
				
			||||||
 | 
					                                { | 
				
			||||||
 | 
					                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
 | 
				
			||||||
 | 
					                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", | 
				
			||||||
 | 
					                                                                      static_cast<std::uint16_t>(codepoint))); | 
				
			||||||
 | 
					                                    bytes += 6; | 
				
			||||||
 | 
					                                } | 
				
			||||||
 | 
					                                else | 
				
			||||||
 | 
					                                { | 
				
			||||||
 | 
					                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
 | 
				
			||||||
 | 
					                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", | 
				
			||||||
 | 
					                                                                      static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)), | 
				
			||||||
 | 
					                                                                      static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)))); | 
				
			||||||
 | 
					                                    bytes += 12; | 
				
			||||||
 | 
					                                } | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					                            else | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                // copy byte to buffer (all previous bytes
 | 
				
			||||||
 | 
					                                // been copied have in default case above)
 | 
				
			||||||
 | 
					                                string_buffer[bytes++] = s[i]; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // write buffer and reset index; there must be 13 bytes
 | 
				
			||||||
 | 
					                    // left, as this is the maximal number of bytes to be
 | 
				
			||||||
 | 
					                    // written ("\uxxxx\uxxxx\0") for one code point
 | 
				
			||||||
 | 
					                    if (string_buffer.size() - bytes < 13) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters(string_buffer.data(), bytes); | 
				
			||||||
 | 
					                        bytes = 0; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // remember the byte position of this accept
 | 
				
			||||||
 | 
					                    bytes_after_last_accept = bytes; | 
				
			||||||
 | 
					                    undumped_chars = 0; | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case UTF8_REJECT:  // decode found invalid UTF-8 byte
 | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    switch (error_handler) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        case error_handler_t::strict: | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr)); | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case error_handler_t::ignore: | 
				
			||||||
 | 
					                        case error_handler_t::replace: | 
				
			||||||
 | 
					                        { | 
				
			||||||
 | 
					                            // in case we saw this character the first time, we
 | 
				
			||||||
 | 
					                            // would like to read it again, because the byte
 | 
				
			||||||
 | 
					                            // may be OK for itself, but just not OK for the
 | 
				
			||||||
 | 
					                            // previous sequence
 | 
				
			||||||
 | 
					                            if (undumped_chars > 0) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                --i; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            // reset length buffer to the last accepted index;
 | 
				
			||||||
 | 
					                            // thus removing/ignoring the invalid characters
 | 
				
			||||||
 | 
					                            bytes = bytes_after_last_accept; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if (error_handler == error_handler_t::replace) | 
				
			||||||
 | 
					                            { | 
				
			||||||
 | 
					                                // add a replacement character
 | 
				
			||||||
 | 
					                                if (ensure_ascii) | 
				
			||||||
 | 
					                                { | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = '\\'; | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = 'u'; | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = 'f'; | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = 'f'; | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = 'f'; | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = 'd'; | 
				
			||||||
 | 
					                                } | 
				
			||||||
 | 
					                                else | 
				
			||||||
 | 
					                                { | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF'); | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF'); | 
				
			||||||
 | 
					                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD'); | 
				
			||||||
 | 
					                                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                // write buffer and reset index; there must be 13 bytes
 | 
				
			||||||
 | 
					                                // left, as this is the maximal number of bytes to be
 | 
				
			||||||
 | 
					                                // written ("\uxxxx\uxxxx\0") for one code point
 | 
				
			||||||
 | 
					                                if (string_buffer.size() - bytes < 13) | 
				
			||||||
 | 
					                                { | 
				
			||||||
 | 
					                                    o->write_characters(string_buffer.data(), bytes); | 
				
			||||||
 | 
					                                    bytes = 0; | 
				
			||||||
 | 
					                                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                bytes_after_last_accept = bytes; | 
				
			||||||
 | 
					                            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            undumped_chars = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            // continue processing the string
 | 
				
			||||||
 | 
					                            state = UTF8_ACCEPT; | 
				
			||||||
 | 
					                            break; | 
				
			||||||
 | 
					                        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        default:            // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                default:  // decode found yet incomplete multi-byte code point
 | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    if (!ensure_ascii) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        // code point will not be escaped - copy byte to buffer
 | 
				
			||||||
 | 
					                        string_buffer[bytes++] = s[i]; | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    ++undumped_chars; | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we finished processing the string
 | 
				
			||||||
 | 
					        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // write buffer
 | 
				
			||||||
 | 
					            if (bytes > 0) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                o->write_characters(string_buffer.data(), bytes); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // we finish reading, but do not accept: string was incomplete
 | 
				
			||||||
 | 
					            switch (error_handler) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                case error_handler_t::strict: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr)); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case error_handler_t::ignore: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // write all accepted bytes
 | 
				
			||||||
 | 
					                    o->write_characters(string_buffer.data(), bytes_after_last_accept); | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case error_handler_t::replace: | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    // write all accepted bytes
 | 
				
			||||||
 | 
					                    o->write_characters(string_buffer.data(), bytes_after_last_accept); | 
				
			||||||
 | 
					                    // add a replacement character
 | 
				
			||||||
 | 
					                    if (ensure_ascii) | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters("\\ufffd", 6); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    else | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                        o->write_characters("\xEF\xBF\xBD", 3); | 
				
			||||||
 | 
					                    } | 
				
			||||||
 | 
					                    break; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                default:            // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief count digits | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Count the number of decimal (base 10) digits for an input unsigned integer. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] x  unsigned integer number to count its digits | 
				
			||||||
 | 
					    @return    number of decimal digits | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    inline unsigned int count_digits(number_unsigned_t x) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        unsigned int n_digits = 1; | 
				
			||||||
 | 
					        for (;;) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (x < 10) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return n_digits; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            if (x < 100) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return n_digits + 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            if (x < 1000) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return n_digits + 2; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            if (x < 10000) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return n_digits + 3; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            x = x / 10000u; | 
				
			||||||
 | 
					            n_digits += 4; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					     * @brief convert a byte to a uppercase hex representation | 
				
			||||||
 | 
					     * @param[in] byte byte to represent | 
				
			||||||
 | 
					     * @return representation ("00".."FF") | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    static std::string hex_bytes(std::uint8_t byte) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        std::string result = "FF"; | 
				
			||||||
 | 
					        constexpr const char* nibble_to_hex = "0123456789ABCDEF"; | 
				
			||||||
 | 
					        result[0] = nibble_to_hex[byte / 16]; | 
				
			||||||
 | 
					        result[1] = nibble_to_hex[byte % 16]; | 
				
			||||||
 | 
					        return result; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // templates to avoid warnings about useless casts
 | 
				
			||||||
 | 
					    template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0> | 
				
			||||||
 | 
					    bool is_negative_number(NumberType x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return x < 0; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 > | 
				
			||||||
 | 
					    bool is_negative_number(NumberType /*unused*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief dump an integer | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dump a given integer to output stream @a o. Works internally with | 
				
			||||||
 | 
					    @a number_buffer. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] x  integer number (signed or unsigned) to dump | 
				
			||||||
 | 
					    @tparam NumberType either @a number_integer_t or @a number_unsigned_t | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    template < typename NumberType, detail::enable_if_t < | 
				
			||||||
 | 
					                   std::is_integral<NumberType>::value || | 
				
			||||||
 | 
					                   std::is_same<NumberType, number_unsigned_t>::value || | 
				
			||||||
 | 
					                   std::is_same<NumberType, number_integer_t>::value || | 
				
			||||||
 | 
					                   std::is_same<NumberType, binary_char_t>::value, | 
				
			||||||
 | 
					                   int > = 0 > | 
				
			||||||
 | 
					    void dump_integer(NumberType x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        static constexpr std::array<std::array<char, 2>, 100> digits_to_99 | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}}, | 
				
			||||||
 | 
					                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}}, | 
				
			||||||
 | 
					                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}}, | 
				
			||||||
 | 
					                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}}, | 
				
			||||||
 | 
					                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}}, | 
				
			||||||
 | 
					                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}}, | 
				
			||||||
 | 
					                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}}, | 
				
			||||||
 | 
					                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}}, | 
				
			||||||
 | 
					                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}}, | 
				
			||||||
 | 
					                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}}, | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // special case for "0"
 | 
				
			||||||
 | 
					        if (x == 0) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            o->write_character('0'); | 
				
			||||||
 | 
					            return; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // use a pointer to fill the buffer
 | 
				
			||||||
 | 
					        auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        number_unsigned_t abs_value; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        unsigned int n_chars{}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (is_negative_number(x)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            *buffer_ptr = '-'; | 
				
			||||||
 | 
					            abs_value = remove_sign(static_cast<number_integer_t>(x)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // account one more byte for the minus sign
 | 
				
			||||||
 | 
					            n_chars = 1 + count_digits(abs_value); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            abs_value = static_cast<number_unsigned_t>(x); | 
				
			||||||
 | 
					            n_chars = count_digits(abs_value); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // spare 1 byte for '\0'
 | 
				
			||||||
 | 
					        JSON_ASSERT(n_chars < number_buffer.size() - 1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // jump to the end to generate the string from backward,
 | 
				
			||||||
 | 
					        // so we later avoid reversing the result
 | 
				
			||||||
 | 
					        buffer_ptr += n_chars; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
 | 
				
			||||||
 | 
					        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
 | 
				
			||||||
 | 
					        while (abs_value >= 100) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto digits_index = static_cast<unsigned>((abs_value % 100)); | 
				
			||||||
 | 
					            abs_value /= 100; | 
				
			||||||
 | 
					            *(--buffer_ptr) = digits_to_99[digits_index][1]; | 
				
			||||||
 | 
					            *(--buffer_ptr) = digits_to_99[digits_index][0]; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (abs_value >= 10) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            const auto digits_index = static_cast<unsigned>(abs_value); | 
				
			||||||
 | 
					            *(--buffer_ptr) = digits_to_99[digits_index][1]; | 
				
			||||||
 | 
					            *(--buffer_ptr) = digits_to_99[digits_index][0]; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        else | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            *(--buffer_ptr) = static_cast<char>('0' + abs_value); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        o->write_characters(number_buffer.data(), n_chars); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief dump a floating-point number | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dump a given floating-point number to output stream @a o. Works internally | 
				
			||||||
 | 
					    with @a number_buffer. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in] x  floating-point number to dump | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    void dump_float(number_float_t x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // NaN / inf
 | 
				
			||||||
 | 
					        if (!std::isfinite(x)) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            o->write_characters("null", 4); | 
				
			||||||
 | 
					            return; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If number_float_t is an IEEE-754 single or double precision number,
 | 
				
			||||||
 | 
					        // use the Grisu2 algorithm to produce short numbers which are
 | 
				
			||||||
 | 
					        // guaranteed to round-trip, using strtof and strtod, resp.
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // NB: The test below works if <long double> == <double>.
 | 
				
			||||||
 | 
					        static constexpr bool is_ieee_single_or_double | 
				
			||||||
 | 
					            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) || | 
				
			||||||
 | 
					              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>()); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        auto* begin = number_buffer.data(); | 
				
			||||||
 | 
					        auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        o->write_characters(begin, static_cast<size_t>(end - begin)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        // get number of digits for a float -> text -> float round-trip
 | 
				
			||||||
 | 
					        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // the actual conversion
 | 
				
			||||||
 | 
					        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
 | 
				
			||||||
 | 
					        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // negative value indicates an error
 | 
				
			||||||
 | 
					        JSON_ASSERT(len > 0); | 
				
			||||||
 | 
					        // check if buffer was large enough
 | 
				
			||||||
 | 
					        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // erase thousands separator
 | 
				
			||||||
 | 
					        if (thousands_sep != '\0') | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
 | 
				
			||||||
 | 
					            const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep); | 
				
			||||||
 | 
					            std::fill(end, number_buffer.end(), '\0'); | 
				
			||||||
 | 
					            JSON_ASSERT((end - number_buffer.begin()) <= len); | 
				
			||||||
 | 
					            len = (end - number_buffer.begin()); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // convert decimal point to '.'
 | 
				
			||||||
 | 
					        if (decimal_point != '\0' && decimal_point != '.') | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
 | 
				
			||||||
 | 
					            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point); | 
				
			||||||
 | 
					            if (dec_pos != number_buffer.end()) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                *dec_pos = '.'; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // determine if we need to append ".0"
 | 
				
			||||||
 | 
					        const bool value_is_int_like = | 
				
			||||||
 | 
					            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, | 
				
			||||||
 | 
					                         [](char c) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return c == '.' || c == 'e'; | 
				
			||||||
 | 
					        }); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (value_is_int_like) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            o->write_characters(".0", 2); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					    @brief check whether a string is UTF-8 encoded | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The function checks each byte of a string whether it is UTF-8 encoded. The | 
				
			||||||
 | 
					    result of the check is stored in the @a state parameter. The function must | 
				
			||||||
 | 
					    be called initially with state 0 (accept). State 1 means the string must | 
				
			||||||
 | 
					    be rejected, because the current byte is not allowed. If the string is | 
				
			||||||
 | 
					    completely processed, but the state is non-zero, the string ended | 
				
			||||||
 | 
					    prematurely; that is, the last byte indicated more bytes should have | 
				
			||||||
 | 
					    followed. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @param[in,out] state  the state of the decoding | 
				
			||||||
 | 
					    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT) | 
				
			||||||
 | 
					    @param[in] byte       next byte to decode | 
				
			||||||
 | 
					    @return               new state | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @note The function has been edited: a std::array is used. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> | 
				
			||||||
 | 
					    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
 | 
				
			||||||
 | 
					    */ | 
				
			||||||
 | 
					    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        static const std::array<std::uint8_t, 400> utf8d = | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
 | 
				
			||||||
 | 
					                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
 | 
				
			||||||
 | 
					                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
 | 
				
			||||||
 | 
					                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
 | 
				
			||||||
 | 
					                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
 | 
				
			||||||
 | 
					                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
 | 
				
			||||||
 | 
					                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
 | 
				
			||||||
 | 
					                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
 | 
				
			||||||
 | 
					                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
 | 
				
			||||||
 | 
					                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
 | 
				
			||||||
 | 
					                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
 | 
				
			||||||
 | 
					                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
 | 
				
			||||||
 | 
					                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
 | 
				
			||||||
 | 
					                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
 | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_ASSERT(byte < utf8d.size()); | 
				
			||||||
 | 
					        const std::uint8_t type = utf8d[byte]; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        codep = (state != UTF8_ACCEPT) | 
				
			||||||
 | 
					                ? (byte & 0x3fu) | (codep << 6u) | 
				
			||||||
 | 
					                : (0xFFu >> type) & (byte); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type); | 
				
			||||||
 | 
					        JSON_ASSERT(index < 400); | 
				
			||||||
 | 
					        state = utf8d[index]; | 
				
			||||||
 | 
					        return state; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Overload to make the compiler happy while it is instantiating | 
				
			||||||
 | 
					     * dump_integer for number_unsigned_t. | 
				
			||||||
 | 
					     * Must never be called. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    number_unsigned_t remove_sign(number_unsigned_t x) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					        return x; // LCOV_EXCL_LINE
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Helper function for dump_integer | 
				
			||||||
 | 
					     * | 
				
			||||||
 | 
					     * This function takes a negative signed integer and returns its absolute | 
				
			||||||
 | 
					     * value as unsigned integer. The plus/minus shuffling is necessary as we can | 
				
			||||||
 | 
					     * not directly remove the sign of an arbitrary signed integer as the | 
				
			||||||
 | 
					     * absolute values of INT_MIN and INT_MAX are usually not the same. See | 
				
			||||||
 | 
					     * #1708 for details. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    inline number_unsigned_t remove_sign(number_integer_t x) noexcept | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
 | 
				
			||||||
 | 
					        return static_cast<number_unsigned_t>(-(x + 1)) + 1; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private: | 
				
			||||||
 | 
					    /// the output of the serializer
 | 
				
			||||||
 | 
					    output_adapter_t<char> o = nullptr; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// a (hopefully) large enough character buffer
 | 
				
			||||||
 | 
					    std::array<char, 64> number_buffer{{}}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the locale
 | 
				
			||||||
 | 
					    const std::lconv* loc = nullptr; | 
				
			||||||
 | 
					    /// the locale's thousand separator character
 | 
				
			||||||
 | 
					    const char thousands_sep = '\0'; | 
				
			||||||
 | 
					    /// the locale's decimal point character
 | 
				
			||||||
 | 
					    const char decimal_point = '\0'; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// string buffer
 | 
				
			||||||
 | 
					    std::array<char, 512> string_buffer{{}}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// the indentation character
 | 
				
			||||||
 | 
					    const char indent_char; | 
				
			||||||
 | 
					    /// the indentation string
 | 
				
			||||||
 | 
					    string_t indent_string; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// error_handler how to react on decoding errors
 | 
				
			||||||
 | 
					    const error_handler_t error_handler; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,146 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstring> // strlen | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <utility> // forward | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/cpp_future.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/detected.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline std::size_t concat_length() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return 0; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Args> | 
				
			||||||
 | 
					inline std::size_t concat_length(const char* cstr, Args&& ... rest); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename... Args> | 
				
			||||||
 | 
					inline std::size_t concat_length(const StringType& str, Args&& ... rest); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Args> | 
				
			||||||
 | 
					inline std::size_t concat_length(const char /*c*/, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return 1 + concat_length(std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Args> | 
				
			||||||
 | 
					inline std::size_t concat_length(const char* cstr, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    // cppcheck-suppress ignoredReturnValue
 | 
				
			||||||
 | 
					    return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename... Args> | 
				
			||||||
 | 
					inline std::size_t concat_length(const StringType& str, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return str.size() + concat_length(std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OutStringType> | 
				
			||||||
 | 
					inline void concat_into(OutStringType& /*out*/) | 
				
			||||||
 | 
					{} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using detect_string_can_append = is_detected<string_can_append, StringType, Arg>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size())); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename StringType, typename Arg> | 
				
			||||||
 | 
					using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_op<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_op<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_iter<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					         enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0> | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    out.append(std::forward<Arg>(arg)); | 
				
			||||||
 | 
					    concat_into(out, std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_op<OutStringType, Arg>::value, int > > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    out += std::forward<Arg>(arg); | 
				
			||||||
 | 
					    concat_into(out, std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_op<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_iter<OutStringType, Arg>::value, int > > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    out.append(arg.begin(), arg.end()); | 
				
			||||||
 | 
					    concat_into(out, std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template < typename OutStringType, typename Arg, typename... Args, | 
				
			||||||
 | 
					           enable_if_t < !detect_string_can_append<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_op<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && !detect_string_can_append_iter<OutStringType, Arg>::value | 
				
			||||||
 | 
					                         && detect_string_can_append_data<OutStringType, Arg>::value, int > > | 
				
			||||||
 | 
					inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    out.append(arg.data(), arg.size()); | 
				
			||||||
 | 
					    concat_into(out, std::forward<Args>(rest)...); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename OutStringType = std::string, typename... Args> | 
				
			||||||
 | 
					inline OutStringType concat(Args && ... args) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    OutStringType str; | 
				
			||||||
 | 
					    str.reserve(concat_length(std::forward<Args>(args)...)); | 
				
			||||||
 | 
					    concat_into(str, std::forward<Args>(args)...); | 
				
			||||||
 | 
					    return str; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,72 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief replace all occurrences of a substring by another string | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@param[in,out] s  the string to manipulate; changed so that all | 
				
			||||||
 | 
					               occurrences of @a f are replaced with @a t | 
				
			||||||
 | 
					@param[in]     f  the substring to replace with @a t | 
				
			||||||
 | 
					@param[in]     t  the string to replace @a f | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pre The search string @a f must not be empty. **This precondition is | 
				
			||||||
 | 
					enforced with an assertion.** | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@since version 2.0.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename StringType> | 
				
			||||||
 | 
					inline void replace_substring(StringType& s, const StringType& f, | 
				
			||||||
 | 
					                              const StringType& t) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    JSON_ASSERT(!f.empty()); | 
				
			||||||
 | 
					    for (auto pos = s.find(f);                // find first occurrence of f
 | 
				
			||||||
 | 
					            pos != StringType::npos;          // make sure f was found
 | 
				
			||||||
 | 
					            s.replace(pos, f.size(), t),      // replace with t, and
 | 
				
			||||||
 | 
					            pos = s.find(f, pos + t.size()))  // find next occurrence of f
 | 
				
			||||||
 | 
					    {} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * @brief string escaping as described in RFC 6901 (Sect. 4) | 
				
			||||||
 | 
					 * @param[in] s string to escape | 
				
			||||||
 | 
					 * @return    escaped string | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Note the order of escaping "~" to "~0" and "/" to "~1" is important. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					template<typename StringType> | 
				
			||||||
 | 
					inline StringType escape(StringType s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    replace_substring(s, StringType{"~"}, StringType{"~0"}); | 
				
			||||||
 | 
					    replace_substring(s, StringType{"/"}, StringType{"~1"}); | 
				
			||||||
 | 
					    return s; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * @brief string unescaping as described in RFC 6901 (Sect. 4) | 
				
			||||||
 | 
					 * @param[in] s string to unescape | 
				
			||||||
 | 
					 * @return    unescaped string | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Note the order of escaping "~1" to "/" and "~0" to "~" is important. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					template<typename StringType> | 
				
			||||||
 | 
					static void unescape(StringType& s) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    replace_substring(s, StringType{"~1"}, StringType{"/"}); | 
				
			||||||
 | 
					    replace_substring(s, StringType{"~0"}, StringType{"~"}); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
@ -0,0 +1,118 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <array> // array | 
				
			||||||
 | 
					#include <cstddef> // size_t | 
				
			||||||
 | 
					#include <cstdint> // uint8_t | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#if JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    #include <compare> // partial_ordering | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					namespace detail | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////
 | 
				
			||||||
 | 
					// JSON type enumeration //
 | 
				
			||||||
 | 
					///////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief the JSON type enumeration | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This enumeration collects the different JSON types. It is internally used to | 
				
			||||||
 | 
					distinguish the stored values, and the functions @ref basic_json::is_null(), | 
				
			||||||
 | 
					@ref basic_json::is_object(), @ref basic_json::is_array(), | 
				
			||||||
 | 
					@ref basic_json::is_string(), @ref basic_json::is_boolean(), | 
				
			||||||
 | 
					@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), | 
				
			||||||
 | 
					@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), | 
				
			||||||
 | 
					@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and | 
				
			||||||
 | 
					@ref basic_json::is_structured() rely on it. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@note There are three enumeration entries (number_integer, number_unsigned, and | 
				
			||||||
 | 
					number_float), because the library distinguishes these three types for numbers: | 
				
			||||||
 | 
					@ref basic_json::number_unsigned_t is used for unsigned integers, | 
				
			||||||
 | 
					@ref basic_json::number_integer_t is used for signed integers, and | 
				
			||||||
 | 
					@ref basic_json::number_float_t is used for floating-point numbers or to | 
				
			||||||
 | 
					approximate integers which do not fit in the limits of their respective type. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON | 
				
			||||||
 | 
					value with the default value for a given type | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@since version 1.0.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					enum class value_t : std::uint8_t | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    null,             ///< null value
 | 
				
			||||||
 | 
					    object,           ///< object (unordered set of name/value pairs)
 | 
				
			||||||
 | 
					    array,            ///< array (ordered collection of values)
 | 
				
			||||||
 | 
					    string,           ///< string value
 | 
				
			||||||
 | 
					    boolean,          ///< boolean value
 | 
				
			||||||
 | 
					    number_integer,   ///< number value (signed integer)
 | 
				
			||||||
 | 
					    number_unsigned,  ///< number value (unsigned integer)
 | 
				
			||||||
 | 
					    number_float,     ///< number value (floating-point)
 | 
				
			||||||
 | 
					    binary,           ///< binary array (ordered collection of bytes)
 | 
				
			||||||
 | 
					    discarded         ///< discarded by the parser callback function
 | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief comparison operator for JSON types | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Returns an ordering that is similar to Python: | 
				
			||||||
 | 
					- order: null < boolean < number < object < array < string < binary | 
				
			||||||
 | 
					- furthermore, each type is not smaller than itself | 
				
			||||||
 | 
					- discarded values are not comparable | 
				
			||||||
 | 
					- binary is represented as a b"" string in python and directly comparable to a | 
				
			||||||
 | 
					  string; however, making a binary array directly comparable with a string would | 
				
			||||||
 | 
					  be surprising behavior in a JSON file. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@since version 1.0.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					#if JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
 | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    inline bool operator<(const value_t lhs, const value_t rhs) noexcept | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    static constexpr std::array<std::uint8_t, 9> order = {{ | 
				
			||||||
 | 
					            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, | 
				
			||||||
 | 
					            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, | 
				
			||||||
 | 
					            6 /* binary */ | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto l_index = static_cast<std::size_t>(lhs); | 
				
			||||||
 | 
					    const auto r_index = static_cast<std::size_t>(rhs); | 
				
			||||||
 | 
					#if JSON_HAS_THREE_WAY_COMPARISON | 
				
			||||||
 | 
					    if (l_index < order.size() && r_index < order.size()) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return order[l_index] <=> order[r_index]; // *NOPAD*
 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    return std::partial_ordering::unordered; | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GCC selects the built-in operator< over an operator rewritten from
 | 
				
			||||||
 | 
					// a user-defined spaceship operator
 | 
				
			||||||
 | 
					// Clang, MSVC, and ICC select the rewritten candidate
 | 
				
			||||||
 | 
					// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
 | 
				
			||||||
 | 
					#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) | 
				
			||||||
 | 
					inline bool operator<(const value_t lhs, const value_t rhs) noexcept | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    return std::is_lt(lhs <=> rhs); // *NOPAD*
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace detail
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,74 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ | 
				
			||||||
 | 
					#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint> // int64_t, uint64_t | 
				
			||||||
 | 
					#include <map> // map | 
				
			||||||
 | 
					#include <memory> // allocator | 
				
			||||||
 | 
					#include <string> // string | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/abi_macros.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief namespace for Niels Lohmann | 
				
			||||||
 | 
					@see https://github.com/nlohmann
 | 
				
			||||||
 | 
					@since version 1.0.0 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief default JSONSerializer template argument | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This serializer ignores the template arguments and uses ADL | 
				
			||||||
 | 
					([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
 | 
				
			||||||
 | 
					for serialization. | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					template<typename T = void, typename SFINAE = void> | 
				
			||||||
 | 
					struct adl_serializer; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// a class to store JSON values
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/basic_json/
 | 
				
			||||||
 | 
					template<template<typename U, typename V, typename... Args> class ObjectType = | 
				
			||||||
 | 
					         std::map, | 
				
			||||||
 | 
					         template<typename U, typename... Args> class ArrayType = std::vector, | 
				
			||||||
 | 
					         class StringType = std::string, class BooleanType = bool, | 
				
			||||||
 | 
					         class NumberIntegerType = std::int64_t, | 
				
			||||||
 | 
					         class NumberUnsignedType = std::uint64_t, | 
				
			||||||
 | 
					         class NumberFloatType = double, | 
				
			||||||
 | 
					         template<typename U> class AllocatorType = std::allocator, | 
				
			||||||
 | 
					         template<typename T, typename SFINAE = void> class JSONSerializer = | 
				
			||||||
 | 
					         adl_serializer, | 
				
			||||||
 | 
					         class BinaryType = std::vector<std::uint8_t>> | 
				
			||||||
 | 
					class basic_json; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/json_pointer/
 | 
				
			||||||
 | 
					template<typename RefStringType> | 
				
			||||||
 | 
					class json_pointer; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					@brief default specialization | 
				
			||||||
 | 
					@sa https://json.nlohmann.me/api/json/
 | 
				
			||||||
 | 
					*/ | 
				
			||||||
 | 
					using json = basic_json<>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief a minimal map-like container that preserves insertion order
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/ordered_map/
 | 
				
			||||||
 | 
					template<class Key, class T, class IgnoredLess, class Allocator> | 
				
			||||||
 | 
					struct ordered_map; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief specialization that maintains the insertion order of object keys
 | 
				
			||||||
 | 
					/// @sa https://json.nlohmann.me/api/ordered_json/
 | 
				
			||||||
 | 
					using ordered_json = basic_json<nlohmann::ordered_map>; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
 | 
				
			||||||
@ -0,0 +1,359 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <functional> // equal_to, less | 
				
			||||||
 | 
					#include <initializer_list> // initializer_list | 
				
			||||||
 | 
					#include <iterator> // input_iterator_tag, iterator_traits | 
				
			||||||
 | 
					#include <memory> // allocator | 
				
			||||||
 | 
					#include <stdexcept> // for out_of_range | 
				
			||||||
 | 
					#include <type_traits> // enable_if, is_convertible | 
				
			||||||
 | 
					#include <utility> // pair | 
				
			||||||
 | 
					#include <vector> // vector | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nlohmann/detail/macro_scope.hpp> | 
				
			||||||
 | 
					#include <nlohmann/detail/meta/type_traits.hpp> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_BEGIN | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ordered_map: a minimal map-like container that preserves insertion order
 | 
				
			||||||
 | 
					/// for use within nlohmann::basic_json<ordered_map>
 | 
				
			||||||
 | 
					template <class Key, class T, class IgnoredLess = std::less<Key>, | 
				
			||||||
 | 
					          class Allocator = std::allocator<std::pair<const Key, T>>> | 
				
			||||||
 | 
					                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator> | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    using key_type = Key; | 
				
			||||||
 | 
					    using mapped_type = T; | 
				
			||||||
 | 
					    using Container = std::vector<std::pair<const Key, T>, Allocator>; | 
				
			||||||
 | 
					    using iterator = typename Container::iterator; | 
				
			||||||
 | 
					    using const_iterator = typename Container::const_iterator; | 
				
			||||||
 | 
					    using size_type = typename Container::size_type; | 
				
			||||||
 | 
					    using value_type = typename Container::value_type; | 
				
			||||||
 | 
					#ifdef JSON_HAS_CPP_14 | 
				
			||||||
 | 
					    using key_compare = std::equal_to<>; | 
				
			||||||
 | 
					#else | 
				
			||||||
 | 
					    using key_compare = std::equal_to<Key>; | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Explicit constructors instead of `using Container::Container`
 | 
				
			||||||
 | 
					    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
 | 
				
			||||||
 | 
					    ordered_map() noexcept(noexcept(Container())) : Container{} {} | 
				
			||||||
 | 
					    explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {} | 
				
			||||||
 | 
					    template <class It> | 
				
			||||||
 | 
					    ordered_map(It first, It last, const Allocator& alloc = Allocator()) | 
				
			||||||
 | 
					        : Container{first, last, alloc} {} | 
				
			||||||
 | 
					    ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() ) | 
				
			||||||
 | 
					        : Container{init, alloc} {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::pair<iterator, bool> emplace(const key_type& key, T&& t) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return {it, false}; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        Container::emplace_back(key, std::forward<T>(t)); | 
				
			||||||
 | 
					        return {std::prev(this->end()), true}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    std::pair<iterator, bool> emplace(KeyType && key, T && t) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return {it, false}; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t)); | 
				
			||||||
 | 
					        return {std::prev(this->end()), true}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    T& operator[](const key_type& key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return emplace(key, T{}).first->second; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    T & operator[](KeyType && key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return emplace(std::forward<KeyType>(key), T{}).first->second; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const T& operator[](const key_type& key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return at(key); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    const T & operator[](KeyType && key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return at(std::forward<KeyType>(key)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    T& at(const key_type& key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it->second; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_THROW(std::out_of_range("key not found")); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    T & at(KeyType && key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it->second; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_THROW(std::out_of_range("key not found")); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const T& at(const key_type& key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it->second; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_THROW(std::out_of_range("key not found")); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    const T & at(KeyType && key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it->second; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JSON_THROW(std::out_of_range("key not found")); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_type erase(const key_type& key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // Since we cannot move const Keys, re-construct them in place
 | 
				
			||||||
 | 
					                for (auto next = it; ++next != this->end(); ++it) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    it->~value_type(); // Destroy but keep allocation
 | 
				
			||||||
 | 
					                    new (&*it) value_type{std::move(*next)}; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                Container::pop_back(); | 
				
			||||||
 | 
					                return 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return 0; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    size_type erase(KeyType && key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                // Since we cannot move const Keys, re-construct them in place
 | 
				
			||||||
 | 
					                for (auto next = it; ++next != this->end(); ++it) | 
				
			||||||
 | 
					                { | 
				
			||||||
 | 
					                    it->~value_type(); // Destroy but keep allocation
 | 
				
			||||||
 | 
					                    new (&*it) value_type{std::move(*next)}; | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                Container::pop_back(); | 
				
			||||||
 | 
					                return 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return 0; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iterator erase(iterator pos) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return erase(pos, std::next(pos)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iterator erase(iterator first, iterator last) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        if (first == last) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            return first; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const auto elements_affected = std::distance(first, last); | 
				
			||||||
 | 
					        const auto offset = std::distance(Container::begin(), first); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // This is the start situation. We need to delete elements_affected
 | 
				
			||||||
 | 
					        // elements (3 in this example: e, f, g), and need to return an
 | 
				
			||||||
 | 
					        // iterator past the last deleted element (h in this example).
 | 
				
			||||||
 | 
					        // Note that offset is the distance from the start of the vector
 | 
				
			||||||
 | 
					        // to first. We will need this later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // [ a, b, c, d, e, f, g, h, i, j ]
 | 
				
			||||||
 | 
					        //               ^        ^
 | 
				
			||||||
 | 
					        //             first    last
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Since we cannot move const Keys, we re-construct them in place.
 | 
				
			||||||
 | 
					        // We start at first and re-construct (viz. copy) the elements from
 | 
				
			||||||
 | 
					        // the back of the vector. Example for first iteration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //               ,--------.
 | 
				
			||||||
 | 
					        //               v        |   destroy e and re-construct with h
 | 
				
			||||||
 | 
					        // [ a, b, c, d, e, f, g, h, i, j ]
 | 
				
			||||||
 | 
					        //               ^        ^
 | 
				
			||||||
 | 
					        //               it       it + elements_affected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            it->~value_type(); // destroy but keep allocation
 | 
				
			||||||
 | 
					            new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
 | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // [ a, b, c, d, h, i, j, h, i, j ]
 | 
				
			||||||
 | 
					        //               ^        ^
 | 
				
			||||||
 | 
					        //             first    last
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // remove the unneeded elements at the end of the vector
 | 
				
			||||||
 | 
					        Container::resize(this->size() - static_cast<size_type>(elements_affected)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // [ a, b, c, d, h, i, j ]
 | 
				
			||||||
 | 
					        //               ^        ^
 | 
				
			||||||
 | 
					        //             first    last
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // first is now pointing past the last deleted element, but we cannot
 | 
				
			||||||
 | 
					        // use this iterator, because it may have been invalidated by the
 | 
				
			||||||
 | 
					        // resize call. Instead, we can return begin() + offset.
 | 
				
			||||||
 | 
					        return Container::begin() + offset; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_type count(const key_type& key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return 0; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    size_type count(KeyType && key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return 1; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return 0; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iterator find(const key_type& key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return Container::end(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class KeyType, detail::enable_if_t< | 
				
			||||||
 | 
					                 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> | 
				
			||||||
 | 
					    iterator find(KeyType && key) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return Container::end(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const_iterator find(const key_type& key) const | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, key)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return it; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return Container::end(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::pair<iterator, bool> insert( value_type&& value ) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        return emplace(value.first, std::move(value.second)); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::pair<iterator, bool> insert( const value_type& value ) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = this->begin(); it != this->end(); ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            if (m_compare(it->first, value.first)) | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					                return {it, false}; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        Container::push_back(value); | 
				
			||||||
 | 
					        return {--this->end(), true}; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename InputIt> | 
				
			||||||
 | 
					    using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category, | 
				
			||||||
 | 
					            std::input_iterator_tag>::value>::type; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename InputIt, typename = require_input_iter<InputIt>> | 
				
			||||||
 | 
					    void insert(InputIt first, InputIt last) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        for (auto it = first; it != last; ++it) | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					            insert(*it); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
					    JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare(); | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NLOHMANN_JSON_NAMESPACE_END | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,158 @@ | 
				
			|||||||
 | 
					//     __ _____ _____ _____
 | 
				
			||||||
 | 
					//  __|  |   __|     |   | |  JSON for Modern C++
 | 
				
			||||||
 | 
					// |  |  |__   |  |  | | | |  version 3.11.2
 | 
				
			||||||
 | 
					// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef JSON_HEDLEY_ALWAYS_INLINE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_ARM_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_ARM_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_ARRAY_PARAM | 
				
			||||||
 | 
					#undef JSON_HEDLEY_ASSUME | 
				
			||||||
 | 
					#undef JSON_HEDLEY_BEGIN_C_DECLS | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_BUILTIN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_EXTENSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_FEATURE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CLANG_HAS_WARNING | 
				
			||||||
 | 
					#undef JSON_HEDLEY_COMPCERT_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONCAT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONCAT3 | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONCAT3_EX | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONCAT_EX | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONSTEXPR | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CONST_CAST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CPP_CAST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CRAY_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_CRAY_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_C_DECL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DEPRECATED | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DEPRECATED_FOR | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_POP | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DIAGNOSTIC_PUSH | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DMC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_DMC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_EMPTY_BASES | 
				
			||||||
 | 
					#undef JSON_HEDLEY_EMSCRIPTEN_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_END_C_DECLS | 
				
			||||||
 | 
					#undef JSON_HEDLEY_FLAGS | 
				
			||||||
 | 
					#undef JSON_HEDLEY_FLAGS_CAST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_BUILTIN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_EXTENSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_FEATURE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_HAS_WARNING | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GCC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_BUILTIN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_EXTENSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_FEATURE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_HAS_WARNING | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_GNUC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_BUILTIN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_EXTENSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_FEATURE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_HAS_WARNING | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IAR_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IAR_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IBM_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IBM_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IMPORT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_INLINE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_INTEL_CL_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_INTEL_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_INTEL_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IS_CONSTANT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_IS_CONSTEXPR_ | 
				
			||||||
 | 
					#undef JSON_HEDLEY_LIKELY | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MALLOC | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MCST_LCC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MESSAGE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MSVC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_MSVC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NEVER_INLINE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NON_NULL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NO_ESCAPE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NO_RETURN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NO_THROW | 
				
			||||||
 | 
					#undef JSON_HEDLEY_NULL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PELLES_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PELLES_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PGI_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PGI_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PREDICT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PRINTF_FORMAT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PRIVATE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PUBLIC | 
				
			||||||
 | 
					#undef JSON_HEDLEY_PURE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_REINTERPRET_CAST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_REQUIRE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_REQUIRE_CONSTEXPR | 
				
			||||||
 | 
					#undef JSON_HEDLEY_REQUIRE_MSG | 
				
			||||||
 | 
					#undef JSON_HEDLEY_RESTRICT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_RETURNS_NON_NULL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_SENTINEL | 
				
			||||||
 | 
					#undef JSON_HEDLEY_STATIC_ASSERT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_STATIC_CAST | 
				
			||||||
 | 
					#undef JSON_HEDLEY_STRINGIFY | 
				
			||||||
 | 
					#undef JSON_HEDLEY_STRINGIFY_EX | 
				
			||||||
 | 
					#undef JSON_HEDLEY_SUNPRO_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TINYC_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TINYC_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_ARMCL_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL2000_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL430_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL6X_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL7X_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CLPRU_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_TI_VERSION_CHECK | 
				
			||||||
 | 
					#undef JSON_HEDLEY_UNAVAILABLE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_UNLIKELY | 
				
			||||||
 | 
					#undef JSON_HEDLEY_UNPREDICTABLE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_UNREACHABLE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_UNREACHABLE_RETURN | 
				
			||||||
 | 
					#undef JSON_HEDLEY_VERSION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_VERSION_DECODE_MAJOR | 
				
			||||||
 | 
					#undef JSON_HEDLEY_VERSION_DECODE_MINOR | 
				
			||||||
 | 
					#undef JSON_HEDLEY_VERSION_DECODE_REVISION | 
				
			||||||
 | 
					#undef JSON_HEDLEY_VERSION_ENCODE | 
				
			||||||
 | 
					#undef JSON_HEDLEY_WARNING | 
				
			||||||
 | 
					#undef JSON_HEDLEY_WARN_UNUSED_RESULT | 
				
			||||||
 | 
					#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG | 
				
			||||||
 | 
					#undef JSON_HEDLEY_FALL_THROUGH | 
				
			||||||
@ -0,0 +1,24 @@ | 
				
			|||||||
 | 
					project('nlohmann_json', | 
				
			||||||
 | 
					    'cpp', | 
				
			||||||
 | 
					    version : '3.11.2', | 
				
			||||||
 | 
					    license : 'MIT', | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					nlohmann_json_dep = declare_dependency( | 
				
			||||||
 | 
					    include_directories: include_directories('single_include') | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					nlohmann_json_multiple_headers = declare_dependency( | 
				
			||||||
 | 
					    include_directories: include_directories('include') | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if not meson.is_subproject() | 
				
			||||||
 | 
					install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann') | 
				
			||||||
 | 
					install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann') | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pkgc = import('pkgconfig') | 
				
			||||||
 | 
					pkgc.generate(name: 'nlohmann_json', | 
				
			||||||
 | 
					    version: meson.project_version(), | 
				
			||||||
 | 
					    description: 'JSON for Modern C++' | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					endif | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						
					Loading…
					
					
				
		Reference in new issue