xref: /freebsd-src/contrib/llvm-project/libcxx/include/__tuple/sfinae_helpers.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
19*0fca6ea1SDimitry Andric #include <__type_traits/conjunction.h>
2006c3fb27SDimitry Andric #include <__type_traits/enable_if.h>
2106c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
2206c3fb27SDimitry Andric #include <__type_traits/is_constructible.h>
2306c3fb27SDimitry Andric #include <__type_traits/is_same.h>
2406c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h>
2506c3fb27SDimitry Andric #include <__type_traits/remove_reference.h>
2606c3fb27SDimitry Andric #include <cstddef>
2706c3fb27SDimitry Andric 
2806c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2906c3fb27SDimitry Andric #  pragma GCC system_header
3006c3fb27SDimitry Andric #endif
3106c3fb27SDimitry Andric 
3206c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
3306c3fb27SDimitry Andric 
3406c3fb27SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
3506c3fb27SDimitry Andric 
3606c3fb27SDimitry Andric struct __tuple_sfinae_base {
37cb14a3feSDimitry Andric   template <template <class, class...> class _Trait, class... _LArgs, class... _RArgs>
38*0fca6ea1SDimitry Andric   static auto __do_test(__tuple_types<_LArgs...>,
39*0fca6ea1SDimitry Andric                         __tuple_types<_RArgs...>) -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
4006c3fb27SDimitry Andric   template <template <class...> class>
4106c3fb27SDimitry Andric   static auto __do_test(...) -> false_type;
4206c3fb27SDimitry Andric 
4306c3fb27SDimitry Andric   template <class _FromArgs, class _ToArgs>
4406c3fb27SDimitry Andric   using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
4506c3fb27SDimitry Andric };
4606c3fb27SDimitry Andric 
4706c3fb27SDimitry Andric // __tuple_constructible
4806c3fb27SDimitry Andric 
49cb14a3feSDimitry Andric template <class _Tp,
50cb14a3feSDimitry Andric           class _Up,
51cb14a3feSDimitry Andric           bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
5206c3fb27SDimitry Andric           bool = __tuple_like_ext<_Up>::value>
53cb14a3feSDimitry Andric struct __tuple_constructible : public false_type {};
5406c3fb27SDimitry Andric 
5506c3fb27SDimitry Andric template <class _Tp, class _Up>
5606c3fb27SDimitry Andric struct __tuple_constructible<_Tp, _Up, true, true>
57cb14a3feSDimitry Andric     : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type,
58cb14a3feSDimitry Andric                                                    typename __make_tuple_types<_Up>::type > {};
5906c3fb27SDimitry Andric 
6006c3fb27SDimitry Andric template <size_t _Ip, class... _Tp>
61cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > {
6206c3fb27SDimitry Andric   typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
6306c3fb27SDimitry Andric };
6406c3fb27SDimitry Andric 
6506c3fb27SDimitry Andric struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
6606c3fb27SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
6706c3fb27SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
6806c3fb27SDimitry Andric   template <class...>
69cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
70cb14a3feSDimitry Andric     return false;
71cb14a3feSDimitry Andric   }
7206c3fb27SDimitry Andric   template <class...>
73cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
74cb14a3feSDimitry Andric     return false;
75cb14a3feSDimitry Andric   }
7606c3fb27SDimitry Andric   template <class...>
77cb14a3feSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() {
78cb14a3feSDimitry Andric     return false;
79cb14a3feSDimitry Andric   }
8006c3fb27SDimitry Andric };
8106c3fb27SDimitry Andric #endif // !defined(_LIBCPP_CXX03_LANG)
8206c3fb27SDimitry Andric 
8306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17
8406c3fb27SDimitry Andric 
8506c3fb27SDimitry Andric template <bool _CanCopy, bool _CanMove>
8606c3fb27SDimitry Andric struct __sfinae_ctor_base {};
8706c3fb27SDimitry Andric template <>
8806c3fb27SDimitry Andric struct __sfinae_ctor_base<false, false> {
8906c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
9006c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = delete;
9106c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = delete;
9206c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
9306c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
9406c3fb27SDimitry Andric };
9506c3fb27SDimitry Andric template <>
9606c3fb27SDimitry Andric struct __sfinae_ctor_base<true, false> {
9706c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
9806c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = default;
9906c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = delete;
10006c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
10106c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
10206c3fb27SDimitry Andric };
10306c3fb27SDimitry Andric template <>
10406c3fb27SDimitry Andric struct __sfinae_ctor_base<false, true> {
10506c3fb27SDimitry Andric   __sfinae_ctor_base()                                     = default;
10606c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base const&)            = delete;
10706c3fb27SDimitry Andric   __sfinae_ctor_base(__sfinae_ctor_base&&)                 = default;
10806c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
10906c3fb27SDimitry Andric   __sfinae_ctor_base& operator=(__sfinae_ctor_base&&)      = default;
11006c3fb27SDimitry Andric };
11106c3fb27SDimitry Andric 
11206c3fb27SDimitry Andric template <bool _CanCopy, bool _CanMove>
11306c3fb27SDimitry Andric struct __sfinae_assign_base {};
11406c3fb27SDimitry Andric template <>
11506c3fb27SDimitry Andric struct __sfinae_assign_base<false, false> {
11606c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
11706c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
11806c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
11906c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
12006c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = delete;
12106c3fb27SDimitry Andric };
12206c3fb27SDimitry Andric template <>
12306c3fb27SDimitry Andric struct __sfinae_assign_base<true, false> {
12406c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
12506c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
12606c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
12706c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
12806c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = delete;
12906c3fb27SDimitry Andric };
13006c3fb27SDimitry Andric template <>
13106c3fb27SDimitry Andric struct __sfinae_assign_base<false, true> {
13206c3fb27SDimitry Andric   __sfinae_assign_base()                                       = default;
13306c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base const&)            = default;
13406c3fb27SDimitry Andric   __sfinae_assign_base(__sfinae_assign_base&&)                 = default;
13506c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
13606c3fb27SDimitry Andric   __sfinae_assign_base& operator=(__sfinae_assign_base&&)      = default;
13706c3fb27SDimitry Andric };
13806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 17
13906c3fb27SDimitry Andric 
14006c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
14106c3fb27SDimitry Andric 
14206c3fb27SDimitry Andric #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H
143