blob: a4c787b6358446f8fb4063c75e1f8269a5702e9c [file] [log] [blame]
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.11.3
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 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, const Args&... rest);
template<typename StringType, typename... Args>
inline std::size_t concat_length(const StringType& str, const Args&... rest);
template<typename... Args>
inline std::size_t concat_length(const char /*c*/, const Args&... rest)
{
return 1 + concat_length(rest...);
}
template<typename... Args>
inline std::size_t concat_length(const char* cstr, const Args&... rest)
{
// cppcheck-suppress ignoredReturnValue
return ::strlen(cstr) + concat_length(rest...);
}
template<typename StringType, typename... Args>
inline std::size_t concat_length(const StringType& str, const Args&... rest)
{
return str.size() + concat_length(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(args...));
concat_into(str, std::forward<Args>(args)...);
return str;
}
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END