35 #ifndef ABSL_META_TYPE_TRAITS_H_ 36 #define ABSL_META_TYPE_TRAITS_H_ 40 #include <type_traits> 50 namespace type_traits_internal {
53 #if defined(_MSC_VER) && !defined(__GNUC__) 55 #pragma warning(disable : 4624) 56 #endif // defined(_MSC_VER) && !defined(__GNUC__) 64 #if defined(_MSC_VER) && !defined(__GNUC__) 66 #endif // defined(_MSC_VER) && !defined(__GNUC__) 79 template <
typename... Ts>
87 template <
size_t Len,
typename T = std::aligned_storage<Len>>
90 template <
size_t Len,
size_t Align>
92 std::aligned_storage<Len, Align>> {
110 template <
class Enabler,
template <
class...>
class Op,
class... Args>
115 template <
template <
class...>
class Op,
class... Args>
120 template <
template <
class...>
class Op,
class... Args>
123 template <
class Enabler,
class To,
template <
class...>
class Op,
class... Args>
128 template <
class To,
template <
class...>
class Op,
class... Args>
130 typename
std::enable_if<std::is_convertible<Op<Args...>, To>::value>
::type,
135 template <
class To,
template <
class...>
class Op,
class... Args>
139 template <
typename T>
141 decltype(std::declval<T&>() = std::declval<const T&>());
143 template <
typename T>
148 template <
typename T>
150 type_traits_internal::IsCopyAssignableImpl, T> {
153 template <
typename T>
155 type_traits_internal::IsMoveAssignableImpl, T> {
170 template <
typename... Ts>
182 template <
typename... Ts>
185 template <
typename T,
typename... Ts>
187 : std::conditional<T::value, conjunction<Ts...>, T>::type {};
189 template <
typename T>
204 template <
typename... Ts>
207 template <
typename T,
typename... Ts>
209 std::conditional<T::value, T, disjunction<Ts...>>::type {};
211 template <
typename T>
224 template <
typename T>
225 struct negation : std::integral_constant<bool, !T::value> {};
241 template <
typename T>
243 : std::integral_constant<bool, __has_trivial_destructor(T) &&
244 std::is_destructible<T>::value> {
245 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 250 "Not compliant with std::is_trivially_destructible; " 251 "Standard: false, Implementation: true");
253 "Not compliant with std::is_trivially_destructible; " 254 "Standard: true, Implementation: false");
255 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 290 template <
typename T>
292 : std::integral_constant<bool, __has_trivial_constructor(T) &&
293 std::is_default_constructible<T>::value &&
294 is_trivially_destructible<T>::value> {
295 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 297 static constexpr
bool compliant =
301 "Not compliant with std::is_trivially_default_constructible; " 302 "Standard: false, Implementation: true");
304 "Not compliant with std::is_trivially_default_constructible; " 305 "Standard: true, Implementation: false");
306 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 322 template <
typename T>
325 std::is_object<T>::value && !std::is_array<T>::value,
326 std::is_move_constructible<
327 type_traits_internal::SingleMemberUnion<T>>,
328 std::is_reference<T>>::type::type {
329 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 331 static constexpr
bool compliant =
335 "Not compliant with std::is_trivially_move_constructible; " 336 "Standard: false, Implementation: true");
338 "Not compliant with std::is_trivially_move_constructible; " 339 "Standard: true, Implementation: false");
340 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 356 template <
typename T>
359 std::is_object<T>::value && !std::is_array<T>::value,
360 std::is_copy_constructible<
361 type_traits_internal::SingleMemberUnion<T>>,
362 std::is_lvalue_reference<T>>::type::type {
363 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 365 static constexpr
bool compliant =
369 "Not compliant with std::is_trivially_copy_constructible; " 370 "Standard: false, Implementation: true");
372 "Not compliant with std::is_trivially_copy_constructible; " 373 "Standard: true, Implementation: false");
374 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 392 template <
typename T>
395 std::is_object<T>::value && !std::is_array<T>::value,
396 std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
397 type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
399 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 401 static constexpr
bool compliant =
405 "Not compliant with std::is_trivially_move_assignable; " 406 "Standard: false, Implementation: true");
408 "Not compliant with std::is_trivially_move_assignable; " 409 "Standard: true, Implementation: false");
410 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 428 template <
typename T>
430 : std::integral_constant<
431 bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
432 absl::is_copy_assignable<T>::value> {
433 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 435 static constexpr
bool compliant =
439 "Not compliant with std::is_trivially_copy_assignable; " 440 "Standard: false, Implementation: true");
442 "Not compliant with std::is_trivially_copy_assignable; " 443 "Standard: true, Implementation: false");
444 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 447 namespace type_traits_internal {
463 template <
typename T>
466 static constexpr
bool kIsCopyOrMoveConstructible =
469 static constexpr
bool kIsCopyOrMoveAssignable =
474 static constexpr
bool kValue =
475 (__has_trivial_copy(
ExtentsRemoved) || !kIsCopyOrMoveConstructible) &&
476 (__has_trivial_assign(
ExtentsRemoved) || !kIsCopyOrMoveAssignable) &&
477 (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) &&
484 template <
typename T>
486 : std::integral_constant<
487 bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
494 template <
typename T>
497 template <
typename T>
500 template <
typename T>
503 template <
typename T>
506 template <
typename T>
509 template <
typename T>
512 template <
typename T>
515 template <
typename T>
518 template <
typename T>
521 template <
typename T>
524 template <
typename T>
527 template <
typename T>
530 template <
typename T>
533 template <
typename T>
536 template <
typename T>
543 template <
typename T>
546 template <
bool B,
typename T =
void>
549 template <
bool B,
typename T,
typename F>
552 template <
typename... T>
555 template <
typename T>
558 template <
typename T>
561 namespace type_traits_internal {
566 #if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ 567 _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) 568 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0 570 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1 573 #if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 574 template <
typename Key,
typename =
size_t>
575 struct IsHashable : std::true_type {};
576 #else // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 577 template <
typename Key,
typename =
void>
580 template <
typename Key>
584 decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
585 std::size_t>::value>> : std::true_type {};
586 #endif // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 594 static auto GetReturnType(
int)
595 -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>()));
597 static NAT GetReturnType(...);
602 "std::hash<Key> does not provide a call operator");
604 std::is_default_constructible<std::hash<Key>>::
value,
605 "std::hash<Key> must be default constructible when it is enabled");
607 std::is_copy_constructible<std::hash<Key>>::
value,
608 "std::hash<Key> must be copy constructible when it is enabled");
610 "std::hash<Key> must be copy assignable when it is enabled");
613 using ReturnType = decltype(GetReturnType<Key>(0));
616 "std::hash<Key> must return size_t");
620 template <
class... Ts>
624 template <
class... Ts>
627 Helper::Sink(Helper::DoIt<Ts>()...);
634 namespace swap_internal {
648 class IsNoexcept = std::integral_constant<
649 bool, noexcept(
swap(std::declval<T&>(), std::declval<T&>()))>>
686 namespace type_traits_internal {
697 #endif // ABSL_META_TYPE_TRAITS_H_
typename std::result_of< T >::type result_of_t
typename std::remove_volatile< T >::type remove_volatile_t
typename std::aligned_storage< Len, Align >::type aligned_storage_t
typename std::remove_reference< T >::type remove_reference_t
decltype(swap(std::declval< T & >(), std::declval< T & >())) IsSwappableImpl
typename std::add_pointer< T >::type add_pointer_t
typename std::remove_extent< T >::type remove_extent_t
typename std::enable_if< IsNoexcept::value >::type IsNothrowSwappableImpl
typename std::decay< T >::type decay_t
typename std::remove_cv< T >::type remove_cv_t
typename std::add_lvalue_reference< T >::type add_lvalue_reference_t
static std::nullptr_t DoIt()
typename std::remove_all_extents< T >::type remove_all_extents_t
decltype(std::declval< T & >()=std::declval< T && >()) IsMoveAssignableImpl
constexpr size_t Align(size_t n, size_t m)
typename std::conditional< B, T, F >::type conditional_t
typename std::remove_const< T >::type remove_const_t
typename std::enable_if< B, T >::type enable_if_t
typename std::make_unsigned< T >::type make_unsigned_t
typename std::make_signed< T >::type make_signed_t
typename std::add_cv< T >::type add_cv_t
typename std::add_const< T >::type add_const_t
void Swap(T &lhs, T &rhs) noexcept(IsNothrowSwappable< T >::value)
typename std::remove_pointer< T >::type remove_pointer_t
typename std::add_rvalue_reference< T >::type add_rvalue_reference_t
IsSwappable< void()> StdSwapIsUnconstrained
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
typename std::common_type< T... >::type common_type_t
typename type_traits_internal::VoidTImpl< Ts... >::type void_t
decltype(std::declval< T & >()=std::declval< const T & >()) IsCopyAssignableImpl
typename std::add_volatile< T >::type add_volatile_t
typename std::underlying_type< T >::type underlying_type_t
typename std::remove_all_extents< T >::type ExtentsRemoved