xref: /freebsd-src/contrib/llvm-project/libcxx/include/__tuple/sfinae_helpers.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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