Mercurial > minori
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 |