106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric #ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H
1006c3fb27SDimitry Andric #define _LIBCPP___TUPLE_SFINAE_HELPERS_H
1106c3fb27SDimitry Andric 
1206c3fb27SDimitry Andric #include <__config>
1306c3fb27SDimitry Andric #include <__fwd/tuple.h>
1406c3fb27SDimitry Andric #include <__tuple/make_tuple_types.h>
1506c3fb27SDimitry Andric #include <__tuple/tuple_element.h>
1606c3fb27SDimitry Andric #include <__tuple/tuple_like_ext.h>
1706c3fb27SDimitry Andric #include <__tuple/tuple_size.h>
1806c3fb27SDimitry Andric #include <__tuple/tuple_types.h>
1906c3fb27SDimitry Andric #include <__type_traits/enable_if.h>
2006c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
2106c3fb27SDimitry Andric #include <__type_traits/is_assignable.h>
2206c3fb27SDimitry Andric #include <__type_traits/is_constructible.h>
2306c3fb27SDimitry Andric #include <__type_traits/is_convertible.h>
2406c3fb27SDimitry Andric #include <__type_traits/is_same.h>
2506c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h>
2606c3fb27SDimitry Andric #include <__type_traits/remove_reference.h>
2706c3fb27SDimitry Andric #include <cstddef>
2806c3fb27SDimitry Andric 
2906c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3006c3fb27SDimitry Andric #  pragma GCC system_header
3106c3fb27SDimitry Andric #endif
3206c3fb27SDimitry Andric 
3306c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
3406c3fb27SDimitry Andric 
3506c3fb27SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
3606c3fb27SDimitry Andric 
3706c3fb27SDimitry Andric template <bool... _Preds>
3806c3fb27SDimitry Andric struct __all_dummy;
3906c3fb27SDimitry Andric 
4006c3fb27SDimitry Andric template <bool... _Pred>
4106c3fb27SDimitry Andric struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
4206c3fb27SDimitry Andric 
4306c3fb27SDimitry Andric struct __tuple_sfinae_base {
44*cb14a3feSDimitry Andric   template <template <class, class...> class _Trait, class... _LArgs, class... _RArgs>
4506c3fb27SDimitry Andric   static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
4606c3fb27SDimitry Andric       -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
4706c3fb27SDimitry Andric   template <template <class...> class>
4806c3fb27SDimitry Andric   static auto __do_test(...) -> false_type;
4906c3fb27SDimitry Andric 
5006c3fb27SDimitry Andric   template <class _FromArgs, class _ToArgs>
5106c3fb27SDimitry Andric   using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
5206c3fb27SDimitry Andric   template <class _FromArgs, class _ToArgs>
5306c3fb27SDimitry Andric   using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{}));
5406c3fb27SDimitry Andric   template <class _FromArgs, class _ToArgs>
5506c3fb27SDimitry Andric   using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{}));
5606c3fb27SDimitry Andric };
5706c3fb27SDimitry Andric 
5806c3fb27SDimitry Andric // __tuple_convertible
5906c3fb27SDimitry Andric 
60*cb14a3feSDimitry Andric template <class _Tp,
61*cb14a3feSDimitry Andric           class _Up,
62*cb14a3feSDimitry Andric           bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
6306c3fb27SDimitry Andric           bool = __tuple_like_ext<_Up>::value>
64*cb14a3feSDimitry Andric struct __tuple_convertible : public false_type {};
6506c3fb27SDimitry Andric 
6606c3fb27SDimitry Andric template <class _Tp, class _Up>
6706c3fb27SDimitry Andric struct __tuple_convertible<_Tp, _Up, true, true>
68*cb14a3feSDimitry Andric     : public __tuple_sfinae_base::__convertible< typename __make_tuple_types<_Tp>::type,
69*cb14a3feSDimitry Andric                                                  typename __make_tuple_types<_Up>::type > {};
7006c3fb27SDimitry Andric 
7106c3fb27SDimitry Andric // __tuple_constructible
7206c3fb27SDimitry Andric 
73*cb14a3feSDimitry Andric template <class _Tp,
74*cb14a3feSDimitry Andric           class _Up,
75*cb14a3feSDimitry Andric           bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
7606c3fb27SDimitry Andric           bool = __tuple_like_ext<_Up>::value>
77*cb14a3feSDimitry Andric struct __tuple_constructible : public false_type {};
7806c3fb27SDimitry Andric 
7906c3fb27SDimitry Andric template <class _Tp, class _Up>
8006c3fb27SDimitry Andric struct __tuple_constructible<_Tp, _Up, true, true>
81*cb14a3feSDimitry Andric     : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type,
82*cb14a3feSDimitry Andric                                                    typename __make_tuple_types<_Up>::type > {};
8306c3fb27SDimitry Andric 
8406c3fb27SDimitry Andric // __tuple_assignable
8506c3fb27SDimitry Andric 
86*cb14a3feSDimitry Andric template <class _Tp,
87*cb14a3feSDimitry Andric           class _Up,
88*cb14a3feSDimitry Andric           bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
8906c3fb27SDimitry Andric           bool = __tuple_like_ext<_Up>::value>
90*cb14a3feSDimitry Andric struct __tuple_assignable : public false_type {};
9106c3fb27SDimitry Andric 
9206c3fb27SDimitry Andric template <class _Tp, class _Up>
9306c3fb27SDimitry Andric struct __tuple_assignable<_Tp, _Up, true, true>
94*cb14a3feSDimitry Andric     : public __tuple_sfinae_base::__assignable< typename __make_tuple_types<_Tp>::type,
95*cb14a3feSDimitry Andric                                                 typename __make_tuple_types<_Up&>::type > {};
9606c3fb27SDimitry Andric 
9706c3fb27SDimitry Andric template <size_t _Ip, class... _Tp>
98*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > {
9906c3fb27SDimitry Andric   typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
10006c3fb27SDimitry Andric };
10106c3fb27SDimitry Andric 
10206c3fb27SDimitry Andric struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
10306c3fb27SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
10406c3fb27SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
10506c3fb27SDimitry Andric   template <class...>
106*cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
107*cb14a3feSDimitry Andric     return false;
108*cb14a3feSDimitry Andric   }
10906c3fb27SDimitry Andric   template <class...>
110*cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
111*cb14a3feSDimitry Andric     return false;
112*cb14a3feSDimitry Andric   }
11306c3fb27SDimitry Andric   template <class...>
114*cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() {
115*cb14a3feSDimitry Andric     return false;
116*cb14a3feSDimitry Andric   }
11706c3fb27SDimitry Andric };
11806c3fb27SDimitry Andric #endif // !defined(_LIBCPP_CXX03_LANG)
11906c3fb27SDimitry Andric 
12006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17
12106c3fb27SDimitry Andric 
12206c3fb27SDimitry Andric template <bool _CanCopy, bool _CanMove>
12306c3fb27SDimitry Andric struct __sfinae_ctor_base {};
12406c3fb27SDimitry Andric template <>
12506c3fb27SDimitry Andric struct __sfinae_ctor_base<false, false> {
12606c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
12706c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = delete;
12806c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = delete;
12906c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
13006c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
13106c3fb27SDimitry Andric };
13206c3fb27SDimitry Andric template <>
13306c3fb27SDimitry Andric struct __sfinae_ctor_base<true, false> {
13406c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
13506c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = default;
13606c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = delete;
13706c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
13806c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
13906c3fb27SDimitry Andric };
14006c3fb27SDimitry Andric template <>
14106c3fb27SDimitry Andric struct __sfinae_ctor_base<false, true> {
14206c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
14306c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = delete;
14406c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = default;
14506c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
14606c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
14706c3fb27SDimitry Andric };
14806c3fb27SDimitry Andric 
14906c3fb27SDimitry Andric template <bool _CanCopy, bool _CanMove>
15006c3fb27SDimitry Andric struct __sfinae_assign_base {};
15106c3fb27SDimitry Andric template <>
15206c3fb27SDimitry Andric struct __sfinae_assign_base<false, false> {
15306c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
15406c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
15506c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
15606c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
15706c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = delete;
15806c3fb27SDimitry Andric };
15906c3fb27SDimitry Andric template <>
16006c3fb27SDimitry Andric struct __sfinae_assign_base<true, false> {
16106c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
16206c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
16306c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
16406c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
16506c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = delete;
16606c3fb27SDimitry Andric };
16706c3fb27SDimitry Andric template <>
16806c3fb27SDimitry Andric struct __sfinae_assign_base<false, true> {
16906c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
17006c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
17106c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
17206c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
17306c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = default;
17406c3fb27SDimitry Andric };
17506c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 17
17606c3fb27SDimitry Andric 
17706c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
17806c3fb27SDimitry Andric 
17906c3fb27SDimitry Andric #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H
180