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