13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP___TUPLE
113e519524SHoward Hinnant#define _LIBCPP___TUPLE
123e519524SHoward Hinnant
133e519524SHoward Hinnant#include <__config>
143e519524SHoward Hinnant#include <cstddef>
153e519524SHoward Hinnant#include <type_traits>
163e519524SHoward Hinnant
17073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
183e519524SHoward Hinnant#  pragma GCC system_header
19073458b1SHoward Hinnant#endif
203e519524SHoward Hinnant
213e519524SHoward Hinnant
223e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
233e519524SHoward Hinnant
24e4957601SMarshall Clowtemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
251013fe3cSEric Fiselier
26cb0d4df9SEric Fiselier#if !defined(_LIBCPP_CXX03_LANG)
27cb0d4df9SEric Fiseliertemplate <class _Tp, class...>
28cb0d4df9SEric Fiselierusing __enable_if_tuple_size_imp = _Tp;
291013fe3cSEric Fiselier
301013fe3cSEric Fiseliertemplate <class _Tp>
31e4957601SMarshall Clowstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
32cb0d4df9SEric Fiselier    const _Tp,
33*4887d047SNikolas Klauser    __enable_if_t<!is_volatile<_Tp>::value>,
34cb0d4df9SEric Fiselier    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
35cb0d4df9SEric Fiselier    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
36ef616835SHoward Hinnant
37ef616835SHoward Hinnanttemplate <class _Tp>
38e4957601SMarshall Clowstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
39cb0d4df9SEric Fiselier    volatile _Tp,
40*4887d047SNikolas Klauser    __enable_if_t<!is_const<_Tp>::value>,
41cb0d4df9SEric Fiselier    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
42cb0d4df9SEric Fiselier    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
43ef616835SHoward Hinnant
44ef616835SHoward Hinnanttemplate <class _Tp>
45e4957601SMarshall Clowstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
46cb0d4df9SEric Fiselier    const volatile _Tp,
47cb0d4df9SEric Fiselier    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
48cb0d4df9SEric Fiselier    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
49ef616835SHoward Hinnant
50cb0d4df9SEric Fiselier#else
51e4957601SMarshall Clowtemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
52e4957601SMarshall Clowtemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
53e4957601SMarshall Clowtemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
54cb0d4df9SEric Fiselier#endif
55ef616835SHoward Hinnant
562b0c7abbSLouis Dionnetemplate <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element;
573e519524SHoward Hinnant
58ef616835SHoward Hinnanttemplate <size_t _Ip, class _Tp>
592b0c7abbSLouis Dionnestruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp>
60ef616835SHoward Hinnant{
613557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
62ef616835SHoward Hinnant};
63ef616835SHoward Hinnant
64ef616835SHoward Hinnanttemplate <size_t _Ip, class _Tp>
652b0c7abbSLouis Dionnestruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp>
66ef616835SHoward Hinnant{
673557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
68ef616835SHoward Hinnant};
69ef616835SHoward Hinnant
70ef616835SHoward Hinnanttemplate <size_t _Ip, class _Tp>
712b0c7abbSLouis Dionnestruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp>
72ef616835SHoward Hinnant{
733557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
74ef616835SHoward Hinnant};
75ef616835SHoward Hinnant
763e519524SHoward Hinnanttemplate <class _Tp> struct __tuple_like : false_type {};
773e519524SHoward Hinnant
787f64810bSHoward Hinnanttemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
797f64810bSHoward Hinnanttemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
807f64810bSHoward Hinnanttemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
817f64810bSHoward Hinnant
8257f00f2fSEric Fiselier// tuple specializations
8357f00f2fSEric Fiselier
8429870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
859743af6eSEric Fiselier
869743af6eSEric Fiseliertemplate <size_t...> struct __tuple_indices {};
879743af6eSEric Fiselier
889743af6eSEric Fiseliertemplate <class _IdxType, _IdxType... _Values>
899743af6eSEric Fiselierstruct __integer_sequence {
909743af6eSEric Fiselier  template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
919743af6eSEric Fiselier  using __convert = _ToIndexSeq<_ToIndexType, _Values...>;
929743af6eSEric Fiselier
939743af6eSEric Fiselier  template <size_t _Sp>
949743af6eSEric Fiselier  using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
959743af6eSEric Fiselier};
969743af6eSEric Fiselier
979743af6eSEric Fiselier#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
989743af6eSEric Fiseliernamespace __detail {
999743af6eSEric Fiselier
1009743af6eSEric Fiseliertemplate<typename _Tp, size_t ..._Extra> struct __repeat;
1019743af6eSEric Fiseliertemplate<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> {
1023557c7c1SLouis Dionne  typedef _LIBCPP_NODEBUG __integer_sequence<_Tp,
1039743af6eSEric Fiselier                           _Np...,
1049743af6eSEric Fiselier                           sizeof...(_Np) + _Np...,
1059743af6eSEric Fiselier                           2 * sizeof...(_Np) + _Np...,
1069743af6eSEric Fiselier                           3 * sizeof...(_Np) + _Np...,
1079743af6eSEric Fiselier                           4 * sizeof...(_Np) + _Np...,
1089743af6eSEric Fiselier                           5 * sizeof...(_Np) + _Np...,
1099743af6eSEric Fiselier                           6 * sizeof...(_Np) + _Np...,
1109743af6eSEric Fiselier                           7 * sizeof...(_Np) + _Np...,
1119743af6eSEric Fiselier                           _Extra...> type;
1129743af6eSEric Fiselier};
1139743af6eSEric Fiselier
1149743af6eSEric Fiseliertemplate<size_t _Np> struct __parity;
1159743af6eSEric Fiseliertemplate<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
1169743af6eSEric Fiselier
1179743af6eSEric Fiseliertemplate<> struct __make<0> { typedef __integer_sequence<size_t> type; };
1189743af6eSEric Fiseliertemplate<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; };
1199743af6eSEric Fiseliertemplate<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; };
1209743af6eSEric Fiseliertemplate<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; };
1219743af6eSEric Fiseliertemplate<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; };
1229743af6eSEric Fiseliertemplate<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
1239743af6eSEric Fiseliertemplate<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
1249743af6eSEric Fiseliertemplate<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
1259743af6eSEric Fiselier
1269743af6eSEric Fiseliertemplate<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
1279743af6eSEric Fiseliertemplate<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
1289743af6eSEric Fiseliertemplate<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
1299743af6eSEric Fiseliertemplate<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
1309743af6eSEric Fiseliertemplate<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
1319743af6eSEric Fiseliertemplate<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
1329743af6eSEric Fiseliertemplate<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
1339743af6eSEric Fiseliertemplate<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
1349743af6eSEric Fiselier
1359743af6eSEric Fiselier} // namespace detail
1369743af6eSEric Fiselier
1379743af6eSEric Fiselier#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
1389743af6eSEric Fiselier
1399743af6eSEric Fiselier#if __has_builtin(__make_integer_seq)
1409743af6eSEric Fiseliertemplate <size_t _Ep, size_t _Sp>
1419743af6eSEric Fiselierusing __make_indices_imp =
1429743af6eSEric Fiselier    typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template
1439743af6eSEric Fiselier    __to_tuple_indices<_Sp>;
1449743af6eSEric Fiselier#else
1459743af6eSEric Fiseliertemplate <size_t _Ep, size_t _Sp>
1469743af6eSEric Fiselierusing __make_indices_imp =
1479743af6eSEric Fiselier    typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>;
1489743af6eSEric Fiselier
1499743af6eSEric Fiselier#endif
1509743af6eSEric Fiselier
1519743af6eSEric Fiseliertemplate <size_t _Ep, size_t _Sp = 0>
1529743af6eSEric Fiselierstruct __make_tuple_indices
1539743af6eSEric Fiselier{
1549743af6eSEric Fiselier    static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
1559743af6eSEric Fiselier    typedef __make_indices_imp<_Ep, _Sp> type;
1569743af6eSEric Fiselier};
1579743af6eSEric Fiselier
1589743af6eSEric Fiselier
159e2f2d1edSEric Fiseliertemplate <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple;
16057f00f2fSEric Fiselier
1613e519524SHoward Hinnanttemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
1623e519524SHoward Hinnant
1634927c295SEric Fiseliertemplate <class ..._Tp>
164e4957601SMarshall Clowstruct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
1654927c295SEric Fiselier    : public integral_constant<size_t, sizeof...(_Tp)>
1664927c295SEric Fiselier{
1674927c295SEric Fiselier};
1684927c295SEric Fiselier
1693e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
1708bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1713e519524SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&
17227d0a2a7SHoward Hinnantget(tuple<_Tp...>&) _NOEXCEPT;
1733e519524SHoward Hinnant
1743e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
1758bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1763e519524SHoward Hinnantconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
17727d0a2a7SHoward Hinnantget(const tuple<_Tp...>&) _NOEXCEPT;
1783e519524SHoward Hinnant
179601afb30SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
1808bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
181601afb30SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&&
18227d0a2a7SHoward Hinnantget(tuple<_Tp...>&&) _NOEXCEPT;
183545b8861SEric Fiselier
184545b8861SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
185545b8861SEric Fiselier_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
186545b8861SEric Fiselierconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
187545b8861SEric Fiselierget(const tuple<_Tp...>&&) _NOEXCEPT;
18829870871SEric Fiselier
18929870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
19057f00f2fSEric Fiselier
19157f00f2fSEric Fiselier// pair specializations
19257f00f2fSEric Fiselier
19357f00f2fSEric Fiseliertemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
194601afb30SHoward Hinnant
1953e519524SHoward Hinnanttemplate <size_t _Ip, class _T1, class _T2>
1968bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1973e519524SHoward Hinnanttypename tuple_element<_Ip, pair<_T1, _T2> >::type&
19827d0a2a7SHoward Hinnantget(pair<_T1, _T2>&) _NOEXCEPT;
1993e519524SHoward Hinnant
2003e519524SHoward Hinnanttemplate <size_t _Ip, class _T1, class _T2>
2018bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2023e519524SHoward Hinnantconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&
20327d0a2a7SHoward Hinnantget(const pair<_T1, _T2>&) _NOEXCEPT;
2043e519524SHoward Hinnant
20529870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
206601afb30SHoward Hinnanttemplate <size_t _Ip, class _T1, class _T2>
2078bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
208601afb30SHoward Hinnanttypename tuple_element<_Ip, pair<_T1, _T2> >::type&&
20927d0a2a7SHoward Hinnantget(pair<_T1, _T2>&&) _NOEXCEPT;
210545b8861SEric Fiselier
211545b8861SEric Fiseliertemplate <size_t _Ip, class _T1, class _T2>
212545b8861SEric Fiselier_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
213545b8861SEric Fiselierconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
214545b8861SEric Fiselierget(const pair<_T1, _T2>&&) _NOEXCEPT;
21557f00f2fSEric Fiselier#endif
21657f00f2fSEric Fiselier
21757f00f2fSEric Fiselier// array specializations
21857f00f2fSEric Fiselier
219e2f2d1edSEric Fiseliertemplate <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
22057f00f2fSEric Fiselier
22157f00f2fSEric Fiseliertemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
222601afb30SHoward Hinnant
2233e519524SHoward Hinnanttemplate <size_t _Ip, class _Tp, size_t _Size>
2248bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2253e519524SHoward Hinnant_Tp&
2268f0cd597SHoward Hinnantget(array<_Tp, _Size>&) _NOEXCEPT;
2273e519524SHoward Hinnant
2283e519524SHoward Hinnanttemplate <size_t _Ip, class _Tp, size_t _Size>
2298bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2303e519524SHoward Hinnantconst _Tp&
2318f0cd597SHoward Hinnantget(const array<_Tp, _Size>&) _NOEXCEPT;
2323e519524SHoward Hinnant
23329870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
234601afb30SHoward Hinnanttemplate <size_t _Ip, class _Tp, size_t _Size>
2358bf1f08aSMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
236601afb30SHoward Hinnant_Tp&&
2378f0cd597SHoward Hinnantget(array<_Tp, _Size>&&) _NOEXCEPT;
238545b8861SEric Fiselier
239545b8861SEric Fiseliertemplate <size_t _Ip, class _Tp, size_t _Size>
240545b8861SEric Fiselier_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
241545b8861SEric Fiselierconst _Tp&&
242545b8861SEric Fiselierget(const array<_Tp, _Size>&&) _NOEXCEPT;
24357f00f2fSEric Fiselier#endif
24457f00f2fSEric Fiselier
24529870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2463e519524SHoward Hinnant
2473e519524SHoward Hinnant// __tuple_types
2483e519524SHoward Hinnant
2493e519524SHoward Hinnanttemplate <class ..._Tp> struct __tuple_types {};
2503e519524SHoward Hinnant
25110b9a1bbSEric Fiselier#if !__has_builtin(__type_pack_element)
2523e519524SHoward Hinnant
25310b9a1bbSEric Fiseliernamespace __indexer_detail {
2543e519524SHoward Hinnant
25510b9a1bbSEric Fiseliertemplate <size_t _Idx, class _Tp>
2563557c7c1SLouis Dionnestruct __indexed { using type _LIBCPP_NODEBUG = _Tp; };
25710b9a1bbSEric Fiselier
25810b9a1bbSEric Fiseliertemplate <class _Types, class _Indexes> struct __indexer;
25910b9a1bbSEric Fiselier
26010b9a1bbSEric Fiseliertemplate <class ..._Types, size_t ..._Idx>
26110b9a1bbSEric Fiselierstruct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>>
26210b9a1bbSEric Fiselier    : __indexed<_Idx, _Types>...
26310b9a1bbSEric Fiselier{};
26410b9a1bbSEric Fiselier
26510b9a1bbSEric Fiseliertemplate <size_t _Idx, class _Tp>
26610b9a1bbSEric Fiselier__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&);
26710b9a1bbSEric Fiselier
26810b9a1bbSEric Fiselier} // namespace __indexer_detail
26910b9a1bbSEric Fiselier
27010b9a1bbSEric Fiseliertemplate <size_t _Idx, class ..._Types>
2713557c7c1SLouis Dionneusing __type_pack_element _LIBCPP_NODEBUG = typename decltype(
27210b9a1bbSEric Fiselier    __indexer_detail::__at_index<_Idx>(
27310b9a1bbSEric Fiselier        __indexer_detail::__indexer<
27410b9a1bbSEric Fiselier            __tuple_types<_Types...>,
27510b9a1bbSEric Fiselier            typename __make_tuple_indices<sizeof...(_Types)>::type
27610b9a1bbSEric Fiselier        >{})
27710b9a1bbSEric Fiselier  )::type;
27810b9a1bbSEric Fiselier#endif
27910b9a1bbSEric Fiselier
28010b9a1bbSEric Fiseliertemplate <size_t _Ip, class ..._Types>
2812b0c7abbSLouis Dionnestruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> >
2823e519524SHoward Hinnant{
28310b9a1bbSEric Fiselier    static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
2843557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type;
2853e519524SHoward Hinnant};
2863e519524SHoward Hinnant
287e2fd8b8dSEric Fiselier
2883e519524SHoward Hinnanttemplate <class ..._Tp>
289e4957601SMarshall Clowstruct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
2903e519524SHoward Hinnant    : public integral_constant<size_t, sizeof...(_Tp)>
2913e519524SHoward Hinnant{
2923e519524SHoward Hinnant};
2933e519524SHoward Hinnant
2943e519524SHoward Hinnanttemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};
2953e519524SHoward Hinnant
29610b9a1bbSEric Fiseliertemplate <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile>
29710b9a1bbSEric Fiselierstruct __apply_cv_mf;
29810b9a1bbSEric Fiseliertemplate <>
29910b9a1bbSEric Fiselierstruct __apply_cv_mf<false, false, false> {
30010b9a1bbSEric Fiselier  template <class _Tp> using __apply = _Tp;
30110b9a1bbSEric Fiselier};
30210b9a1bbSEric Fiseliertemplate <>
30310b9a1bbSEric Fiselierstruct __apply_cv_mf<false, true, false> {
3043557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp;
30510b9a1bbSEric Fiselier};
30610b9a1bbSEric Fiseliertemplate <>
30710b9a1bbSEric Fiselierstruct __apply_cv_mf<false, false, true> {
3083557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp;
30910b9a1bbSEric Fiselier};
31010b9a1bbSEric Fiseliertemplate <>
31110b9a1bbSEric Fiselierstruct __apply_cv_mf<false, true, true> {
3123557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp;
31310b9a1bbSEric Fiselier};
31410b9a1bbSEric Fiseliertemplate <>
31510b9a1bbSEric Fiselierstruct __apply_cv_mf<true, false, false> {
3163557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = _Tp&;
31710b9a1bbSEric Fiselier};
31810b9a1bbSEric Fiseliertemplate <>
31910b9a1bbSEric Fiselierstruct __apply_cv_mf<true, true, false> {
3203557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp&;
32110b9a1bbSEric Fiselier};
32210b9a1bbSEric Fiseliertemplate <>
32310b9a1bbSEric Fiselierstruct __apply_cv_mf<true, false, true> {
3243557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp&;
32510b9a1bbSEric Fiselier};
32610b9a1bbSEric Fiseliertemplate <>
32710b9a1bbSEric Fiselierstruct __apply_cv_mf<true, true, true> {
3283557c7c1SLouis Dionne  template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp&;
32910b9a1bbSEric Fiselier};
33010b9a1bbSEric Fiseliertemplate <class _Tp, class _RawTp = typename remove_reference<_Tp>::type>
3313557c7c1SLouis Dionneusing __apply_cv_t _LIBCPP_NODEBUG = __apply_cv_mf<
33210b9a1bbSEric Fiselier    is_lvalue_reference<_Tp>::value,
33310b9a1bbSEric Fiselier    is_const<_RawTp>::value,
33410b9a1bbSEric Fiselier    is_volatile<_RawTp>::value>;
33510b9a1bbSEric Fiselier
3363e519524SHoward Hinnant// __make_tuple_types
3373e519524SHoward Hinnant
33830ad985bSHoward Hinnant// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
33930ad985bSHoward Hinnant// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).
34030ad985bSHoward Hinnant// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>.  If _Tuple is a
34130ad985bSHoward Hinnant// lvalue_reference type, then __tuple_types<_Types&...> is the result.
34230ad985bSHoward Hinnant
34310b9a1bbSEric Fiseliertemplate <class _TupleTypes, class _TupleIndices>
34410b9a1bbSEric Fiselierstruct __make_tuple_types_flat;
3453e519524SHoward Hinnant
34610b9a1bbSEric Fiseliertemplate <template <class...> class _Tuple, class ..._Types, size_t ..._Idx>
34710b9a1bbSEric Fiselierstruct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
34810b9a1bbSEric Fiselier  // Specialization for pair, tuple, and __tuple_types
34910b9a1bbSEric Fiselier  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
3503557c7c1SLouis Dionne  using __apply_quals _LIBCPP_NODEBUG = __tuple_types<
35110b9a1bbSEric Fiselier      typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>...
35210b9a1bbSEric Fiselier    >;
3533e519524SHoward Hinnant};
3543e519524SHoward Hinnant
35510b9a1bbSEric Fiseliertemplate <class _Vt, size_t _Np, size_t ..._Idx>
35610b9a1bbSEric Fiselierstruct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> {
35727cdf401SEric Fiselier  template <size_t>
35827cdf401SEric Fiselier  using __value_type = _Vt;
35910b9a1bbSEric Fiselier  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
36010b9a1bbSEric Fiselier  using __apply_quals = __tuple_types<
36127cdf401SEric Fiselier      typename _ApplyFn::template __apply<__value_type<_Idx>>...
36210b9a1bbSEric Fiselier    >;
3633e519524SHoward Hinnant};
3643e519524SHoward Hinnant
36510b9a1bbSEric Fiseliertemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value,
36610b9a1bbSEric Fiselier          size_t _Sp = 0,
36710b9a1bbSEric Fiselier          bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)>
3683e519524SHoward Hinnantstruct __make_tuple_types
3693e519524SHoward Hinnant{
3703e519524SHoward Hinnant    static_assert(_Sp <= _Ep, "__make_tuple_types input error");
37110b9a1bbSEric Fiselier    using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type;
37210b9a1bbSEric Fiselier    using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>;
37310b9a1bbSEric Fiselier    using type = typename _Maker::template __apply_quals<_Tp>;
37410b9a1bbSEric Fiselier};
37510b9a1bbSEric Fiselier
37610b9a1bbSEric Fiseliertemplate <class ..._Types, size_t _Ep>
37710b9a1bbSEric Fiselierstruct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> {
3783557c7c1SLouis Dionne  typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
37910b9a1bbSEric Fiselier};
38010b9a1bbSEric Fiselier
38110b9a1bbSEric Fiseliertemplate <class ..._Types, size_t _Ep>
38210b9a1bbSEric Fiselierstruct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> {
3833557c7c1SLouis Dionne  typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
3843e519524SHoward Hinnant};
3853e519524SHoward Hinnant
386e2fd8b8dSEric Fiseliertemplate <bool ..._Preds>
387e2fd8b8dSEric Fiselierstruct __all_dummy;
388e2fd8b8dSEric Fiselier
389e2fd8b8dSEric Fiseliertemplate <bool ..._Pred>
3905c0ea748SArthur O'Dwyerstruct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
391e2fd8b8dSEric Fiselier
392e2fd8b8dSEric Fiselierstruct __tuple_sfinae_base {
39327cdf401SEric Fiselier  template <template <class, class...> class _Trait,
39427cdf401SEric Fiselier            class ..._LArgs, class ..._RArgs>
39527cdf401SEric Fiselier  static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
396*4887d047SNikolas Klauser    -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
39727cdf401SEric Fiselier  template <template <class...> class>
39827cdf401SEric Fiselier  static auto __do_test(...) -> false_type;
399e2fd8b8dSEric Fiselier
40027cdf401SEric Fiselier  template <class _FromArgs, class _ToArgs>
40127cdf401SEric Fiselier  using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
40227cdf401SEric Fiselier  template <class _FromArgs, class _ToArgs>
40327cdf401SEric Fiselier  using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{}));
40427cdf401SEric Fiselier  template <class _FromArgs, class _ToArgs>
40527cdf401SEric Fiselier  using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{}));
406e2fd8b8dSEric Fiselier};
407e2fd8b8dSEric Fiselier
4083e519524SHoward Hinnant// __tuple_convertible
4093e519524SHoward Hinnant
4103e519524SHoward Hinnanttemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
4113e519524SHoward Hinnant                                bool = __tuple_like<_Up>::value>
4123e519524SHoward Hinnantstruct __tuple_convertible
4133e519524SHoward Hinnant    : public false_type {};
4143e519524SHoward Hinnant
4153e519524SHoward Hinnanttemplate <class _Tp, class _Up>
4163e519524SHoward Hinnantstruct __tuple_convertible<_Tp, _Up, true, true>
417e2fd8b8dSEric Fiselier    : public __tuple_sfinae_base::__convertible<
418295bce11SEric Fiselier      typename __make_tuple_types<_Tp>::type
419295bce11SEric Fiselier    , typename __make_tuple_types<_Up>::type
420295bce11SEric Fiselier    >
421295bce11SEric Fiselier{};
422295bce11SEric Fiselier
423e2fd8b8dSEric Fiselier// __tuple_constructible
424e2fd8b8dSEric Fiselier
4250527c620SHoward Hinnanttemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
4260527c620SHoward Hinnant                                bool = __tuple_like<_Up>::value>
4270527c620SHoward Hinnantstruct __tuple_constructible
4280527c620SHoward Hinnant    : public false_type {};
4290527c620SHoward Hinnant
4300527c620SHoward Hinnanttemplate <class _Tp, class _Up>
4310527c620SHoward Hinnantstruct __tuple_constructible<_Tp, _Up, true, true>
432e2fd8b8dSEric Fiselier    : public __tuple_sfinae_base::__constructible<
433295bce11SEric Fiselier      typename __make_tuple_types<_Tp>::type
434295bce11SEric Fiselier    , typename __make_tuple_types<_Up>::type
435295bce11SEric Fiselier    >
436295bce11SEric Fiselier{};
437295bce11SEric Fiselier
438e2fd8b8dSEric Fiselier// __tuple_assignable
439e2fd8b8dSEric Fiselier
4403e519524SHoward Hinnanttemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
4413e519524SHoward Hinnant                                bool = __tuple_like<_Up>::value>
4423e519524SHoward Hinnantstruct __tuple_assignable
4433e519524SHoward Hinnant    : public false_type {};
4443e519524SHoward Hinnant
4453e519524SHoward Hinnanttemplate <class _Tp, class _Up>
4463e519524SHoward Hinnantstruct __tuple_assignable<_Tp, _Up, true, true>
447e2fd8b8dSEric Fiselier    : public __tuple_sfinae_base::__assignable<
448e2fd8b8dSEric Fiselier      typename __make_tuple_types<_Tp>::type
44927cdf401SEric Fiselier    , typename __make_tuple_types<_Up&>::type
450e2fd8b8dSEric Fiselier    >
4513e519524SHoward Hinnant{};
4523e519524SHoward Hinnant
4534927c295SEric Fiselier
4544927c295SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
4552b0c7abbSLouis Dionnestruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
4564927c295SEric Fiselier{
4573557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
4584927c295SEric Fiselier};
4594927c295SEric Fiselier
4604927c295SEric Fiselier#if _LIBCPP_STD_VER > 11
4614927c295SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
4623557c7c1SLouis Dionneusing tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type;
4634927c295SEric Fiselier#endif
4644927c295SEric Fiselier
465347a1cc2SEric Fiseliertemplate <bool _IsTuple, class _SizeTrait, size_t _Expected>
466347a1cc2SEric Fiselierstruct __tuple_like_with_size_imp : false_type {};
4674927c295SEric Fiselier
468347a1cc2SEric Fiseliertemplate <class _SizeTrait, size_t _Expected>
469347a1cc2SEric Fiselierstruct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
470347a1cc2SEric Fiselier    : integral_constant<bool, _SizeTrait::value == _Expected> {};
4714927c295SEric Fiselier
472f7558068SNikolas Klausertemplate <class _Tuple, size_t _ExpectedSize, class _RawTuple = __uncvref_t<_Tuple> >
4733557c7c1SLouis Dionneusing __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
474347a1cc2SEric Fiselier                                   __tuple_like<_RawTuple>::value,
475347a1cc2SEric Fiselier                                   tuple_size<_RawTuple>, _ExpectedSize
476347a1cc2SEric Fiselier                              >;
4774927c295SEric Fiselier
4784927c295SEric Fiselierstruct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
479c8ad8686SEric Fiselier
480c8ad8686SEric Fiselier    static constexpr bool __enable_explicit_default() { return false; }
481c8ad8686SEric Fiselier    static constexpr bool __enable_implicit_default() { return false; }
4824927c295SEric Fiselier    template <class ...>
4834927c295SEric Fiselier    static constexpr bool __enable_explicit() { return false; }
4844927c295SEric Fiselier    template <class ...>
4854927c295SEric Fiselier    static constexpr bool __enable_implicit() { return false; }
4864927c295SEric Fiselier    template <class ...>
4874927c295SEric Fiselier    static constexpr bool __enable_assign() { return false; }
4884927c295SEric Fiselier};
48929870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
4904927c295SEric Fiselier
491921a3f1cSEric Fiselier#if _LIBCPP_STD_VER > 14
492921a3f1cSEric Fiselier
493921a3f1cSEric Fiseliertemplate <bool _CanCopy, bool _CanMove>
494921a3f1cSEric Fiselierstruct __sfinae_ctor_base {};
495921a3f1cSEric Fiseliertemplate <>
496921a3f1cSEric Fiselierstruct __sfinae_ctor_base<false, false> {
497921a3f1cSEric Fiselier  __sfinae_ctor_base() = default;
498921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
499921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
500921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
501921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
502921a3f1cSEric Fiselier};
503921a3f1cSEric Fiseliertemplate <>
504921a3f1cSEric Fiselierstruct __sfinae_ctor_base<true, false> {
505921a3f1cSEric Fiselier  __sfinae_ctor_base() = default;
506921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
507921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
508921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
509921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
510921a3f1cSEric Fiselier};
511921a3f1cSEric Fiseliertemplate <>
512921a3f1cSEric Fiselierstruct __sfinae_ctor_base<false, true> {
513921a3f1cSEric Fiselier  __sfinae_ctor_base() = default;
514921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
515921a3f1cSEric Fiselier  __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
516921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
517921a3f1cSEric Fiselier  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
518921a3f1cSEric Fiselier};
519921a3f1cSEric Fiselier
520921a3f1cSEric Fiseliertemplate <bool _CanCopy, bool _CanMove>
521921a3f1cSEric Fiselierstruct __sfinae_assign_base {};
522921a3f1cSEric Fiseliertemplate <>
523921a3f1cSEric Fiselierstruct __sfinae_assign_base<false, false> {
524921a3f1cSEric Fiselier  __sfinae_assign_base() = default;
525921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base const&) = default;
526921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base &&) = default;
527921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
528921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
529921a3f1cSEric Fiselier};
530921a3f1cSEric Fiseliertemplate <>
531921a3f1cSEric Fiselierstruct __sfinae_assign_base<true, false> {
532921a3f1cSEric Fiselier  __sfinae_assign_base() = default;
533921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base const&) = default;
534921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base &&) = default;
535921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
536921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
537921a3f1cSEric Fiselier};
538921a3f1cSEric Fiseliertemplate <>
539921a3f1cSEric Fiselierstruct __sfinae_assign_base<false, true> {
540921a3f1cSEric Fiselier  __sfinae_assign_base() = default;
541921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base const&) = default;
542921a3f1cSEric Fiselier  __sfinae_assign_base(__sfinae_assign_base &&) = default;
543921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
544921a3f1cSEric Fiselier  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
545921a3f1cSEric Fiselier};
546921a3f1cSEric Fiselier#endif // _LIBCPP_STD_VER > 14
547921a3f1cSEric Fiselier
54857f00f2fSEric Fiselier_LIBCPP_END_NAMESPACE_STD
54957f00f2fSEric Fiselier
5503e519524SHoward Hinnant#endif // _LIBCPP___TUPLE
551