• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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