| // __ _____ _____ _____ |
| // __| | __| | | | 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 |