comparison dep/toml11/toml/traits.hpp @ 318:3b355fa948c7

config: use TOML instead of INI unfortunately, INI is not enough, and causes some paths including semicolons to break with our current storage of the library folders. so, I decided to switch to TOML which does support real arrays...
author Paper <paper@paper.us.eu.org>
date Wed, 12 Jun 2024 05:25:41 -0400
parents
children
comparison
equal deleted inserted replaced
317:b1f4d1867ab1 318:3b355fa948c7
1 // Copyright Toru Niina 2017.
2 // Distributed under the MIT License.
3 #ifndef TOML11_TRAITS_HPP
4 #define TOML11_TRAITS_HPP
5
6 #include "from.hpp"
7 #include "into.hpp"
8 #include "version.hpp"
9
10 #include <chrono>
11 #include <forward_list>
12 #include <string>
13 #include <tuple>
14 #include <type_traits>
15 #include <utility>
16
17 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L
18 #if __has_include(<string_view>)
19 #include <string_view>
20 #endif // has_include(<string_view>)
21 #endif // cplusplus >= C++17
22
23 namespace toml
24 {
25 template<typename C, template<typename ...> class T, template<typename ...> class A>
26 class basic_value;
27
28 namespace detail
29 {
30 // ---------------------------------------------------------------------------
31 // check whether type T is a kind of container/map class
32
33 struct has_iterator_impl
34 {
35 template<typename T> static std::true_type check(typename T::iterator*);
36 template<typename T> static std::false_type check(...);
37 };
38 struct has_value_type_impl
39 {
40 template<typename T> static std::true_type check(typename T::value_type*);
41 template<typename T> static std::false_type check(...);
42 };
43 struct has_key_type_impl
44 {
45 template<typename T> static std::true_type check(typename T::key_type*);
46 template<typename T> static std::false_type check(...);
47 };
48 struct has_mapped_type_impl
49 {
50 template<typename T> static std::true_type check(typename T::mapped_type*);
51 template<typename T> static std::false_type check(...);
52 };
53 struct has_reserve_method_impl
54 {
55 template<typename T> static std::false_type check(...);
56 template<typename T> static std::true_type check(
57 decltype(std::declval<T>().reserve(std::declval<std::size_t>()))*);
58 };
59 struct has_push_back_method_impl
60 {
61 template<typename T> static std::false_type check(...);
62 template<typename T> static std::true_type check(
63 decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))*);
64 };
65 struct is_comparable_impl
66 {
67 template<typename T> static std::false_type check(...);
68 template<typename T> static std::true_type check(
69 decltype(std::declval<T>() < std::declval<T>())*);
70 };
71
72 struct has_from_toml_method_impl
73 {
74 template<typename T, typename C,
75 template<typename ...> class Tb, template<typename ...> class A>
76 static std::true_type check(
77 decltype(std::declval<T>().from_toml(
78 std::declval<::toml::basic_value<C, Tb, A>>()))*);
79
80 template<typename T, typename C,
81 template<typename ...> class Tb, template<typename ...> class A>
82 static std::false_type check(...);
83 };
84 struct has_into_toml_method_impl
85 {
86 template<typename T>
87 static std::true_type check(decltype(std::declval<T>().into_toml())*);
88 template<typename T>
89 static std::false_type check(...);
90 };
91
92 struct has_specialized_from_impl
93 {
94 template<typename T>
95 static std::false_type check(...);
96 template<typename T, std::size_t S = sizeof(::toml::from<T>)>
97 static std::true_type check(::toml::from<T>*);
98 };
99 struct has_specialized_into_impl
100 {
101 template<typename T>
102 static std::false_type check(...);
103 template<typename T, std::size_t S = sizeof(::toml::into<T>)>
104 static std::true_type check(::toml::from<T>*);
105 };
106
107
108 /// Intel C++ compiler can not use decltype in parent class declaration, here
109 /// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
110 #ifdef __INTEL_COMPILER
111 #define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
112 #endif
113
114 template<typename T>
115 struct has_iterator : decltype(has_iterator_impl::check<T>(nullptr)){};
116 template<typename T>
117 struct has_value_type : decltype(has_value_type_impl::check<T>(nullptr)){};
118 template<typename T>
119 struct has_key_type : decltype(has_key_type_impl::check<T>(nullptr)){};
120 template<typename T>
121 struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
122 template<typename T>
123 struct has_reserve_method : decltype(has_reserve_method_impl::check<T>(nullptr)){};
124 template<typename T>
125 struct has_push_back_method : decltype(has_push_back_method_impl::check<T>(nullptr)){};
126 template<typename T>
127 struct is_comparable : decltype(is_comparable_impl::check<T>(nullptr)){};
128
129 template<typename T, typename C,
130 template<typename ...> class Tb, template<typename ...> class A>
131 struct has_from_toml_method
132 : decltype(has_from_toml_method_impl::check<T, C, Tb, A>(nullptr)){};
133
134 template<typename T>
135 struct has_into_toml_method
136 : decltype(has_into_toml_method_impl::check<T>(nullptr)){};
137
138 template<typename T>
139 struct has_specialized_from : decltype(has_specialized_from_impl::check<T>(nullptr)){};
140 template<typename T>
141 struct has_specialized_into : decltype(has_specialized_into_impl::check<T>(nullptr)){};
142
143 #ifdef __INTEL_COMPILER
144 #undef decltype
145 #endif
146
147 // ---------------------------------------------------------------------------
148 // C++17 and/or/not
149
150 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L
151
152 using std::conjunction;
153 using std::disjunction;
154 using std::negation;
155
156 #else
157
158 template<typename ...> struct conjunction : std::true_type{};
159 template<typename T> struct conjunction<T> : T{};
160 template<typename T, typename ... Ts>
161 struct conjunction<T, Ts...> :
162 std::conditional<static_cast<bool>(T::value), conjunction<Ts...>, T>::type
163 {};
164
165 template<typename ...> struct disjunction : std::false_type{};
166 template<typename T> struct disjunction<T> : T {};
167 template<typename T, typename ... Ts>
168 struct disjunction<T, Ts...> :
169 std::conditional<static_cast<bool>(T::value), T, disjunction<Ts...>>::type
170 {};
171
172 template<typename T>
173 struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
174
175 #endif
176
177 // ---------------------------------------------------------------------------
178 // type checkers
179
180 template<typename T> struct is_std_pair : std::false_type{};
181 template<typename T1, typename T2>
182 struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
183
184 template<typename T> struct is_std_tuple : std::false_type{};
185 template<typename ... Ts>
186 struct is_std_tuple<std::tuple<Ts...>> : std::true_type{};
187
188 template<typename T> struct is_std_forward_list : std::false_type{};
189 template<typename T>
190 struct is_std_forward_list<std::forward_list<T>> : std::true_type{};
191
192 template<typename T> struct is_chrono_duration: std::false_type{};
193 template<typename Rep, typename Period>
194 struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};
195
196 template<typename T>
197 struct is_map : conjunction< // map satisfies all the following conditions
198 has_iterator<T>, // has T::iterator
199 has_value_type<T>, // has T::value_type
200 has_key_type<T>, // has T::key_type
201 has_mapped_type<T> // has T::mapped_type
202 >{};
203 template<typename T> struct is_map<T&> : is_map<T>{};
204 template<typename T> struct is_map<T const&> : is_map<T>{};
205 template<typename T> struct is_map<T volatile&> : is_map<T>{};
206 template<typename T> struct is_map<T const volatile&> : is_map<T>{};
207
208 template<typename T>
209 struct is_container : conjunction<
210 negation<is_map<T>>, // not a map
211 negation<std::is_same<T, std::string>>, // not a std::string
212 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L
213 #if __has_include(<string_view>)
214 negation<std::is_same<T, std::string_view>>, // not a std::string_view
215 #endif // has_include(<string_view>)
216 #endif
217 has_iterator<T>, // has T::iterator
218 has_value_type<T> // has T::value_type
219 >{};
220 template<typename T> struct is_container<T&> : is_container<T>{};
221 template<typename T> struct is_container<T const&> : is_container<T>{};
222 template<typename T> struct is_container<T volatile&> : is_container<T>{};
223 template<typename T> struct is_container<T const volatile&> : is_container<T>{};
224
225 template<typename T>
226 struct is_basic_value: std::false_type{};
227 template<typename T> struct is_basic_value<T&> : is_basic_value<T>{};
228 template<typename T> struct is_basic_value<T const&> : is_basic_value<T>{};
229 template<typename T> struct is_basic_value<T volatile&> : is_basic_value<T>{};
230 template<typename T> struct is_basic_value<T const volatile&> : is_basic_value<T>{};
231 template<typename C, template<typename ...> class M, template<typename ...> class V>
232 struct is_basic_value<::toml::basic_value<C, M, V>>: std::true_type{};
233
234 // ---------------------------------------------------------------------------
235 // C++14 index_sequence
236
237 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L
238
239 using std::index_sequence;
240 using std::make_index_sequence;
241
242 #else
243
244 template<std::size_t ... Ns> struct index_sequence{};
245
246 template<typename IS, std::size_t N> struct push_back_index_sequence{};
247 template<std::size_t N, std::size_t ... Ns>
248 struct push_back_index_sequence<index_sequence<Ns...>, N>
249 {
250 typedef index_sequence<Ns..., N> type;
251 };
252
253 template<std::size_t N>
254 struct index_sequence_maker
255 {
256 typedef typename push_back_index_sequence<
257 typename index_sequence_maker<N-1>::type, N>::type type;
258 };
259 template<>
260 struct index_sequence_maker<0>
261 {
262 typedef index_sequence<0> type;
263 };
264 template<std::size_t N>
265 using make_index_sequence = typename index_sequence_maker<N-1>::type;
266
267 #endif // cplusplus >= 2014
268
269 // ---------------------------------------------------------------------------
270 // C++14 enable_if_t
271
272 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L
273
274 using std::enable_if_t;
275
276 #else
277
278 template<bool B, typename T>
279 using enable_if_t = typename std::enable_if<B, T>::type;
280
281 #endif // cplusplus >= 2014
282
283 // ---------------------------------------------------------------------------
284 // return_type_of_t
285
286 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L && defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable>=201703
287
288 template<typename F, typename ... Args>
289 using return_type_of_t = std::invoke_result_t<F, Args...>;
290
291 #else
292 // result_of is deprecated after C++17
293 template<typename F, typename ... Args>
294 using return_type_of_t = typename std::result_of<F(Args...)>::type;
295
296 #endif
297
298 // ---------------------------------------------------------------------------
299 // is_string_literal
300 //
301 // to use this, pass `typename remove_reference<T>::type` to T.
302
303 template<typename T>
304 struct is_string_literal:
305 disjunction<
306 std::is_same<const char*, T>,
307 conjunction<
308 std::is_array<T>,
309 std::is_same<const char, typename std::remove_extent<T>::type>
310 >
311 >{};
312
313 // ---------------------------------------------------------------------------
314 // C++20 remove_cvref_t
315
316 template<typename T>
317 struct remove_cvref
318 {
319 using type = typename std::remove_cv<
320 typename std::remove_reference<T>::type>::type;
321 };
322
323 template<typename T>
324 using remove_cvref_t = typename remove_cvref<T>::type;
325
326 }// detail
327 }//toml
328 #endif // TOML_TRAITS