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 // https://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 https://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 ABSL_META_TYPE_TRAITS_H_ 36 #define ABSL_META_TYPE_TRAITS_H_ 37 38 #include <stddef.h> 39 #include <functional> 40 #include <type_traits> 41 42 #include "absl/base/config.h" 43 44 // MSVC constructibility traits do not detect destructor properties and so our 45 // implementations should not use them as a source-of-truth. 46 #if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) 47 #define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 48 #endif 49 50 namespace absl { 51 ABSL_NAMESPACE_BEGIN 52 53 // Defined and documented later on in this file. 54 template <typename T> 55 struct is_trivially_destructible; 56 57 // Defined and documented later on in this file. 58 template <typename T> 59 struct is_trivially_move_assignable; 60 61 namespace type_traits_internal { 62 63 // Silence MSVC warnings about the destructor being defined as deleted. 64 #if defined(_MSC_VER) && !defined(__GNUC__) 65 #pragma warning(push) 66 #pragma warning(disable : 4624) 67 #endif // defined(_MSC_VER) && !defined(__GNUC__) 68 69 template <class T> 70 union SingleMemberUnion { 71 T t; 72 }; 73 74 // Restore the state of the destructor warning that was silenced above. 75 #if defined(_MSC_VER) && !defined(__GNUC__) 76 #pragma warning(pop) 77 #endif // defined(_MSC_VER) && !defined(__GNUC__) 78 79 template <class T> 80 struct IsTriviallyMoveConstructibleObject 81 : std::integral_constant< 82 bool, std::is_move_constructible< 83 type_traits_internal::SingleMemberUnion<T>>::value && 84 absl::is_trivially_destructible<T>::value> {}; 85 86 template <class T> 87 struct IsTriviallyCopyConstructibleObject 88 : std::integral_constant< 89 bool, std::is_copy_constructible< 90 type_traits_internal::SingleMemberUnion<T>>::value && 91 absl::is_trivially_destructible<T>::value> {}; 92 93 template <class T> 94 struct IsTriviallyMoveAssignableReference : std::false_type {}; 95 96 template <class T> 97 struct IsTriviallyMoveAssignableReference<T&> 98 : absl::is_trivially_move_assignable<T>::type {}; 99 100 template <class T> 101 struct IsTriviallyMoveAssignableReference<T&&> 102 : absl::is_trivially_move_assignable<T>::type {}; 103 104 template <typename... Ts> 105 struct VoidTImpl { 106 using type = void; 107 }; 108 109 // This trick to retrieve a default alignment is necessary for our 110 // implementation of aligned_storage_t to be consistent with any implementation 111 // of std::aligned_storage. 112 template <size_t Len, typename T = std::aligned_storage<Len>> 113 struct default_alignment_of_aligned_storage; 114 115 template <size_t Len, size_t Align> 116 struct default_alignment_of_aligned_storage<Len, 117 std::aligned_storage<Len, Align>> { 118 static constexpr size_t value = Align; 119 }; 120 121 //////////////////////////////// 122 // Library Fundamentals V2 TS // 123 //////////////////////////////// 124 125 // NOTE: The `is_detected` family of templates here differ from the library 126 // fundamentals specification in that for library fundamentals, `Op<Args...>` is 127 // evaluated as soon as the type `is_detected<Op, Args...>` undergoes 128 // substitution, regardless of whether or not the `::value` is accessed. That 129 // is inconsistent with all other standard traits and prevents lazy evaluation 130 // in larger contexts (such as if the `is_detected` check is a trailing argument 131 // of a `conjunction`. This implementation opts to instead be lazy in the same 132 // way that the standard traits are (this "defect" of the detection idiom 133 // specifications has been reported). 134 135 template <class Enabler, template <class...> class Op, class... Args> 136 struct is_detected_impl { 137 using type = std::false_type; 138 }; 139 140 template <template <class...> class Op, class... Args> 141 struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> { 142 using type = std::true_type; 143 }; 144 145 template <template <class...> class Op, class... Args> 146 struct is_detected : is_detected_impl<void, Op, Args...>::type {}; 147 148 template <class Enabler, class To, template <class...> class Op, class... Args> 149 struct is_detected_convertible_impl { 150 using type = std::false_type; 151 }; 152 153 template <class To, template <class...> class Op, class... Args> 154 struct is_detected_convertible_impl< 155 typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type, 156 To, Op, Args...> { 157 using type = std::true_type; 158 }; 159 160 template <class To, template <class...> class Op, class... Args> 161 struct is_detected_convertible 162 : is_detected_convertible_impl<void, To, Op, Args...>::type {}; 163 164 template <typename T> 165 using IsCopyAssignableImpl = 166 decltype(std::declval<T&>() = std::declval<const T&>()); 167 168 template <typename T> 169 using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>()); 170 171 } // namespace type_traits_internal 172 173 // MSVC 19.20 has a regression that causes our workarounds to fail, but their 174 // std forms now appear to be compliant. 175 #if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920) 176 177 template <typename T> 178 using is_copy_assignable = std::is_copy_assignable<T>; 179 180 template <typename T> 181 using is_move_assignable = std::is_move_assignable<T>; 182 183 #else 184 185 template <typename T> 186 struct is_copy_assignable : type_traits_internal::is_detected< 187 type_traits_internal::IsCopyAssignableImpl, T> { 188 }; 189 190 template <typename T> 191 struct is_move_assignable : type_traits_internal::is_detected< 192 type_traits_internal::IsMoveAssignableImpl, T> { 193 }; 194 195 #endif 196 197 // void_t() 198 // 199 // Ignores the type of any its arguments and returns `void`. In general, this 200 // metafunction allows you to create a general case that maps to `void` while 201 // allowing specializations that map to specific types. 202 // 203 // This metafunction is designed to be a drop-in replacement for the C++17 204 // `std::void_t` metafunction. 205 // 206 // NOTE: `absl::void_t` does not use the standard-specified implementation so 207 // that it can remain compatible with gcc < 5.1. This can introduce slightly 208 // different behavior, such as when ordering partial specializations. 209 template <typename... Ts> 210 using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type; 211 212 // conjunction 213 // 214 // Performs a compile-time logical AND operation on the passed types (which 215 // must have `::value` members convertible to `bool`. Short-circuits if it 216 // encounters any `false` members (and does not compare the `::value` members 217 // of any remaining arguments). 218 // 219 // This metafunction is designed to be a drop-in replacement for the C++17 220 // `std::conjunction` metafunction. 221 template <typename... Ts> 222 struct conjunction : std::true_type {}; 223 224 template <typename T, typename... Ts> 225 struct conjunction<T, Ts...> 226 : std::conditional<T::value, conjunction<Ts...>, T>::type {}; 227 228 template <typename T> 229 struct conjunction<T> : T {}; 230 231 // disjunction 232 // 233 // Performs a compile-time logical OR operation on the passed types (which 234 // must have `::value` members convertible to `bool`. Short-circuits if it 235 // encounters any `true` members (and does not compare the `::value` members 236 // of any remaining arguments). 237 // 238 // This metafunction is designed to be a drop-in replacement for the C++17 239 // `std::disjunction` metafunction. 240 template <typename... Ts> 241 struct disjunction : std::false_type {}; 242 243 template <typename T, typename... Ts> 244 struct disjunction<T, Ts...> : 245 std::conditional<T::value, T, disjunction<Ts...>>::type {}; 246 247 template <typename T> 248 struct disjunction<T> : T {}; 249 250 // negation 251 // 252 // Performs a compile-time logical NOT operation on the passed type (which 253 // must have `::value` members convertible to `bool`. 254 // 255 // This metafunction is designed to be a drop-in replacement for the C++17 256 // `std::negation` metafunction. 257 template <typename T> 258 struct negation : std::integral_constant<bool, !T::value> {}; 259 260 // is_function() 261 // 262 // Determines whether the passed type `T` is a function type. 263 // 264 // This metafunction is designed to be a drop-in replacement for the C++11 265 // `std::is_function()` metafunction for platforms that have incomplete C++11 266 // support (such as libstdc++ 4.x). 267 // 268 // This metafunction works because appending `const` to a type does nothing to 269 // function types and reference types (and forms a const-qualified type 270 // otherwise). 271 template <typename T> 272 struct is_function 273 : std::integral_constant< 274 bool, !(std::is_reference<T>::value || 275 std::is_const<typename std::add_const<T>::type>::value)> {}; 276 277 // is_trivially_destructible() 278 // 279 // Determines whether the passed type `T` is trivially destructible. 280 // 281 // This metafunction is designed to be a drop-in replacement for the C++11 282 // `std::is_trivially_destructible()` metafunction for platforms that have 283 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 284 // fully support C++11, we check whether this yields the same result as the std 285 // implementation. 286 // 287 // NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= 288 // 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always 289 // be present. These extensions are documented at 290 // https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. 291 template <typename T> 292 struct is_trivially_destructible 293 : std::integral_constant<bool, __has_trivial_destructor(T) && 294 std::is_destructible<T>::value> { 295 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 296 private: 297 static constexpr bool compliant = std::is_trivially_destructible<T>::value == 298 is_trivially_destructible::value; 299 static_assert(compliant || std::is_trivially_destructible<T>::value, 300 "Not compliant with std::is_trivially_destructible; " 301 "Standard: false, Implementation: true"); 302 static_assert(compliant || !std::is_trivially_destructible<T>::value, 303 "Not compliant with std::is_trivially_destructible; " 304 "Standard: true, Implementation: false"); 305 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 306 }; 307 308 // is_trivially_default_constructible() 309 // 310 // Determines whether the passed type `T` is trivially default constructible. 311 // 312 // This metafunction is designed to be a drop-in replacement for the C++11 313 // `std::is_trivially_default_constructible()` metafunction for platforms that 314 // have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that 315 // do fully support C++11, we check whether this yields the same result as the 316 // std implementation. 317 // 318 // NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] 319 // "The predicate condition for a template specialization is_constructible<T, 320 // Args...> shall be satisfied if and only if the following variable 321 // definition would be well-formed for some invented variable t: 322 // 323 // T t(declval<Args>()...); 324 // 325 // is_trivially_constructible<T, Args...> additionally requires that the 326 // variable definition does not call any operation that is not trivial. 327 // For the purposes of this check, the call to std::declval is considered 328 // trivial." 329 // 330 // Notes from https://en.cppreference.com/w/cpp/types/is_constructible: 331 // In many implementations, is_nothrow_constructible also checks if the 332 // destructor throws because it is effectively noexcept(T(arg)). Same 333 // applies to is_trivially_constructible, which, in these implementations, also 334 // requires that the destructor is trivial. 335 // GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 336 // LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. 337 // 338 // "T obj();" need to be well-formed and not call any nontrivial operation. 339 // Nontrivially destructible types will cause the expression to be nontrivial. 340 template <typename T> 341 struct is_trivially_default_constructible 342 : std::integral_constant<bool, __has_trivial_constructor(T) && 343 std::is_default_constructible<T>::value && 344 is_trivially_destructible<T>::value> { 345 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ 346 !defined( \ 347 ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) 348 private: 349 static constexpr bool compliant = 350 std::is_trivially_default_constructible<T>::value == 351 is_trivially_default_constructible::value; 352 static_assert(compliant || std::is_trivially_default_constructible<T>::value, 353 "Not compliant with std::is_trivially_default_constructible; " 354 "Standard: false, Implementation: true"); 355 static_assert(compliant || !std::is_trivially_default_constructible<T>::value, 356 "Not compliant with std::is_trivially_default_constructible; " 357 "Standard: true, Implementation: false"); 358 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 359 }; 360 361 // is_trivially_move_constructible() 362 // 363 // Determines whether the passed type `T` is trivially move constructible. 364 // 365 // This metafunction is designed to be a drop-in replacement for the C++11 366 // `std::is_trivially_move_constructible()` metafunction for platforms that have 367 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 368 // fully support C++11, we check whether this yields the same result as the std 369 // implementation. 370 // 371 // NOTE: `T obj(declval<T>());` needs to be well-formed and not call any 372 // nontrivial operation. Nontrivially destructible types will cause the 373 // expression to be nontrivial. 374 template <typename T> 375 struct is_trivially_move_constructible 376 : std::conditional< 377 std::is_object<T>::value && !std::is_array<T>::value, 378 type_traits_internal::IsTriviallyMoveConstructibleObject<T>, 379 std::is_reference<T>>::type::type { 380 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ 381 !defined( \ 382 ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) 383 private: 384 static constexpr bool compliant = 385 std::is_trivially_move_constructible<T>::value == 386 is_trivially_move_constructible::value; 387 static_assert(compliant || std::is_trivially_move_constructible<T>::value, 388 "Not compliant with std::is_trivially_move_constructible; " 389 "Standard: false, Implementation: true"); 390 static_assert(compliant || !std::is_trivially_move_constructible<T>::value, 391 "Not compliant with std::is_trivially_move_constructible; " 392 "Standard: true, Implementation: false"); 393 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 394 }; 395 396 // is_trivially_copy_constructible() 397 // 398 // Determines whether the passed type `T` is trivially copy constructible. 399 // 400 // This metafunction is designed to be a drop-in replacement for the C++11 401 // `std::is_trivially_copy_constructible()` metafunction for platforms that have 402 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 403 // fully support C++11, we check whether this yields the same result as the std 404 // implementation. 405 // 406 // NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any 407 // nontrivial operation. Nontrivially destructible types will cause the 408 // expression to be nontrivial. 409 template <typename T> 410 struct is_trivially_copy_constructible 411 : std::conditional< 412 std::is_object<T>::value && !std::is_array<T>::value, 413 type_traits_internal::IsTriviallyCopyConstructibleObject<T>, 414 std::is_lvalue_reference<T>>::type::type { 415 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ 416 !defined( \ 417 ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) 418 private: 419 static constexpr bool compliant = 420 std::is_trivially_copy_constructible<T>::value == 421 is_trivially_copy_constructible::value; 422 static_assert(compliant || std::is_trivially_copy_constructible<T>::value, 423 "Not compliant with std::is_trivially_copy_constructible; " 424 "Standard: false, Implementation: true"); 425 static_assert(compliant || !std::is_trivially_copy_constructible<T>::value, 426 "Not compliant with std::is_trivially_copy_constructible; " 427 "Standard: true, Implementation: false"); 428 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 429 }; 430 431 // is_trivially_move_assignable() 432 // 433 // Determines whether the passed type `T` is trivially move assignable. 434 // 435 // This metafunction is designed to be a drop-in replacement for the C++11 436 // `std::is_trivially_move_assignable()` metafunction for platforms that have 437 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 438 // fully support C++11, we check whether this yields the same result as the std 439 // implementation. 440 // 441 // NOTE: `is_assignable<T, U>::value` is `true` if the expression 442 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated 443 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no 444 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply 445 // `is_trivially_assignable<T&, T>`. 446 template <typename T> 447 struct is_trivially_move_assignable 448 : std::conditional< 449 std::is_object<T>::value && !std::is_array<T>::value && 450 std::is_move_assignable<T>::value, 451 std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>, 452 type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type:: 453 type { 454 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 455 private: 456 static constexpr bool compliant = 457 std::is_trivially_move_assignable<T>::value == 458 is_trivially_move_assignable::value; 459 static_assert(compliant || std::is_trivially_move_assignable<T>::value, 460 "Not compliant with std::is_trivially_move_assignable; " 461 "Standard: false, Implementation: true"); 462 static_assert(compliant || !std::is_trivially_move_assignable<T>::value, 463 "Not compliant with std::is_trivially_move_assignable; " 464 "Standard: true, Implementation: false"); 465 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 466 }; 467 468 // is_trivially_copy_assignable() 469 // 470 // Determines whether the passed type `T` is trivially copy assignable. 471 // 472 // This metafunction is designed to be a drop-in replacement for the C++11 473 // `std::is_trivially_copy_assignable()` metafunction for platforms that have 474 // incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do 475 // fully support C++11, we check whether this yields the same result as the std 476 // implementation. 477 // 478 // NOTE: `is_assignable<T, U>::value` is `true` if the expression 479 // `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated 480 // operand. `is_trivially_assignable<T, U>` requires the assignment to call no 481 // operation that is not trivial. `is_trivially_copy_assignable<T>` is simply 482 // `is_trivially_assignable<T&, const T&>`. 483 template <typename T> 484 struct is_trivially_copy_assignable 485 : std::integral_constant< 486 bool, __has_trivial_assign(typename std::remove_reference<T>::type) && 487 absl::is_copy_assignable<T>::value> { 488 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 489 private: 490 static constexpr bool compliant = 491 std::is_trivially_copy_assignable<T>::value == 492 is_trivially_copy_assignable::value; 493 static_assert(compliant || std::is_trivially_copy_assignable<T>::value, 494 "Not compliant with std::is_trivially_copy_assignable; " 495 "Standard: false, Implementation: true"); 496 static_assert(compliant || !std::is_trivially_copy_assignable<T>::value, 497 "Not compliant with std::is_trivially_copy_assignable; " 498 "Standard: true, Implementation: false"); 499 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 500 }; 501 502 #if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L 503 template <typename T> 504 using remove_cvref = std::remove_cvref<T>; 505 506 template <typename T> 507 using remove_cvref_t = typename std::remove_cvref<T>::type; 508 #else 509 // remove_cvref() 510 // 511 // C++11 compatible implementation of std::remove_cvref which was added in 512 // C++20. 513 template <typename T> 514 struct remove_cvref { 515 using type = 516 typename std::remove_cv<typename std::remove_reference<T>::type>::type; 517 }; 518 519 template <typename T> 520 using remove_cvref_t = typename remove_cvref<T>::type; 521 #endif 522 523 namespace type_traits_internal { 524 // is_trivially_copyable() 525 // 526 // Determines whether the passed type `T` is trivially copyable. 527 // 528 // This metafunction is designed to be a drop-in replacement for the C++11 529 // `std::is_trivially_copyable()` metafunction for platforms that have 530 // incomplete C++11 support (such as libstdc++ 4.x). We use the C++17 definition 531 // of TriviallyCopyable. 532 // 533 // NOTE: `is_trivially_copyable<T>::value` is `true` if all of T's copy/move 534 // constructors/assignment operators are trivial or deleted, T has at least 535 // one non-deleted copy/move constructor/assignment operator, and T is trivially 536 // destructible. Arrays of trivially copyable types are trivially copyable. 537 // 538 // We expose this metafunction only for internal use within absl. 539 template <typename T> 540 class is_trivially_copyable_impl { 541 using ExtentsRemoved = typename std::remove_all_extents<T>::type; 542 static constexpr bool kIsCopyOrMoveConstructible = 543 std::is_copy_constructible<ExtentsRemoved>::value || 544 std::is_move_constructible<ExtentsRemoved>::value; 545 static constexpr bool kIsCopyOrMoveAssignable = 546 absl::is_copy_assignable<ExtentsRemoved>::value || 547 absl::is_move_assignable<ExtentsRemoved>::value; 548 549 public: 550 static constexpr bool kValue = 551 (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) && 552 (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) && 553 (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) && 554 is_trivially_destructible<ExtentsRemoved>::value && 555 // We need to check for this explicitly because otherwise we'll say 556 // references are trivial copyable when compiled by MSVC. 557 !std::is_reference<ExtentsRemoved>::value; 558 }; 559 560 template <typename T> 561 struct is_trivially_copyable 562 : std::integral_constant< 563 bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {}; 564 } // namespace type_traits_internal 565 566 // ----------------------------------------------------------------------------- 567 // C++14 "_t" trait aliases 568 // ----------------------------------------------------------------------------- 569 570 template <typename T> 571 using remove_cv_t = typename std::remove_cv<T>::type; 572 573 template <typename T> 574 using remove_const_t = typename std::remove_const<T>::type; 575 576 template <typename T> 577 using remove_volatile_t = typename std::remove_volatile<T>::type; 578 579 template <typename T> 580 using add_cv_t = typename std::add_cv<T>::type; 581 582 template <typename T> 583 using add_const_t = typename std::add_const<T>::type; 584 585 template <typename T> 586 using add_volatile_t = typename std::add_volatile<T>::type; 587 588 template <typename T> 589 using remove_reference_t = typename std::remove_reference<T>::type; 590 591 template <typename T> 592 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type; 593 594 template <typename T> 595 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type; 596 597 template <typename T> 598 using remove_pointer_t = typename std::remove_pointer<T>::type; 599 600 template <typename T> 601 using add_pointer_t = typename std::add_pointer<T>::type; 602 603 template <typename T> 604 using make_signed_t = typename std::make_signed<T>::type; 605 606 template <typename T> 607 using make_unsigned_t = typename std::make_unsigned<T>::type; 608 609 template <typename T> 610 using remove_extent_t = typename std::remove_extent<T>::type; 611 612 template <typename T> 613 using remove_all_extents_t = typename std::remove_all_extents<T>::type; 614 615 template <size_t Len, size_t Align = type_traits_internal:: 616 default_alignment_of_aligned_storage<Len>::value> 617 using aligned_storage_t = typename std::aligned_storage<Len, Align>::type; 618 619 template <typename T> 620 using decay_t = typename std::decay<T>::type; 621 622 template <bool B, typename T = void> 623 using enable_if_t = typename std::enable_if<B, T>::type; 624 625 template <bool B, typename T, typename F> 626 using conditional_t = typename std::conditional<B, T, F>::type; 627 628 template <typename... T> 629 using common_type_t = typename std::common_type<T...>::type; 630 631 template <typename T> 632 using underlying_type_t = typename std::underlying_type<T>::type; 633 634 635 namespace type_traits_internal { 636 637 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 638 // std::result_of is deprecated (C++17) or removed (C++20) 639 template<typename> struct result_of; 640 template<typename F, typename... Args> 641 struct result_of<F(Args...)> : std::invoke_result<F, Args...> {}; 642 #else 643 template<typename F> using result_of = std::result_of<F>; 644 #endif 645 646 } // namespace type_traits_internal 647 648 template<typename F> 649 using result_of_t = typename type_traits_internal::result_of<F>::type; 650 651 namespace type_traits_internal { 652 // In MSVC we can't probe std::hash or stdext::hash because it triggers a 653 // static_assert instead of failing substitution. Libc++ prior to 4.0 654 // also used a static_assert. 655 // 656 #if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ 657 _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) 658 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0 659 #else 660 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1 661 #endif 662 663 #if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 664 template <typename Key, typename = size_t> 665 struct IsHashable : std::true_type {}; 666 #else // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 667 template <typename Key, typename = void> 668 struct IsHashable : std::false_type {}; 669 670 template <typename Key> 671 struct IsHashable< 672 Key, 673 absl::enable_if_t<std::is_convertible< 674 decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())), 675 std::size_t>::value>> : std::true_type {}; 676 #endif // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 677 678 struct AssertHashEnabledHelper { 679 private: 680 static void Sink(...) {} 681 struct NAT {}; 682 683 template <class Key> 684 static auto GetReturnType(int) 685 -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>())); 686 template <class Key> 687 static NAT GetReturnType(...); 688 689 template <class Key> 690 static std::nullptr_t DoIt() { 691 static_assert(IsHashable<Key>::value, 692 "std::hash<Key> does not provide a call operator"); 693 static_assert( 694 std::is_default_constructible<std::hash<Key>>::value, 695 "std::hash<Key> must be default constructible when it is enabled"); 696 static_assert( 697 std::is_copy_constructible<std::hash<Key>>::value, 698 "std::hash<Key> must be copy constructible when it is enabled"); 699 static_assert(absl::is_copy_assignable<std::hash<Key>>::value, 700 "std::hash<Key> must be copy assignable when it is enabled"); 701 // is_destructible is unchecked as it's implied by each of the 702 // is_constructible checks. 703 using ReturnType = decltype(GetReturnType<Key>(0)); 704 static_assert(std::is_same<ReturnType, NAT>::value || 705 std::is_same<ReturnType, size_t>::value, 706 "std::hash<Key> must return size_t"); 707 return nullptr; 708 } 709 710 template <class... Ts> 711 friend void AssertHashEnabled(); 712 }; 713 714 template <class... Ts> 715 inline void AssertHashEnabled() { 716 using Helper = AssertHashEnabledHelper; 717 Helper::Sink(Helper::DoIt<Ts>()...); 718 } 719 720 } // namespace type_traits_internal 721 722 // An internal namespace that is required to implement the C++17 swap traits. 723 // It is not further nested in type_traits_internal to avoid long symbol names. 724 namespace swap_internal { 725 726 // Necessary for the traits. 727 using std::swap; 728 729 // This declaration prevents global `swap` and `absl::swap` overloads from being 730 // considered unless ADL picks them up. 731 void swap(); 732 733 template <class T> 734 using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>())); 735 736 // NOTE: This dance with the default template parameter is for MSVC. 737 template <class T, 738 class IsNoexcept = std::integral_constant< 739 bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>> 740 using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type; 741 742 // IsSwappable 743 // 744 // Determines whether the standard swap idiom is a valid expression for 745 // arguments of type `T`. 746 template <class T> 747 struct IsSwappable 748 : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {}; 749 750 // IsNothrowSwappable 751 // 752 // Determines whether the standard swap idiom is a valid expression for 753 // arguments of type `T` and is noexcept. 754 template <class T> 755 struct IsNothrowSwappable 756 : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {}; 757 758 // Swap() 759 // 760 // Performs the swap idiom from a namespace where valid candidates may only be 761 // found in `std` or via ADL. 762 template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0> 763 void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) { 764 swap(lhs, rhs); 765 } 766 767 // StdSwapIsUnconstrained 768 // 769 // Some standard library implementations are broken in that they do not 770 // constrain `std::swap`. This will effectively tell us if we are dealing with 771 // one of those implementations. 772 using StdSwapIsUnconstrained = IsSwappable<void()>; 773 774 } // namespace swap_internal 775 776 namespace type_traits_internal { 777 778 // Make the swap-related traits/function accessible from this namespace. 779 using swap_internal::IsNothrowSwappable; 780 using swap_internal::IsSwappable; 781 using swap_internal::Swap; 782 using swap_internal::StdSwapIsUnconstrained; 783 784 } // namespace type_traits_internal 785 ABSL_NAMESPACE_END 786 } // namespace absl 787 788 #endif // ABSL_META_TYPE_TRAITS_H_ 789