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