sfinae_helpers.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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_dir/make_tuple_types.h>
  13. #include <__tuple_dir/tuple_element.h>
  14. #include <__tuple_dir/tuple_like_ext.h>
  15. #include <__tuple_dir/tuple_size.h>
  16. #include <__tuple_dir/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. template <bool _IsTuple, class _SizeTrait, size_t _Expected>
  93. struct __tuple_like_with_size_imp : false_type {};
  94. template <class _SizeTrait, size_t _Expected>
  95. struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
  96. : integral_constant<bool, _SizeTrait::value == _Expected> {};
  97. template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __libcpp_remove_reference_t<_Tuple> >
  98. using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
  99. __tuple_like_ext<_RawTuple>::value,
  100. tuple_size<_RawTuple>, _ExpectedSize
  101. >;
  102. struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
  103. static constexpr bool __enable_explicit_default() { return false; }
  104. static constexpr bool __enable_implicit_default() { return false; }
  105. template <class ...>
  106. static constexpr bool __enable_explicit() { return false; }
  107. template <class ...>
  108. static constexpr bool __enable_implicit() { return false; }
  109. template <class ...>
  110. static constexpr bool __enable_assign() { return false; }
  111. };
  112. #endif // !defined(_LIBCPP_CXX03_LANG)
  113. #if _LIBCPP_STD_VER > 14
  114. template <bool _CanCopy, bool _CanMove>
  115. struct __sfinae_ctor_base {};
  116. template <>
  117. struct __sfinae_ctor_base<false, false> {
  118. __sfinae_ctor_base() = default;
  119. __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
  120. __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
  121. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  122. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  123. };
  124. template <>
  125. struct __sfinae_ctor_base<true, false> {
  126. __sfinae_ctor_base() = default;
  127. __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
  128. __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
  129. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  130. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  131. };
  132. template <>
  133. struct __sfinae_ctor_base<false, true> {
  134. __sfinae_ctor_base() = default;
  135. __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
  136. __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
  137. __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
  138. __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
  139. };
  140. template <bool _CanCopy, bool _CanMove>
  141. struct __sfinae_assign_base {};
  142. template <>
  143. struct __sfinae_assign_base<false, false> {
  144. __sfinae_assign_base() = default;
  145. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  146. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  147. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
  148. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
  149. };
  150. template <>
  151. struct __sfinae_assign_base<true, false> {
  152. __sfinae_assign_base() = default;
  153. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  154. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  155. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
  156. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
  157. };
  158. template <>
  159. struct __sfinae_assign_base<false, true> {
  160. __sfinae_assign_base() = default;
  161. __sfinae_assign_base(__sfinae_assign_base const&) = default;
  162. __sfinae_assign_base(__sfinae_assign_base &&) = default;
  163. __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
  164. __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
  165. };
  166. #endif // _LIBCPP_STD_VER > 14
  167. _LIBCPP_END_NAMESPACE_STD
  168. #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H