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
18 NLOHMANN_JSON_NAMESPACE_BEGIN
19 namespace detail
20 {
21
concat_length()22 inline std::size_t concat_length()
23 {
24 return 0;
25 }
26
27 template<typename... Args>
28 inline std::size_t concat_length(const char* cstr, Args&& ... rest);
29
30 template<typename StringType, typename... Args>
31 inline std::size_t concat_length(const StringType& str, Args&& ... rest);
32
33 template<typename... Args>
concat_length(const char,Args &&...rest)34 inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
35 {
36 return 1 + concat_length(std::forward<Args>(rest)...);
37 }
38
39 template<typename... Args>
concat_length(const char * cstr,Args &&...rest)40 inline 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
46 template<typename StringType, typename... Args>
concat_length(const StringType & str,Args &&...rest)47 inline std::size_t concat_length(const StringType& str, Args&& ... rest)
48 {
49 return str.size() + concat_length(std::forward<Args>(rest)...);
50 }
51
52 template<typename OutStringType>
concat_into(OutStringType &)53 inline void concat_into(OutStringType& /*out*/)
54 {}
55
56 template<typename StringType, typename Arg>
57 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
58
59 template<typename StringType, typename Arg>
60 using detect_string_can_append = is_detected<string_can_append, StringType, Arg>;
61
62 template<typename StringType, typename Arg>
63 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
64
65 template<typename StringType, typename Arg>
66 using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>;
67
68 template<typename StringType, typename Arg>
69 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
70
71 template<typename StringType, typename Arg>
72 using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>;
73
74 template<typename StringType, typename Arg>
75 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
76
77 template<typename StringType, typename Arg>
78 using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
79
80 template < 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 >
83 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
84
85 template < 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 >
89 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
90
91 template < 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 >
96 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
97
98 template<typename OutStringType, typename Arg, typename... Args,
99 enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
concat_into(OutStringType & out,Arg && arg,Args &&...rest)100 inline 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
106 template < 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 > >
concat_into(OutStringType & out,Arg && arg,Args &&...rest)109 inline 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
115 template < 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 > >
concat_into(OutStringType & out,const Arg & arg,Args &&...rest)119 inline 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
125 template < 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 > >
concat_into(OutStringType & out,const Arg & arg,Args &&...rest)130 inline 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
136 template<typename OutStringType = std::string, typename... Args>
concat(Args &&...args)137 inline 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
146 NLOHMANN_JSON_NAMESPACE_END
147