15#include <nlohmann/detail/meta/cpp_future.hpp>
16#include <nlohmann/detail/meta/detected.hpp>
18NLOHMANN_JSON_NAMESPACE_BEGIN
22inline std::size_t concat_length()
27template<
typename... Args>
28inline std::size_t concat_length(
const char* cstr,
const Args& ... rest);
30template<
typename StringType,
typename... Args>
31inline std::size_t concat_length(
const StringType& str,
const Args& ... rest);
33template<
typename... Args>
34inline std::size_t concat_length(
const char ,
const Args& ... rest)
36 return 1 + concat_length(rest...);
39template<
typename... Args>
40inline std::size_t concat_length(
const char* cstr,
const Args& ... rest)
43 return ::strlen(cstr) + concat_length(rest...);
46template<
typename StringType,
typename... Args>
47inline std::size_t concat_length(
const StringType& str,
const Args& ... rest)
49 return str.size() + concat_length(rest...);
52template<
typename OutStringType>
53inline void concat_into(OutStringType& )
56template<
typename StringType,
typename Arg>
57using string_can_append =
decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
59template<
typename StringType,
typename Arg>
60using detect_string_can_append = is_detected<string_can_append, StringType, Arg>;
62template<
typename StringType,
typename Arg>
63using string_can_append_op =
decltype(std::declval<StringType&>() += std::declval < Arg && > ());
65template<
typename StringType,
typename Arg>
66using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>;
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()));
71template<
typename StringType,
typename Arg>
72using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>;
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()));
77template<
typename StringType,
typename Arg>
78using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
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);
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);
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);
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)
102 out.append(std::forward<Arg>(arg));
103 concat_into(out, std::forward<Args>(rest)...);
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)
111 out += std::forward<Arg>(arg);
112 concat_into(out, std::forward<Args>(rest)...);
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)
121 out.append(arg.begin(), arg.end());
122 concat_into(out, std::forward<Args>(rest)...);
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)
132 out.append(arg.data(), arg.size());
133 concat_into(out, std::forward<Args>(rest)...);
136template<
typename OutStringType = std::string,
typename... Args>
137inline OutStringType concat(Args && ... args)
140 str.reserve(concat_length(args...));
141 concat_into(str, std::forward<Args>(args)...);
146NLOHMANN_JSON_NAMESPACE_END
detail namespace with internal helper functions
定义 from_json.hpp:43