1// __ _____ _____ _____ 2// __| | __| | | | JSON for Modern C++ 3// | | |__ | | | | | | version 3.11.2 4// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5// 6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7// SPDX-License-Identifier: MIT 8 9#pragma once 10 11#include <cstring> // strlen 12#include <string> // string 13#include <utility> // forward 14 15#include <nlohmann/detail/meta/cpp_future.hpp> 16#include <nlohmann/detail/meta/detected.hpp> 17 18NLOHMANN_JSON_NAMESPACE_BEGIN 19namespace detail 20{ 21 22inline std::size_t concat_length() 23{ 24 return 0; 25} 26 27template<typename... Args> 28inline std::size_t concat_length(const char* cstr, Args&& ... rest); 29 30template<typename StringType, typename... Args> 31inline std::size_t concat_length(const StringType& str, Args&& ... rest); 32 33template<typename... Args> 34inline std::size_t concat_length(const char /*c*/, Args&& ... rest) 35{ 36 return 1 + concat_length(std::forward<Args>(rest)...); 37} 38 39template<typename... Args> 40inline std::size_t concat_length(const char* cstr, Args&& ... rest) 41{ 42 // cppcheck-suppress ignoredReturnValue 43 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...); 44} 45 46template<typename StringType, typename... Args> 47inline std::size_t concat_length(const StringType& str, Args&& ... rest) 48{ 49 return str.size() + concat_length(std::forward<Args>(rest)...); 50} 51 52template<typename OutStringType> 53inline void concat_into(OutStringType& /*out*/) 54{} 55 56template<typename StringType, typename Arg> 57using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ())); 58 59template<typename StringType, typename Arg> 60using detect_string_can_append = is_detected<string_can_append, StringType, Arg>; 61 62template<typename StringType, typename Arg> 63using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ()); 64 65template<typename StringType, typename Arg> 66using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>; 67 68template<typename StringType, typename Arg> 69using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end())); 70 71template<typename StringType, typename Arg> 72using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>; 73 74template<typename StringType, typename Arg> 75using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size())); 76 77template<typename StringType, typename Arg> 78using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>; 79 80template < typename OutStringType, typename Arg, typename... Args, 81 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 82 && detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 > 83inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest); 84 85template < typename OutStringType, typename Arg, typename... Args, 86 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 87 && !detect_string_can_append_op<OutStringType, Arg>::value 88 && detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 > 89inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest); 90 91template < typename OutStringType, typename Arg, typename... Args, 92 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 93 && !detect_string_can_append_op<OutStringType, Arg>::value 94 && !detect_string_can_append_iter<OutStringType, Arg>::value 95 && detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 > 96inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest); 97 98template<typename OutStringType, typename Arg, typename... Args, 99 enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0> 100inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest) 101{ 102 out.append(std::forward<Arg>(arg)); 103 concat_into(out, std::forward<Args>(rest)...); 104} 105 106template < typename OutStringType, typename Arg, typename... Args, 107 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 108 && detect_string_can_append_op<OutStringType, Arg>::value, int > > 109inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest) 110{ 111 out += std::forward<Arg>(arg); 112 concat_into(out, std::forward<Args>(rest)...); 113} 114 115template < typename OutStringType, typename Arg, typename... Args, 116 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 117 && !detect_string_can_append_op<OutStringType, Arg>::value 118 && detect_string_can_append_iter<OutStringType, Arg>::value, int > > 119inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest) 120{ 121 out.append(arg.begin(), arg.end()); 122 concat_into(out, std::forward<Args>(rest)...); 123} 124 125template < typename OutStringType, typename Arg, typename... Args, 126 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value 127 && !detect_string_can_append_op<OutStringType, Arg>::value 128 && !detect_string_can_append_iter<OutStringType, Arg>::value 129 && detect_string_can_append_data<OutStringType, Arg>::value, int > > 130inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest) 131{ 132 out.append(arg.data(), arg.size()); 133 concat_into(out, std::forward<Args>(rest)...); 134} 135 136template<typename OutStringType = std::string, typename... Args> 137inline OutStringType concat(Args && ... args) 138{ 139 OutStringType str; 140 str.reserve(concat_length(std::forward<Args>(args)...)); 141 concat_into(str, std::forward<Args>(args)...); 142 return str; 143} 144 145} // namespace detail 146NLOHMANN_JSON_NAMESPACE_END 147