File indexing completed on 2024-11-15 09:01:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef ABSL_META_TYPE_TRAITS_H_
0036 #define ABSL_META_TYPE_TRAITS_H_
0037
0038 #include <cstddef>
0039 #include <functional>
0040 #include <type_traits>
0041
0042 #include "absl/base/attributes.h"
0043 #include "absl/base/config.h"
0044
0045
0046
0047 #if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
0048 #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__
0049 #else
0050 #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t)
0051 #endif
0052
0053 namespace absl {
0054 ABSL_NAMESPACE_BEGIN
0055
0056 namespace type_traits_internal {
0057
0058 template <typename... Ts>
0059 struct VoidTImpl {
0060 using type = void;
0061 };
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <class Enabler, template <class...> class Op, class... Args>
0078 struct is_detected_impl {
0079 using type = std::false_type;
0080 };
0081
0082 template <template <class...> class Op, class... Args>
0083 struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> {
0084 using type = std::true_type;
0085 };
0086
0087 template <template <class...> class Op, class... Args>
0088 struct is_detected : is_detected_impl<void, Op, Args...>::type {};
0089
0090 template <class Enabler, class To, template <class...> class Op, class... Args>
0091 struct is_detected_convertible_impl {
0092 using type = std::false_type;
0093 };
0094
0095 template <class To, template <class...> class Op, class... Args>
0096 struct is_detected_convertible_impl<
0097 typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type,
0098 To, Op, Args...> {
0099 using type = std::true_type;
0100 };
0101
0102 template <class To, template <class...> class Op, class... Args>
0103 struct is_detected_convertible
0104 : is_detected_convertible_impl<void, To, Op, Args...>::type {};
0105
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 template <typename... Ts>
0121 using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type;
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 template <typename... Ts>
0133 struct conjunction : std::true_type {};
0134
0135 template <typename T, typename... Ts>
0136 struct conjunction<T, Ts...>
0137 : std::conditional<T::value, conjunction<Ts...>, T>::type {};
0138
0139 template <typename T>
0140 struct conjunction<T> : T {};
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 template <typename... Ts>
0152 struct disjunction : std::false_type {};
0153
0154 template <typename T, typename... Ts>
0155 struct disjunction<T, Ts...> :
0156 std::conditional<T::value, T, disjunction<Ts...>>::type {};
0157
0158 template <typename T>
0159 struct disjunction<T> : T {};
0160
0161
0162
0163
0164
0165
0166
0167
0168 template <typename T>
0169 struct negation : std::integral_constant<bool, !T::value> {};
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template <typename T>
0183 struct is_function
0184 : std::integral_constant<
0185 bool, !(std::is_reference<T>::value ||
0186 std::is_const<typename std::add_const<T>::type>::value)> {};
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 using std::is_copy_assignable;
0204 using std::is_move_assignable;
0205 using std::is_trivially_copy_assignable;
0206 using std::is_trivially_copy_constructible;
0207 using std::is_trivially_default_constructible;
0208 using std::is_trivially_destructible;
0209 using std::is_trivially_move_assignable;
0210 using std::is_trivially_move_constructible;
0211
0212 #if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L
0213 template <typename T>
0214 using remove_cvref = std::remove_cvref<T>;
0215
0216 template <typename T>
0217 using remove_cvref_t = typename std::remove_cvref<T>::type;
0218 #else
0219
0220
0221
0222
0223 template <typename T>
0224 struct remove_cvref {
0225 using type =
0226 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
0227 };
0228
0229 template <typename T>
0230 using remove_cvref_t = typename remove_cvref<T>::type;
0231 #endif
0232
0233
0234
0235
0236
0237 template <typename T>
0238 using remove_cv_t = typename std::remove_cv<T>::type;
0239
0240 template <typename T>
0241 using remove_const_t = typename std::remove_const<T>::type;
0242
0243 template <typename T>
0244 using remove_volatile_t = typename std::remove_volatile<T>::type;
0245
0246 template <typename T>
0247 using add_cv_t = typename std::add_cv<T>::type;
0248
0249 template <typename T>
0250 using add_const_t = typename std::add_const<T>::type;
0251
0252 template <typename T>
0253 using add_volatile_t = typename std::add_volatile<T>::type;
0254
0255 template <typename T>
0256 using remove_reference_t = typename std::remove_reference<T>::type;
0257
0258 template <typename T>
0259 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
0260
0261 template <typename T>
0262 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
0263
0264 template <typename T>
0265 using remove_pointer_t = typename std::remove_pointer<T>::type;
0266
0267 template <typename T>
0268 using add_pointer_t = typename std::add_pointer<T>::type;
0269
0270 template <typename T>
0271 using make_signed_t = typename std::make_signed<T>::type;
0272
0273 template <typename T>
0274 using make_unsigned_t = typename std::make_unsigned<T>::type;
0275
0276 template <typename T>
0277 using remove_extent_t = typename std::remove_extent<T>::type;
0278
0279 template <typename T>
0280 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
0281
0282 ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
0283 namespace type_traits_internal {
0284
0285
0286
0287 template <size_t Len, typename T = std::aligned_storage<Len>>
0288 struct default_alignment_of_aligned_storage;
0289
0290 template <size_t Len, size_t Align>
0291 struct default_alignment_of_aligned_storage<
0292 Len, std::aligned_storage<Len, Align>> {
0293 static constexpr size_t value = Align;
0294 };
0295 }
0296
0297
0298 template <size_t Len, size_t Align = type_traits_internal::
0299 default_alignment_of_aligned_storage<Len>::value>
0300 using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
0301 ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
0302
0303 template <typename T>
0304 using decay_t = typename std::decay<T>::type;
0305
0306 template <bool B, typename T = void>
0307 using enable_if_t = typename std::enable_if<B, T>::type;
0308
0309 template <bool B, typename T, typename F>
0310 using conditional_t = typename std::conditional<B, T, F>::type;
0311
0312 template <typename... T>
0313 using common_type_t = typename std::common_type<T...>::type;
0314
0315 template <typename T>
0316 using underlying_type_t = typename std::underlying_type<T>::type;
0317
0318
0319 namespace type_traits_internal {
0320
0321 #if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \
0322 (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
0323
0324 template<typename> struct result_of;
0325 template<typename F, typename... Args>
0326 struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
0327 #else
0328 template<typename F> using result_of = std::result_of<F>;
0329 #endif
0330
0331 }
0332
0333 template<typename F>
0334 using result_of_t = typename type_traits_internal::result_of<F>::type;
0335
0336 namespace type_traits_internal {
0337
0338
0339
0340
0341 #if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \
0342 _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11)
0343 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0
0344 #else
0345 #define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1
0346 #endif
0347
0348 #if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
0349 template <typename Key, typename = size_t>
0350 struct IsHashable : std::true_type {};
0351 #else
0352 template <typename Key, typename = void>
0353 struct IsHashable : std::false_type {};
0354
0355 template <typename Key>
0356 struct IsHashable<
0357 Key,
0358 absl::enable_if_t<std::is_convertible<
0359 decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
0360 std::size_t>::value>> : std::true_type {};
0361 #endif
0362
0363 struct AssertHashEnabledHelper {
0364 private:
0365 static void Sink(...) {}
0366 struct NAT {};
0367
0368 template <class Key>
0369 static auto GetReturnType(int)
0370 -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>()));
0371 template <class Key>
0372 static NAT GetReturnType(...);
0373
0374 template <class Key>
0375 static std::nullptr_t DoIt() {
0376 static_assert(IsHashable<Key>::value,
0377 "std::hash<Key> does not provide a call operator");
0378 static_assert(
0379 std::is_default_constructible<std::hash<Key>>::value,
0380 "std::hash<Key> must be default constructible when it is enabled");
0381 static_assert(
0382 std::is_copy_constructible<std::hash<Key>>::value,
0383 "std::hash<Key> must be copy constructible when it is enabled");
0384 static_assert(absl::is_copy_assignable<std::hash<Key>>::value,
0385 "std::hash<Key> must be copy assignable when it is enabled");
0386
0387
0388 using ReturnType = decltype(GetReturnType<Key>(0));
0389 static_assert(std::is_same<ReturnType, NAT>::value ||
0390 std::is_same<ReturnType, size_t>::value,
0391 "std::hash<Key> must return size_t");
0392 return nullptr;
0393 }
0394
0395 template <class... Ts>
0396 friend void AssertHashEnabled();
0397 };
0398
0399 template <class... Ts>
0400 inline void AssertHashEnabled() {
0401 using Helper = AssertHashEnabledHelper;
0402 Helper::Sink(Helper::DoIt<Ts>()...);
0403 }
0404
0405 }
0406
0407
0408
0409 namespace swap_internal {
0410
0411
0412 using std::swap;
0413
0414
0415
0416 void swap();
0417
0418 template <class T>
0419 using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));
0420
0421
0422 template <class T,
0423 class IsNoexcept = std::integral_constant<
0424 bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>>
0425 using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type;
0426
0427
0428
0429
0430
0431 template <class T>
0432 struct IsSwappable
0433 : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};
0434
0435
0436
0437
0438
0439 template <class T>
0440 struct IsNothrowSwappable
0441 : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};
0442
0443
0444
0445
0446
0447 template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0>
0448 void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
0449 swap(lhs, rhs);
0450 }
0451
0452
0453
0454
0455
0456
0457 using StdSwapIsUnconstrained = IsSwappable<void()>;
0458
0459 }
0460
0461 namespace type_traits_internal {
0462
0463
0464 using swap_internal::IsNothrowSwappable;
0465 using swap_internal::IsSwappable;
0466 using swap_internal::Swap;
0467 using swap_internal::StdSwapIsUnconstrained;
0468
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506 #if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \
0507 !(defined(__clang__) && (defined(_WIN32) || defined(_WIN64))) && \
0508 !defined(__NVCC__)
0509 template <class T>
0510 struct is_trivially_relocatable
0511 : std::integral_constant<bool, __is_trivially_relocatable(T)> {};
0512 #else
0513
0514
0515
0516 template <class T>
0517 struct is_trivially_relocatable
0518 : absl::conjunction<absl::is_trivially_move_constructible<T>,
0519 absl::is_trivially_destructible<T>> {};
0520 #endif
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552 #if defined(ABSL_HAVE_CONSTANT_EVALUATED)
0553 constexpr bool is_constant_evaluated() noexcept {
0554 #ifdef __cpp_lib_is_constant_evaluated
0555 return std::is_constant_evaluated();
0556 #elif ABSL_HAVE_BUILTIN(__builtin_is_constant_evaluated)
0557 return __builtin_is_constant_evaluated();
0558 #endif
0559 }
0560 #endif
0561 ABSL_NAMESPACE_END
0562 }
0563
0564 #endif