24 #include <type_traits> 29 #if __has_include(<bits/c++config.h>) 36 #include <bits/c++config.h> 39 #define FOLLY_CREATE_HAS_MEMBER_TYPE_TRAITS(classname, type_name) \ 40 template <typename TTheClass_> \ 41 struct classname##__folly_traits_impl__ { \ 42 template <typename UTheClass_> \ 43 static constexpr bool test(typename UTheClass_::type_name*) { \ 47 static constexpr bool test(...) { \ 51 template <typename TTheClass_> \ 52 using classname = typename std::conditional< \ 53 classname##__folly_traits_impl__<TTheClass_>::template test<TTheClass_>( \ 56 std::false_type>::type 58 #define FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, cv_qual) \ 59 template <typename TTheClass_, typename RTheReturn_, typename... TTheArgs_> \ 60 struct classname##__folly_traits_impl__< \ 62 RTheReturn_(TTheArgs_...) cv_qual> { \ 64 typename UTheClass_, \ 65 RTheReturn_ (UTheClass_::*)(TTheArgs_...) cv_qual> \ 67 template <typename UTheClass_> \ 68 static std::true_type test(sfinae<UTheClass_, &UTheClass_::func_name>*); \ 70 static std::false_type test(...); \ 121 #define FOLLY_CREATE_HAS_MEMBER_FN_TRAITS(classname, func_name) \ 122 template <typename, typename> \ 123 struct classname##__folly_traits_impl__; \ 124 FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, ); \ 125 FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, const); \ 126 FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL( \ 127 classname, func_name, volatile); \ 128 FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL( \ 129 classname, func_name, volatile const); \ 130 template <typename TTheClass_, typename TTheSignature_> \ 132 decltype(classname##__folly_traits_impl__<TTheClass_, TTheSignature_>:: \ 133 template test<TTheClass_>(nullptr)) 137 #if __cpp_lib_bool_constant || _MSC_VER 149 template <std::
size_t I>
170 template <
typename T>
177 template <
typename T>
182 template <
typename T>
186 template <
typename Src>
188 template <
typename Dst>
191 template <
typename Src>
193 template <
typename Dst>
196 template <
typename Src>
198 template <
typename Dst>
201 template <
typename Src>
203 template <
typename Dst>
206 template <
typename Src>
208 template <
typename Dst>
211 template <
typename Src>
213 template <
typename Dst>
219 template <
typename Src,
typename Dst>
223 template <
typename Src,
typename Dst>
292 namespace traits_detail {
293 template <
class T,
class...>
299 template <
class T,
class... Ts>
301 template <
class... Ts>
305 #if defined(__clang__) && !defined(_LIBCPP_VERSION) 308 #elif defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 358 namespace traits_detail {
360 #define FOLLY_HAS_TRUE_XXX(name) \ 361 FOLLY_CREATE_HAS_MEMBER_TYPE_TRAITS(has_##name, name); \ 363 struct name##_is_true : std::is_same<typename T::name, std::true_type> {}; \ 365 struct has_true_##name : std::conditional< \ 366 has_##name<T>::value, \ 368 std::false_type>::type {} 373 #undef FOLLY_HAS_TRUE_XXX 390 namespace traits_detail_IsEqualityComparable {
393 template <
class T,
class U = T>
395 : std::is_convertible<
396 decltype(std::declval<T>() == std::declval<U>()),
403 namespace traits_detail_IsLessThanComparable {
406 template <
class T,
class U = T>
408 : std::is_convertible<
409 decltype(std::declval<T>() < std::declval<U>()),
413 using traits_detail_IsLessThanComparable::
414 IsLessThanComparable;
416 namespace traits_detail_IsNothrowSwappable {
417 #if defined(__cpp_lib_is_swappable) || (_CPPLIB_VER && _HAS_CXX17)
421 template <typename T>
422 using IsNothrowSwappable = std::is_nothrow_swappable<T>;
427 template <typename T>
428 using IsNothrowSwappable = std::_Is_nothrow_swappable<T>;
433 struct IsNothrowSwappable
434 : bool_constant<std::is_nothrow_move_constructible<T>::value&& noexcept(
435 swap(std::declval<T&>(), std::declval<T&>()))> {};
439 using traits_detail_IsNothrowSwappable::IsNothrowSwappable;
442 struct IsRelocatable : std::conditional<
443 traits_detail::has_IsRelocatable<T>::value,
444 traits_detail::has_true_IsRelocatable<T>,
448 is_trivially_copyable<T>>::type {};
451 struct IsZeroInitializable
453 traits_detail::has_IsZeroInitializable<T>::value,
454 traits_detail::has_true_IsZeroInitializable<T>,
455 bool_constant<!std::is_class<T>::value>>::type {};
457 template <typename...>
458 struct Conjunction : std::true_type {};
459 template <typename T>
460 struct Conjunction<T> : T {};
461 template <typename T, typename... TList>
462 struct Conjunction<T, TList...>
463 : std::conditional<T::value, Conjunction<TList...>, T>::type {};
465 template <typename...>
466 struct Disjunction : std::false_type {};
467 template <typename T>
468 struct Disjunction<T> : T {};
469 template <typename T, typename... TList>
470 struct Disjunction<T, TList...>
471 : std::conditional<T::value, T, Disjunction<TList...>>::type {};
473 template <typename T>
474 struct Negation : bool_constant<!T::value> {};
476 template <bool... Bs>
478 using valid_type = bool;
479 static constexpr std::size_t size() {
480 return sizeof...(Bs);
485 template <class... Ts>
486 struct StrictConjunction
487 : std::is_same<Bools<Ts::value...>, Bools<(Ts::value || true)...>> {};
489 template <class... Ts>
490 struct StrictDisjunction
492 std::is_same<Bools<Ts::value...>, Bools<(Ts::value && false)...>>> {};
509 #define FOLLY_ASSUME_RELOCATABLE(...) \
510 struct IsRelocatable<__VA_ARGS__> : std::true_type {}
537 #define FOLLY_ASSUME_FBVECTOR_COMPATIBLE(...) \
540 FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__); \
543 #define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(...) \
545 template <class T1> \
546 FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1>); \
549 #define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(...) \
551 template <class T1, class T2> \
552 FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2>); \
555 #define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(...) \
557 template <class T1, class T2, class T3> \
558 FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3>); \
561 #define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(...) \
563 template <class T1, class T2, class T3, class T4> \
564 FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3, T4>); \
574 FOLLY_NAMESPACE_STD_BEGIN
576 template <class T, class U>
578 #ifndef _GLIBCXX_USE_FB
579 FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN
580 template <class T, class R, class A>
582 FOLLY_GLIBCXX_NAMESPACE_CXX11_END
584 template <class T, class R, class A, class S>
587 template <class T, class A>
589 template <class T, class A>
591 template <class T, class C, class A>
593 template <class K, class V, class C, class A>
598 FOLLY_NAMESPACE_STD_END
603 template <class T, class U>
604 struct IsRelocatable<std::pair<T, U>>
605 : bool_constant<IsRelocatable<T>::value && IsRelocatable<U>::value> {};
608 template <typename T, typename... Ts>
609 using IsOneOf = StrictDisjunction<std::is_same<T, Ts>...>;
623 template <typename T, bool>
624 struct is_negative_impl {
625 constexpr static bool check(T x) {
630 template <typename T>
631 struct is_negative_impl<T, false> {
632 constexpr static bool check(T) {
642 FOLLY_GNU_DISABLE_WARNING("-Wsign-compare")
643 #if __GNUC_PREREQ(5, 0)
644 FOLLY_GNU_DISABLE_WARNING("-Wbool-compare")
646 FOLLY_MSVC_DISABLE_WARNING(4388)
647 FOLLY_MSVC_DISABLE_WARNING(4804)
649 template <typename RHS, RHS rhs, typename LHS>
650 bool less_than_impl(LHS const lhs) {
653 rhs > std::numeric_limits<LHS>::max() ? true :
654 rhs <= std::numeric_limits<LHS>::min() ? false :
659 template <typename RHS, RHS rhs, typename LHS>
660 bool greater_than_impl(LHS const lhs) {
663 rhs > std::numeric_limits<LHS>::max() ? false :
664 rhs < std::numeric_limits<LHS>::min() ? true :
674 template <typename T>
675 constexpr bool is_negative(T x) {
676 return folly::detail::is_negative_impl<T, std::is_signed<T>::value>::check(x);
680 template <typename T>
681 constexpr bool is_non_positive(T x) {
682 return !x || folly::is_negative(x);
686 template <typename T>
687 constexpr bool is_positive(T x) {
688 return !is_non_positive(x);
692 template <typename T>
693 constexpr bool is_non_negative(T x) {
694 return !x || is_positive(x);
697 template <typename RHS, RHS rhs, typename LHS>
698 bool less_than(LHS const lhs) {
700 less_than_impl<RHS, rhs, typename std::remove_reference<LHS>::type>(lhs);
703 template <typename RHS, RHS rhs, typename LHS>
704 bool greater_than(LHS const lhs) {
706 greater_than_impl<RHS, rhs, typename std::remove_reference<LHS>::type>(
714 #if !_GLIBCXX_USE_CXX11_ABI
715 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string)
717 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::vector)
718 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::deque)
719 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr)
720 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr)
721 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function)
733 #if FOLLY_SUPPLY_MISSING_INT128_TRAITS
734 FOLLY_NAMESPACE_STD_BEGIN
736 struct is_arithmetic<__int128> : ::std::true_type {};
738 struct is_arithmetic<unsigned __int128> : ::std::true_type {};
740 struct is_integral<__int128> : ::std::true_type {};
742 struct is_integral<unsigned __int128> : ::std::true_type {};
744 struct make_unsigned<__int128> {
745 typedef unsigned __int128 type;
748 struct make_signed<__int128> {
749 typedef __int128 type;
752 struct make_unsigned<unsigned __int128> {
753 typedef unsigned __int128 type;
756 struct make_signed<unsigned __int128> {
757 typedef __int128 type;
760 struct is_signed<__int128> : ::std::true_type {};
762 struct is_unsigned<unsigned __int128> : ::std::true_type {};
763 FOLLY_NAMESPACE_STD_END
typename remove_cvref< T >::type remove_cvref_t
typename like_< Src >::template apply< Dst > & apply
std::integral_constant< std::size_t, I > index_constant
—— Concurrent Priority Queue Implementation ——
typename traits_detail::type_t_< T, Ts... >::type type_t
std::integral_constant< bool, B > bool_constant
typename detail::like_< Src >::template apply< remove_cvref_t< Dst >> like_t
#define FOLLY_HAS_TRUE_XXX(name)
type_t< void, Ts... > void_t
std::is_trivially_copyable< T > is_trivially_copyable
typename std::remove_cv< typename std::remove_reference< T >::type >::type type
bool operator==(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
typename like_< Src >::template apply< Dst > && apply
const Ignore & operator=(T const &) const
std::enable_if< IsLessThanComparable< Value >::value, bool >::type operator<(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
constexpr Ignore(const T &)