sfinae_helpers.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H
  9. #define _LIBCPP___TUPLE_SFINAE_HELPERS_H
  10. #include <__config>
  11. #include <__fwd/tuple.h>
  12. #include <__tuple/make_tuple_types.h>
  13. #include <__tuple/tuple_element.h>
  14. #include <__tuple/tuple_like_ext.h>
  15. #include <__tuple/tuple_size.h>
  16. #include <__tuple/tuple_types.h>
  17. #include <__type_traits/enable_if.h>
  18. #include <__type_traits/integral_constant.h>
  19. #include <__type_traits/is_assignable.h>
  20. #include <__type_traits/is_constructible.h>
  21. #include <__type_traits/is_convertible.h>
  22. #include <__type_traits/is_same.h>
  23. #include <__type_traits/remove_cvref.h>
  24. #include <__type_traits/remove_reference.h>
  25. #include <cstddef>
  26. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  27. # pragma GCC system_header
  28. #endif
  29. _LIBCPP_BEGIN_NAMESPACE_STD
  30. #ifndef _LIBCPP_CXX03_LANG
  31. template <bool ..._Preds>
  32. struct __all_dummy;
  33. template <bool ..._Pred>
  34. struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
  35. struct __tuple_sfinae_base {
  36. template <template <class, class...> class _Trait,
  37. class ..._LArgs, class ..._RArgs>
  38. static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
  39. -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
  40. template <template <class...> class>
  41. static auto __do_test(...) -> false_type;
  42. template <class _FromArgs, class _ToArgs>
  43. using __constructible = decltype(__do_test<is_constructible>(declval<_ToArgs>(), declval<_FromArgs>()));
  44. template <class _FromArgs, class _ToArgs>
  45. using __convertible = decltype(__do_test<is_convertible>(declval<_FromArgs>(), declval<_ToArgs>()));
  46. template <class _FromArgs, class _ToArgs>
  47. using __assignable = decltype(__do_test<is_assignable>(declval<_ToArgs>(), declval<_FromArgs>()));
  48. };
  49. // __tuple_convertible
  50. template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
  51. bool = __tuple_like_ext<_Up>::value,
  52. class = void>
  53. struct __tuple_convertible
  54. : public false_type {};
  55. template <class _Tp, class _Up>
  56. struct __tuple_convertible<_Tp, _Up, true, true,
  57. typename enable_if<(tuple_size<typename remove_reference<_Tp>::type>::value == tuple_size<_Up>::value)>::type>
  58. : public __tuple_sfinae_base::__convertible<
  59. typename __make_tuple_types<_Tp>::type
  60. , typename __make_tuple_types<_Up>::type
  61. >
  62. {};
  63. // __tuple_constructible
  64. template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
  65. bool = __tuple_like_ext<_Up>::value>
  66. struct __tuple_constructible
  67. : public false_type {};
  68. template <class _Tp, class _Up>
  69. struct __tuple_constructible<_Tp, _Up, true, true>
  70. : public __tuple_sfinae_base::__constructible<
  71. typename __make_tuple_types<_Tp>::type
  72. , typename __make_tuple_types<_Up>::type
  73. >
  74. {};
  75. // __tuple_assignable
  76. template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
  77. bool = __tuple_like_ext<_Up>::value>
  78. struct __tuple_assignable
  79. : public false_type {};
  80. template <class _Tp, class _Up>
  81. struct __tuple_assignable<_Tp, _Up, true, true>
  82. : public __tuple_sfinae_base::__assignable<
  83. typename __make_tuple_types<_Tp>::type
  84. , typename __make_tuple_types<_Up&>::type
  85. >
  86. {};
  87. template <size_t _Ip, class ..._Tp>
  88. struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
  89. {
  90. typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
  91. };
  92. struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
  93. static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
  94. static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
  95. template <class ...>
  96. static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { return false; }
  97. template <class ...>
  98. static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { return false; }
  99. template <class ...>
  100. static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() { return false; }
  101. };
  102. #endif // !defined(_LIBCPP_CXX03_LANG)
  103. #if _LIBCPP_STD_VER >= 17
  104. template <bool _CanCopy, bool _CanMove>
  105. struct __sfinae_ctor_base {};
  106. template <>
  107. struct __sfinae_ctor_base<false, false> {
  108. __sfinae_ctor_base() = default;
  109. __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
  110. __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
  111. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  112. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  113. };
  114. template <>
  115. struct __sfinae_ctor_base<true, false> {
  116. __sfinae_ctor_base() = default;
  117. __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
  118. __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
  119. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  120. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  121. };
  122. template <>
  123. struct __sfinae_ctor_base<false, true> {
  124. __sfinae_ctor_base() = default;
  125. __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
  126. __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
  127. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  128. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  129. };
  130. template <bool _CanCopy, bool _CanMove>
  131. struct __sfinae_assign_base {};
  132. template <>
  133. struct __sfinae_assign_base<false, false> {
  134. __sfinae_assign_base() = default;
  135. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  136. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  137. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
  138. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
  139. };
  140. template <>
  141. struct __sfinae_assign_base<true, false> {
  142. __sfinae_assign_base() = default;
  143. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  144. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  145. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
  146. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
  147. };
  148. template <>
  149. struct __sfinae_assign_base<false, true> {
  150. __sfinae_assign_base() = default;
  151. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  152. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  153. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
  154. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
  155. };
  156. #endif // _LIBCPP_STD_VER >= 17
  157. _LIBCPP_END_NAMESPACE_STD
  158. #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H