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 |
