File indexing completed on 2025-01-18 10:02:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cstring> // strlen
0012 #include <string> // string
0013 #include <utility> // forward
0014
0015 #include <nlohmann/detail/meta/cpp_future.hpp>
0016 #include <nlohmann/detail/meta/detected.hpp>
0017
0018 NLOHMANN_JSON_NAMESPACE_BEGIN
0019 namespace detail
0020 {
0021
0022 inline std::size_t concat_length()
0023 {
0024 return 0;
0025 }
0026
0027 template<typename... Args>
0028 inline std::size_t concat_length(const char* cstr, Args&& ... rest);
0029
0030 template<typename StringType, typename... Args>
0031 inline std::size_t concat_length(const StringType& str, Args&& ... rest);
0032
0033 template<typename... Args>
0034 inline std::size_t concat_length(const char , Args&& ... rest)
0035 {
0036 return 1 + concat_length(std::forward<Args>(rest)...);
0037 }
0038
0039 template<typename... Args>
0040 inline std::size_t concat_length(const char* cstr, Args&& ... rest)
0041 {
0042
0043 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
0044 }
0045
0046 template<typename StringType, typename... Args>
0047 inline std::size_t concat_length(const StringType& str, Args&& ... rest)
0048 {
0049 return str.size() + concat_length(std::forward<Args>(rest)...);
0050 }
0051
0052 template<typename OutStringType>
0053 inline void concat_into(OutStringType& )
0054 {}
0055
0056 template<typename StringType, typename Arg>
0057 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
0058
0059 template<typename StringType, typename Arg>
0060 using detect_string_can_append = is_detected<string_can_append, StringType, Arg>;
0061
0062 template<typename StringType, typename Arg>
0063 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
0064
0065 template<typename StringType, typename Arg>
0066 using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>;
0067
0068 template<typename StringType, typename Arg>
0069 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
0070
0071 template<typename StringType, typename Arg>
0072 using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>;
0073
0074 template<typename StringType, typename Arg>
0075 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
0076
0077 template<typename StringType, typename Arg>
0078 using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
0079
0080 template < typename OutStringType, typename Arg, typename... Args,
0081 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0082 && detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 >
0083 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
0084
0085 template < typename OutStringType, typename Arg, typename... Args,
0086 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0087 && !detect_string_can_append_op<OutStringType, Arg>::value
0088 && detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 >
0089 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
0090
0091 template < typename OutStringType, typename Arg, typename... Args,
0092 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0093 && !detect_string_can_append_op<OutStringType, Arg>::value
0094 && !detect_string_can_append_iter<OutStringType, Arg>::value
0095 && detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 >
0096 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
0097
0098 template<typename OutStringType, typename Arg, typename... Args,
0099 enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
0100 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
0101 {
0102 out.append(std::forward<Arg>(arg));
0103 concat_into(out, std::forward<Args>(rest)...);
0104 }
0105
0106 template < typename OutStringType, typename Arg, typename... Args,
0107 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0108 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
0109 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
0110 {
0111 out += std::forward<Arg>(arg);
0112 concat_into(out, std::forward<Args>(rest)...);
0113 }
0114
0115 template < typename OutStringType, typename Arg, typename... Args,
0116 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0117 && !detect_string_can_append_op<OutStringType, Arg>::value
0118 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
0119 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
0120 {
0121 out.append(arg.begin(), arg.end());
0122 concat_into(out, std::forward<Args>(rest)...);
0123 }
0124
0125 template < typename OutStringType, typename Arg, typename... Args,
0126 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
0127 && !detect_string_can_append_op<OutStringType, Arg>::value
0128 && !detect_string_can_append_iter<OutStringType, Arg>::value
0129 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
0130 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
0131 {
0132 out.append(arg.data(), arg.size());
0133 concat_into(out, std::forward<Args>(rest)...);
0134 }
0135
0136 template<typename OutStringType = std::string, typename... Args>
0137 inline OutStringType concat(Args && ... args)
0138 {
0139 OutStringType str;
0140 str.reserve(concat_length(std::forward<Args>(args)...));
0141 concat_into(str, std::forward<Args>(args)...);
0142 return str;
0143 }
0144
0145 }
0146 NLOHMANN_JSON_NAMESPACE_END