1 // 2 // Copyright 2017 The Abseil Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 // ----------------------------------------------------------------------------- 17 // type_traits.h 18 // ----------------------------------------------------------------------------- 19 // 20 // This file contains C++11-compatible versions of standard <type_traits> API 21 // functions for determining the characteristics of types. Such traits can 22 // support type inference, classification, and transformation, as well as 23 // make it easier to write templates based on generic type behavior. 24 // 25 // See http://en.cppreference.com/w/cpp/header/type_traits 26 // 27 // WARNING: use of many of the constructs in this header will count as "complex 28 // template metaprogramming", so before proceeding, please carefully consider 29 // https://google.github.io/styleguide/cppguide.html#Template_metaprogramming 30 // 31 // WARNING: using template metaprogramming to detect or depend on API 32 // features is brittle and not guaranteed. Neither the standard library nor 33 // Abseil provides any guarantee that APIs are stable in the face of template 34 // metaprogramming. Use with caution. 35 #ifndef S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_ 36 #define S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_ 37 38 #include <cstddef> 39 #include <functional> 40 #include <type_traits> 41 42 #include "s2/third_party/absl/base/config.h" 43 44 namespace absl { 45 46 namespace type_traits_internal { 47 48 template <typename... Ts> 49 struct VoidTImpl { 50 using type = void; 51 }; 52 53 // This trick to retrieve a default alignment is necessary for our 54 // implementation of aligned_storage_t to be consistent with any implementation 55 // of std::aligned_storage. 56 template <size_t Len, typename T = std::aligned_storage<Len>> 57 struct default_alignment_of_aligned_storage; 58 59 template <size_t Len, size_t Align> 60 struct default_alignment_of_aligned_storage<Len, 61 std::aligned_storage<Len, Align>> { 62 static constexpr size_t value = Align; 63 }; 64 65 //////////////////////////////// 66 // Library Fundamentals V2 TS // 67 //////////////////////////////// 68 69 // NOTE: The `is_detected` family of templates here differ from the library 70 // fundamentals specification in that for library fundamentals, `Op<Args...>` is 71 // evaluated as soon as the type `is_detected<Op, Args...>` undergoes 72 // substitution, regardless of whether or not the `::value` is accessed. That 73 // is inconsistent with all other standard traits and prevents lazy evaluation 74 // in larger contexts (such as if the `is_detected` check is a trailing argument 75 // of a `conjunction`. This implementation opts to instead be lazy in the same 76 // way that the standard traits are (this "defect" of the detection idiom 77 // specifications has been reported). 78 79 template <class Enabler, template <class...> class Op, class... Args> 80 struct is_detected_impl { 81 using type = std::false_type; 82 }; 83 84 template <template <class...> class Op, class... Args> 85 struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> { 86 using type = std::true_type; 87 }; 88 89 template <template <class...> class Op, class... Args> 90 struct is_detected : is_detected_impl<void, Op, Args...>::type {}; 91 92 template <class Enabler, class To, template <class...> class Op, class... Args> 93 struct is_detected_convertible_impl { 94 using type = std::false_type; 95 }; 96 97 template <class To, template <class...> class Op, class... Args> 98 struct is_detected_convertible_impl< 99 typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type, 100 To, Op, Args...> { 101 using type = std::true_type; 102 }; 103 104 template <class To, template <class...> class Op, class... Args> 105 struct is_detected_convertible 106 : is_detected_convertible_impl<void, To, Op, Args...>::type {}; 107 108 template <typename T> 109 using IsCopyAssignableImpl = 110 decltype(std::declval<T&>() = std::declval<const T&>()); 111 112 template <typename T> 113 using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>()); 114 115 } // namespace type_traits_internal 116 117 template <typename T> 118 struct is_copy_assignable : type_traits_internal::is_detected< 119 type_traits_internal::IsCopyAssignableImpl, T> { 120 }; 121 122 template <typename T> 123 struct is_move_assignable : type_traits_internal::is_detected< 124 type_traits_internal::IsMoveAssignableImpl, T> { 125 }; 126 127 // void_t() 128 // 129 // Ignores the type of any its arguments and returns `void`. In general, this 130 // metafunction allows you to create a general case that maps to `void` while 131 // allowing specializations that map to specific types. 132 // 133 // This metafunction is designed to be a drop-in replacement for the C++17 134 // `std::void_t` metafunction. 135 // 136 // NOTE: `absl::void_t` does not use the standard-specified implementation so 137 // that it can remain compatible with gcc < 5.1. This can introduce slightly 138 // different behavior, such as when ordering partial specializations. 139 template <typename... Ts> 140 using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type; 141 142 // conjunction 143 // 144 // Performs a compile-time logical AND operation on the passed types (which 145 // must have `::value` members convertible to `bool`. Short-circuits if it 146 // encounters any `false` members (and does not compare the `::value` members 147 // of any remaining arguments). 148 // 149 // This metafunction is designed to be a drop-in replacement for the C++17 150 // `std::conjunction` metafunction. 151 template <typename... Ts> 152 struct conjunction; 153 154 template <typename T, typename... Ts> 155 struct conjunction<T, Ts...> 156 : std::conditional<T::value, conjunction<Ts...>, T>::type {}; 157 158 template <typename T> 159 struct conjunction<T> : T {}; 160 161 template <> 162 struct conjunction<> : std::true_type {}; 163 164 // disjunction 165 // 166 // Performs a compile-time logical OR operation on the passed types (which 167 // must have `::value` members convertible to `bool`. Short-circuits if it 168 // encounters any `true` members (and does not compare the `::value` members 169 // of any remaining arguments). 170 // 171 // This metafunction is designed to be a drop-in replacement for the C++17 172 // `std::disjunction` metafunction. 173 template <typename... Ts> 174 struct disjunction; 175 176 template <typename T, typename... Ts> 177 struct disjunction<T, Ts...> : 178 std::conditional<T::value, T, disjunction<Ts...>>::type {}; 179 180 template <typename T> 181 struct disjunction<T> : T {}; 182 183 template <> 184 struct disjunction<> : std::false_type {}; 185 186 // negation 187 // 188 // Performs a compile-time logical NOT operation on the passed type (which 189 // must have `::value` members convertible to `bool`. 190 // 191 // This metafunction is designed to be a drop-in replacement for the C++17 192 // `std::negation` metafunction. 193 template <typename T> 194 struct negation : std::integral_constant<bool, !T::value> {}; 195 196 // is_trivially_destructible() 197 // 198 // Determines whether the passed type `T` is trivially destructable. 199 // 200 // This metafunction is designed to be a drop-in replacement for the C++11 201 // `std::is_trivially_destructible()` metafunction for platforms that have 202 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 203 // fully support C++11, we check whether this yields the same result as the std 204 // implementation. 205 // 206 // NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= 207 // 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always 208 // be present. These extensions are documented at 209 // https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. 210 template <typename T> 211 struct is_trivially_destructible 212 : std::integral_constant<bool, __has_trivial_destructor(T) && 213 std::is_destructible<T>::value> { 214 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 215 private: 216 static constexpr bool compliant = std::is_trivially_destructible<T>::value == 217 is_trivially_destructible::value; 218 static_assert(compliant || std::is_trivially_destructible<T>::value, 219 "Not compliant with std::is_trivially_destructible; " 220 "Standard: false, Implementation: true"); 221 static_assert(compliant || !std::is_trivially_destructible<T>::value, 222 "Not compliant with std::is_trivially_destructible; " 223 "Standard: true, Implementation: false"); 224 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 225 }; 226 227 // is_trivially_default_constructible() 228 // 229 // Determines whether the passed type `T` is trivially default constructible. 230 // 231 // This metafunction is designed to be a drop-in replacement for the C++11 232 // `std::is_trivially_default_constructible()` metafunction for platforms that 233 // have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that 234 // do fully support C++11, we check whether this yields the same result as the 235 // std implementation. 236 // 237 // NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] 238 // "The predicate condition for a template specialization is_constructible<T, 239 // Args...> shall be satisfied if and only if the following variable 240 // definition would be well-formed for some invented variable t: 241 // 242 // T t(declval<Args>()...); 243 // 244 // is_trivially_constructible<T, Args...> additionally requires that the 245 // variable definition does not call any operation that is not trivial. 246 // For the purposes of this check, the call to std::declval is considered 247 // trivial." 248 // 249 // Notes from http://en.cppreference.com/w/cpp/types/is_constructible: 250 // In many implementations, is_nothrow_constructible also checks if the 251 // destructor throws because it is effectively noexcept(T(arg)). Same 252 // applies to is_trivially_constructible, which, in these implementations, also 253 // requires that the destructor is trivial. 254 // GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 255 // LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. 256 // 257 // "T obj();" need to be well-formed and not call any nontrivial operation. 258 // Nontrivially destructible types will cause the expression to be nontrivial. 259 template <typename T> 260 struct is_trivially_default_constructible 261 : std::integral_constant<bool, __has_trivial_constructor(T) && 262 std::is_default_constructible<T>::value && 263 is_trivially_destructible<T>::value> { 264 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 265 private: 266 static constexpr bool compliant = 267 std::is_trivially_default_constructible<T>::value == 268 is_trivially_default_constructible::value; 269 static_assert(compliant || std::is_trivially_default_constructible<T>::value, 270 "Not compliant with std::is_trivially_default_constructible; " 271 "Standard: false, Implementation: true"); 272 static_assert(compliant || !std::is_trivially_default_constructible<T>::value, 273 "Not compliant with std::is_trivially_default_constructible; " 274 "Standard: true, Implementation: false"); 275 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 276 }; 277 278 // is_trivially_copy_constructible() 279 // 280 // Determines whether the passed type `T` is trivially copy constructible. 281 // 282 // This metafunction is designed to be a drop-in replacement for the C++11 283 // `std::is_trivially_copy_constructible()` metafunction for platforms that have 284 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 285 // fully support C++11, we check whether this yields the same result as the std 286 // implementation. 287 // 288 // NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any 289 // nontrivial operation. Nontrivially destructible types will cause the 290 // expression to be nontrivial. 291 template <typename T> 292 struct is_trivially_copy_constructible 293 : std::integral_constant<bool, __has_trivial_copy(T) && 294 std::is_copy_constructible<T>::value && 295 is_trivially_destructible<T>::value> { 296 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 297 private: 298 static constexpr bool compliant = 299 std::is_trivially_copy_constructible<T>::value == 300 is_trivially_copy_constructible::value; 301 static_assert(compliant || std::is_trivially_copy_constructible<T>::value, 302 "Not compliant with std::is_trivially_copy_constructible; " 303 "Standard: false, Implementation: true"); 304 static_assert(compliant || !std::is_trivially_copy_constructible<T>::value, 305 "Not compliant with std::is_trivially_copy_constructible; " 306 "Standard: true, Implementation: false"); 307 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 308 }; 309 310 // is_trivially_copy_assignable() 311 // 312 // Determines whether the passed type `T` is trivially copy assignable. 313 // 314 // This metafunction is designed to be a drop-in replacement for the C++11 315 // `std::is_trivially_copy_assignable()` metafunction for platforms that have 316 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 317 // fully support C++11, we check whether this yields the same result as the std 318 // implementation. 319 // 320 // NOTE: `is_assignable<T, U>::value` is `true` if the expression 321 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated 322 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no 323 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply 324 // `is_trivially_assignable<T&, const T&>`. 325 template <typename T> 326 struct is_trivially_copy_assignable 327 : std::integral_constant< 328 bool, __has_trivial_assign(typename std::remove_reference<T>::type) && 329 absl::is_copy_assignable<T>::value> { 330 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 331 private: 332 static constexpr bool compliant = 333 std::is_trivially_copy_assignable<T>::value == 334 is_trivially_copy_assignable::value; 335 static_assert(compliant || std::is_trivially_copy_assignable<T>::value, 336 "Not compliant with std::is_trivially_copy_assignable; " 337 "Standard: false, Implementation: true"); 338 static_assert(compliant || !std::is_trivially_copy_assignable<T>::value, 339 "Not compliant with std::is_trivially_copy_assignable; " 340 "Standard: true, Implementation: false"); 341 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 342 }; 343 344 // ----------------------------------------------------------------------------- 345 // C++14 "_t" trait aliases 346 // ----------------------------------------------------------------------------- 347 348 template <typename T> 349 using remove_cv_t = typename std::remove_cv<T>::type; 350 351 template <typename T> 352 using remove_const_t = typename std::remove_const<T>::type; 353 354 template <typename T> 355 using remove_volatile_t = typename std::remove_volatile<T>::type; 356 357 template <typename T> 358 using add_cv_t = typename std::add_cv<T>::type; 359 360 template <typename T> 361 using add_const_t = typename std::add_const<T>::type; 362 363 template <typename T> 364 using add_volatile_t = typename std::add_volatile<T>::type; 365 366 template <typename T> 367 using remove_reference_t = typename std::remove_reference<T>::type; 368 369 template <typename T> 370 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type; 371 372 template <typename T> 373 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type; 374 375 template <typename T> 376 using remove_pointer_t = typename std::remove_pointer<T>::type; 377 378 template <typename T> 379 using add_pointer_t = typename std::add_pointer<T>::type; 380 381 template <typename T> 382 using make_signed_t = typename std::make_signed<T>::type; 383 384 template <typename T> 385 using make_unsigned_t = typename std::make_unsigned<T>::type; 386 387 template <typename T> 388 using remove_extent_t = typename std::remove_extent<T>::type; 389 390 template <typename T> 391 using remove_all_extents_t = typename std::remove_all_extents<T>::type; 392 393 template <size_t Len, size_t Align = type_traits_internal:: 394 default_alignment_of_aligned_storage<Len>::value> 395 using aligned_storage_t = typename std::aligned_storage<Len, Align>::type; 396 397 template <typename T> 398 using decay_t = typename std::decay<T>::type; 399 400 template <bool B, typename T = void> 401 using enable_if_t = typename std::enable_if<B, T>::type; 402 403 template <bool B, typename T, typename F> 404 using conditional_t = typename std::conditional<B, T, F>::type; 405 406 template <typename... T> 407 using common_type_t = typename std::common_type<T...>::type; 408 409 template <typename T> 410 using underlying_type_t = typename std::underlying_type<T>::type; 411 412 template <typename T> 413 using result_of_t = typename std::result_of<T>::type; 414 415 namespace type_traits_internal { 416 template <typename Key, typename = size_t> 417 struct IsHashable : std::false_type {}; 418 419 template <typename Key> 420 struct IsHashable<Key, 421 decltype(std::declval<std::hash<Key>>()(std::declval<Key>()))> 422 : std::true_type {}; 423 424 template <typename Key> 425 struct IsHashEnabled 426 : absl::conjunction<std::is_default_constructible<std::hash<Key>>, 427 std::is_copy_constructible<std::hash<Key>>, 428 std::is_destructible<std::hash<Key>>, 429 absl::is_copy_assignable<std::hash<Key>>, 430 IsHashable<Key>> {}; 431 432 } // namespace type_traits_internal 433 434 } // namespace absl 435 436 #endif // S2_THIRD_PARTY_ABSL_META_TYPE_TRAITS_H_ 437