17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------------------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP___TUPLE 127a984708SDavid Chisnall#define _LIBCPP___TUPLE 137a984708SDavid Chisnall 147a984708SDavid Chisnall#include <__config> 157a984708SDavid Chisnall#include <cstddef> 167a984708SDavid Chisnall#include <type_traits> 177a984708SDavid Chisnall 187a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 197a984708SDavid Chisnall#pragma GCC system_header 207a984708SDavid Chisnall#endif 217a984708SDavid Chisnall 227a984708SDavid Chisnall 237a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 247a984708SDavid Chisnall 25*b5893f02SDimitry Andrictemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; 26aed8d94eSDimitry Andric 27aed8d94eSDimitry Andric#if !defined(_LIBCPP_CXX03_LANG) 28aed8d94eSDimitry Andrictemplate <class _Tp, class...> 29aed8d94eSDimitry Andricusing __enable_if_tuple_size_imp = _Tp; 307a984708SDavid Chisnall 317a984708SDavid Chisnalltemplate <class _Tp> 32*b5893f02SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< 33aed8d94eSDimitry Andric const _Tp, 34aed8d94eSDimitry Andric typename enable_if<!is_volatile<_Tp>::value>::type, 35aed8d94eSDimitry Andric integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> 36aed8d94eSDimitry Andric : public integral_constant<size_t, tuple_size<_Tp>::value> {}; 377a984708SDavid Chisnall 387a984708SDavid Chisnalltemplate <class _Tp> 39*b5893f02SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< 40aed8d94eSDimitry Andric volatile _Tp, 41aed8d94eSDimitry Andric typename enable_if<!is_const<_Tp>::value>::type, 42aed8d94eSDimitry Andric integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> 43aed8d94eSDimitry Andric : public integral_constant<size_t, tuple_size<_Tp>::value> {}; 447a984708SDavid Chisnall 457a984708SDavid Chisnalltemplate <class _Tp> 46*b5893f02SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< 47aed8d94eSDimitry Andric const volatile _Tp, 48aed8d94eSDimitry Andric integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> 49aed8d94eSDimitry Andric : public integral_constant<size_t, tuple_size<_Tp>::value> {}; 507a984708SDavid Chisnall 51aed8d94eSDimitry Andric#else 52*b5893f02SDimitry Andrictemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; 53*b5893f02SDimitry Andrictemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; 54*b5893f02SDimitry Andrictemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; 55aed8d94eSDimitry Andric#endif 56aed8d94eSDimitry Andric 57aed8d94eSDimitry Andrictemplate <size_t _Ip, class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_element; 587a984708SDavid Chisnall 597a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp> 60aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> 617a984708SDavid Chisnall{ 627a984708SDavid Chisnallpublic: 637a984708SDavid Chisnall typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; 647a984708SDavid Chisnall}; 657a984708SDavid Chisnall 667a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp> 67aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> 687a984708SDavid Chisnall{ 697a984708SDavid Chisnallpublic: 707a984708SDavid Chisnall typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; 717a984708SDavid Chisnall}; 727a984708SDavid Chisnall 737a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp> 74aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> 757a984708SDavid Chisnall{ 767a984708SDavid Chisnallpublic: 777a984708SDavid Chisnall typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; 787a984708SDavid Chisnall}; 797a984708SDavid Chisnall 807a984708SDavid Chisnalltemplate <class _Tp> struct __tuple_like : false_type {}; 817a984708SDavid Chisnall 827a984708SDavid Chisnalltemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {}; 837a984708SDavid Chisnalltemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {}; 847a984708SDavid Chisnalltemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {}; 857a984708SDavid Chisnall 86854fa44bSDimitry Andric// tuple specializations 87854fa44bSDimitry Andric 88540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 897c82a1ecSDimitry Andric 907c82a1ecSDimitry Andrictemplate <size_t...> struct __tuple_indices {}; 917c82a1ecSDimitry Andric 927c82a1ecSDimitry Andrictemplate <class _IdxType, _IdxType... _Values> 937c82a1ecSDimitry Andricstruct __integer_sequence { 947c82a1ecSDimitry Andric template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> 957c82a1ecSDimitry Andric using __convert = _ToIndexSeq<_ToIndexType, _Values...>; 967c82a1ecSDimitry Andric 977c82a1ecSDimitry Andric template <size_t _Sp> 987c82a1ecSDimitry Andric using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; 997c82a1ecSDimitry Andric}; 1007c82a1ecSDimitry Andric 1017c82a1ecSDimitry Andric#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) 1027c82a1ecSDimitry Andricnamespace __detail { 1037c82a1ecSDimitry Andric 1047c82a1ecSDimitry Andrictemplate<typename _Tp, size_t ..._Extra> struct __repeat; 1057c82a1ecSDimitry Andrictemplate<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { 1067c82a1ecSDimitry Andric typedef __integer_sequence<_Tp, 1077c82a1ecSDimitry Andric _Np..., 1087c82a1ecSDimitry Andric sizeof...(_Np) + _Np..., 1097c82a1ecSDimitry Andric 2 * sizeof...(_Np) + _Np..., 1107c82a1ecSDimitry Andric 3 * sizeof...(_Np) + _Np..., 1117c82a1ecSDimitry Andric 4 * sizeof...(_Np) + _Np..., 1127c82a1ecSDimitry Andric 5 * sizeof...(_Np) + _Np..., 1137c82a1ecSDimitry Andric 6 * sizeof...(_Np) + _Np..., 1147c82a1ecSDimitry Andric 7 * sizeof...(_Np) + _Np..., 1157c82a1ecSDimitry Andric _Extra...> type; 1167c82a1ecSDimitry Andric}; 1177c82a1ecSDimitry Andric 1187c82a1ecSDimitry Andrictemplate<size_t _Np> struct __parity; 1197c82a1ecSDimitry Andrictemplate<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; 1207c82a1ecSDimitry Andric 1217c82a1ecSDimitry Andrictemplate<> struct __make<0> { typedef __integer_sequence<size_t> type; }; 1227c82a1ecSDimitry Andrictemplate<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; }; 1237c82a1ecSDimitry Andrictemplate<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; }; 1247c82a1ecSDimitry Andrictemplate<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; }; 1257c82a1ecSDimitry Andrictemplate<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; }; 1267c82a1ecSDimitry Andrictemplate<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; 1277c82a1ecSDimitry Andrictemplate<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; 1287c82a1ecSDimitry Andrictemplate<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; 1297c82a1ecSDimitry Andric 1307c82a1ecSDimitry Andrictemplate<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; 1317c82a1ecSDimitry Andrictemplate<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; 1327c82a1ecSDimitry Andrictemplate<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; 1337c82a1ecSDimitry Andrictemplate<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; 1347c82a1ecSDimitry Andrictemplate<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; 1357c82a1ecSDimitry Andrictemplate<> 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> {}; }; 1367c82a1ecSDimitry Andrictemplate<> 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> {}; }; 1377c82a1ecSDimitry Andrictemplate<> 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> {}; }; 1387c82a1ecSDimitry Andric 1397c82a1ecSDimitry Andric} // namespace detail 1407c82a1ecSDimitry Andric 1417c82a1ecSDimitry Andric#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) 1427c82a1ecSDimitry Andric 1437c82a1ecSDimitry Andric#if __has_builtin(__make_integer_seq) 1447c82a1ecSDimitry Andrictemplate <size_t _Ep, size_t _Sp> 1457c82a1ecSDimitry Andricusing __make_indices_imp = 1467c82a1ecSDimitry Andric typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template 1477c82a1ecSDimitry Andric __to_tuple_indices<_Sp>; 1487c82a1ecSDimitry Andric#else 1497c82a1ecSDimitry Andrictemplate <size_t _Ep, size_t _Sp> 1507c82a1ecSDimitry Andricusing __make_indices_imp = 1517c82a1ecSDimitry Andric typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; 1527c82a1ecSDimitry Andric 1537c82a1ecSDimitry Andric#endif 1547c82a1ecSDimitry Andric 1557c82a1ecSDimitry Andrictemplate <size_t _Ep, size_t _Sp = 0> 1567c82a1ecSDimitry Andricstruct __make_tuple_indices 1577c82a1ecSDimitry Andric{ 1587c82a1ecSDimitry Andric static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); 1597c82a1ecSDimitry Andric typedef __make_indices_imp<_Ep, _Sp> type; 1607c82a1ecSDimitry Andric}; 1617c82a1ecSDimitry Andric 1627c82a1ecSDimitry Andric 163aed8d94eSDimitry Andrictemplate <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple; 164854fa44bSDimitry Andric 1657a984708SDavid Chisnalltemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; 1667a984708SDavid Chisnall 167aed8d94eSDimitry Andrictemplate <class ..._Tp> 168*b5893f02SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > 169aed8d94eSDimitry Andric : public integral_constant<size_t, sizeof...(_Tp)> 170aed8d94eSDimitry Andric{ 171aed8d94eSDimitry Andric}; 172aed8d94eSDimitry Andric 1737a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp> 1744f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 1757a984708SDavid Chisnalltypename tuple_element<_Ip, tuple<_Tp...> >::type& 1767a984708SDavid Chisnallget(tuple<_Tp...>&) _NOEXCEPT; 1777a984708SDavid Chisnall 1787a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp> 1794f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 1807a984708SDavid Chisnallconst typename tuple_element<_Ip, tuple<_Tp...> >::type& 1817a984708SDavid Chisnallget(const tuple<_Tp...>&) _NOEXCEPT; 1827a984708SDavid Chisnall 1837a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp> 1844f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 1857a984708SDavid Chisnalltypename tuple_element<_Ip, tuple<_Tp...> >::type&& 1867a984708SDavid Chisnallget(tuple<_Tp...>&&) _NOEXCEPT; 1879729cf09SDimitry Andric 1889729cf09SDimitry Andrictemplate <size_t _Ip, class ..._Tp> 1899729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 1909729cf09SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&& 1919729cf09SDimitry Andricget(const tuple<_Tp...>&&) _NOEXCEPT; 192540d2a8bSDimitry Andric 193540d2a8bSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 194854fa44bSDimitry Andric 195854fa44bSDimitry Andric// pair specializations 196854fa44bSDimitry Andric 197854fa44bSDimitry Andrictemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; 1987a984708SDavid Chisnall 1997a984708SDavid Chisnalltemplate <size_t _Ip, class _T1, class _T2> 2004f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2017a984708SDavid Chisnalltypename tuple_element<_Ip, pair<_T1, _T2> >::type& 2027a984708SDavid Chisnallget(pair<_T1, _T2>&) _NOEXCEPT; 2037a984708SDavid Chisnall 2047a984708SDavid Chisnalltemplate <size_t _Ip, class _T1, class _T2> 2054f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2067a984708SDavid Chisnallconst typename tuple_element<_Ip, pair<_T1, _T2> >::type& 2077a984708SDavid Chisnallget(const pair<_T1, _T2>&) _NOEXCEPT; 2087a984708SDavid Chisnall 209540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2107a984708SDavid Chisnalltemplate <size_t _Ip, class _T1, class _T2> 2114f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2127a984708SDavid Chisnalltypename tuple_element<_Ip, pair<_T1, _T2> >::type&& 2137a984708SDavid Chisnallget(pair<_T1, _T2>&&) _NOEXCEPT; 2149729cf09SDimitry Andric 2159729cf09SDimitry Andrictemplate <size_t _Ip, class _T1, class _T2> 2169729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2179729cf09SDimitry Andricconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 2189729cf09SDimitry Andricget(const pair<_T1, _T2>&&) _NOEXCEPT; 219854fa44bSDimitry Andric#endif 220854fa44bSDimitry Andric 221854fa44bSDimitry Andric// array specializations 222854fa44bSDimitry Andric 223aed8d94eSDimitry Andrictemplate <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array; 224854fa44bSDimitry Andric 225854fa44bSDimitry Andrictemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {}; 2267a984708SDavid Chisnall 2277a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp, size_t _Size> 2284f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2297a984708SDavid Chisnall_Tp& 2307a984708SDavid Chisnallget(array<_Tp, _Size>&) _NOEXCEPT; 2317a984708SDavid Chisnall 2327a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp, size_t _Size> 2334f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2347a984708SDavid Chisnallconst _Tp& 2357a984708SDavid Chisnallget(const array<_Tp, _Size>&) _NOEXCEPT; 2367a984708SDavid Chisnall 237540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2387a984708SDavid Chisnalltemplate <size_t _Ip, class _Tp, size_t _Size> 2394f7ab58eSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2407a984708SDavid Chisnall_Tp&& 2417a984708SDavid Chisnallget(array<_Tp, _Size>&&) _NOEXCEPT; 2429729cf09SDimitry Andric 2439729cf09SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size> 2449729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2459729cf09SDimitry Andricconst _Tp&& 2469729cf09SDimitry Andricget(const array<_Tp, _Size>&&) _NOEXCEPT; 247854fa44bSDimitry Andric#endif 248854fa44bSDimitry Andric 249540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2507a984708SDavid Chisnall 2517a984708SDavid Chisnall// __tuple_types 2527a984708SDavid Chisnall 2537a984708SDavid Chisnalltemplate <class ..._Tp> struct __tuple_types {}; 2547a984708SDavid Chisnall 2557c82a1ecSDimitry Andric#if !__has_builtin(__type_pack_element) 2567c82a1ecSDimitry Andric 2577c82a1ecSDimitry Andricnamespace __indexer_detail { 2587c82a1ecSDimitry Andric 2597c82a1ecSDimitry Andrictemplate <size_t _Idx, class _Tp> 2607c82a1ecSDimitry Andricstruct __indexed { using type = _Tp; }; 2617c82a1ecSDimitry Andric 2627c82a1ecSDimitry Andrictemplate <class _Types, class _Indexes> struct __indexer; 2637c82a1ecSDimitry Andric 2647c82a1ecSDimitry Andrictemplate <class ..._Types, size_t ..._Idx> 2657c82a1ecSDimitry Andricstruct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> 2667c82a1ecSDimitry Andric : __indexed<_Idx, _Types>... 2677c82a1ecSDimitry Andric{}; 2687c82a1ecSDimitry Andric 2697c82a1ecSDimitry Andrictemplate <size_t _Idx, class _Tp> 2707c82a1ecSDimitry Andric__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); 2717c82a1ecSDimitry Andric 2727c82a1ecSDimitry Andric} // namespace __indexer_detail 2737c82a1ecSDimitry Andric 2747c82a1ecSDimitry Andrictemplate <size_t _Idx, class ..._Types> 2757c82a1ecSDimitry Andricusing __type_pack_element = typename decltype( 2767c82a1ecSDimitry Andric __indexer_detail::__at_index<_Idx>( 2777c82a1ecSDimitry Andric __indexer_detail::__indexer< 2787c82a1ecSDimitry Andric __tuple_types<_Types...>, 2797c82a1ecSDimitry Andric typename __make_tuple_indices<sizeof...(_Types)>::type 2807c82a1ecSDimitry Andric >{}) 2817c82a1ecSDimitry Andric )::type; 2827c82a1ecSDimitry Andric#endif 2837c82a1ecSDimitry Andric 2847c82a1ecSDimitry Andrictemplate <size_t _Ip, class ..._Types> 285aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...>> 2867a984708SDavid Chisnall{ 2877a984708SDavid Chisnallpublic: 2887c82a1ecSDimitry Andric static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); 2897c82a1ecSDimitry Andric typedef __type_pack_element<_Ip, _Types...> type; 2907a984708SDavid Chisnall}; 2917a984708SDavid Chisnall 2927a984708SDavid Chisnall 2937a984708SDavid Chisnalltemplate <class ..._Tp> 294*b5893f02SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > 2957a984708SDavid Chisnall : public integral_constant<size_t, sizeof...(_Tp)> 2967a984708SDavid Chisnall{ 2977a984708SDavid Chisnall}; 2987a984708SDavid Chisnall 2997a984708SDavid Chisnalltemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; 3007a984708SDavid Chisnall 3017c82a1ecSDimitry Andrictemplate <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile> 3027c82a1ecSDimitry Andricstruct __apply_cv_mf; 3037c82a1ecSDimitry Andrictemplate <> 3047c82a1ecSDimitry Andricstruct __apply_cv_mf<false, false, false> { 3057c82a1ecSDimitry Andric template <class _Tp> using __apply = _Tp; 3067c82a1ecSDimitry Andric}; 3077c82a1ecSDimitry Andrictemplate <> 3087c82a1ecSDimitry Andricstruct __apply_cv_mf<false, true, false> { 3097c82a1ecSDimitry Andric template <class _Tp> using __apply = const _Tp; 3107c82a1ecSDimitry Andric}; 3117c82a1ecSDimitry Andrictemplate <> 3127c82a1ecSDimitry Andricstruct __apply_cv_mf<false, false, true> { 3137c82a1ecSDimitry Andric template <class _Tp> using __apply = volatile _Tp; 3147c82a1ecSDimitry Andric}; 3157c82a1ecSDimitry Andrictemplate <> 3167c82a1ecSDimitry Andricstruct __apply_cv_mf<false, true, true> { 3177c82a1ecSDimitry Andric template <class _Tp> using __apply = const volatile _Tp; 3187c82a1ecSDimitry Andric}; 3197c82a1ecSDimitry Andrictemplate <> 3207c82a1ecSDimitry Andricstruct __apply_cv_mf<true, false, false> { 3217c82a1ecSDimitry Andric template <class _Tp> using __apply = _Tp&; 3227c82a1ecSDimitry Andric}; 3237c82a1ecSDimitry Andrictemplate <> 3247c82a1ecSDimitry Andricstruct __apply_cv_mf<true, true, false> { 3257c82a1ecSDimitry Andric template <class _Tp> using __apply = const _Tp&; 3267c82a1ecSDimitry Andric}; 3277c82a1ecSDimitry Andrictemplate <> 3287c82a1ecSDimitry Andricstruct __apply_cv_mf<true, false, true> { 3297c82a1ecSDimitry Andric template <class _Tp> using __apply = volatile _Tp&; 3307c82a1ecSDimitry Andric}; 3317c82a1ecSDimitry Andrictemplate <> 3327c82a1ecSDimitry Andricstruct __apply_cv_mf<true, true, true> { 3337c82a1ecSDimitry Andric template <class _Tp> using __apply = const volatile _Tp&; 3347c82a1ecSDimitry Andric}; 3357c82a1ecSDimitry Andrictemplate <class _Tp, class _RawTp = typename remove_reference<_Tp>::type> 3367c82a1ecSDimitry Andricusing __apply_cv_t = __apply_cv_mf< 3377c82a1ecSDimitry Andric is_lvalue_reference<_Tp>::value, 3387c82a1ecSDimitry Andric is_const<_RawTp>::value, 3397c82a1ecSDimitry Andric is_volatile<_RawTp>::value>; 3407c82a1ecSDimitry Andric 3417a984708SDavid Chisnall// __make_tuple_types 3427a984708SDavid Chisnall 3437a984708SDavid Chisnall// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a 3447a984708SDavid Chisnall// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). 3457a984708SDavid Chisnall// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a 3467a984708SDavid Chisnall// lvalue_reference type, then __tuple_types<_Types&...> is the result. 3477a984708SDavid Chisnall 3487c82a1ecSDimitry Andrictemplate <class _TupleTypes, class _TupleIndices> 3497c82a1ecSDimitry Andricstruct __make_tuple_types_flat; 3507a984708SDavid Chisnall 3517c82a1ecSDimitry Andrictemplate <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> 3527c82a1ecSDimitry Andricstruct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { 3537c82a1ecSDimitry Andric // Specialization for pair, tuple, and __tuple_types 3547c82a1ecSDimitry Andric template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> 3557c82a1ecSDimitry Andric using __apply_quals = __tuple_types< 3567c82a1ecSDimitry Andric typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>... 3577c82a1ecSDimitry Andric >; 3587a984708SDavid Chisnall}; 3597a984708SDavid Chisnall 3607c82a1ecSDimitry Andrictemplate <class _Vt, size_t _Np, size_t ..._Idx> 3617c82a1ecSDimitry Andricstruct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { 3627c82a1ecSDimitry Andric template <size_t> 3637c82a1ecSDimitry Andric using __value_type = _Vt; 3647c82a1ecSDimitry Andric template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> 3657c82a1ecSDimitry Andric using __apply_quals = __tuple_types< 3667c82a1ecSDimitry Andric typename _ApplyFn::template __apply<__value_type<_Idx>>... 3677c82a1ecSDimitry Andric >; 3687a984708SDavid Chisnall}; 3697a984708SDavid Chisnall 3707c82a1ecSDimitry Andrictemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, 3717c82a1ecSDimitry Andric size_t _Sp = 0, 3727c82a1ecSDimitry Andric bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)> 3737a984708SDavid Chisnallstruct __make_tuple_types 3747a984708SDavid Chisnall{ 3757a984708SDavid Chisnall static_assert(_Sp <= _Ep, "__make_tuple_types input error"); 3767c82a1ecSDimitry Andric using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type; 3777c82a1ecSDimitry Andric using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; 3787c82a1ecSDimitry Andric using type = typename _Maker::template __apply_quals<_Tp>; 3797c82a1ecSDimitry Andric}; 3807c82a1ecSDimitry Andric 3817c82a1ecSDimitry Andrictemplate <class ..._Types, size_t _Ep> 3827c82a1ecSDimitry Andricstruct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { 3837c82a1ecSDimitry Andric typedef __tuple_types<_Types...> type; 3847c82a1ecSDimitry Andric}; 3857c82a1ecSDimitry Andric 3867c82a1ecSDimitry Andrictemplate <class ..._Types, size_t _Ep> 3877c82a1ecSDimitry Andricstruct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { 3887c82a1ecSDimitry Andric typedef __tuple_types<_Types...> type; 3897c82a1ecSDimitry Andric}; 3907c82a1ecSDimitry Andric 3917c82a1ecSDimitry Andrictemplate <bool ..._Preds> 3927c82a1ecSDimitry Andricstruct __all_dummy; 3937c82a1ecSDimitry Andric 3947c82a1ecSDimitry Andrictemplate <bool ..._Pred> 395aed8d94eSDimitry Andricusing __all = is_same<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>; 3967c82a1ecSDimitry Andric 3977c82a1ecSDimitry Andricstruct __tuple_sfinae_base { 3987c82a1ecSDimitry Andric template <template <class, class...> class _Trait, 3997c82a1ecSDimitry Andric class ..._LArgs, class ..._RArgs> 4007c82a1ecSDimitry Andric static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) 4017c82a1ecSDimitry Andric -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>; 4027c82a1ecSDimitry Andric template <template <class...> class> 4037c82a1ecSDimitry Andric static auto __do_test(...) -> false_type; 4047c82a1ecSDimitry Andric 4057c82a1ecSDimitry Andric template <class _FromArgs, class _ToArgs> 4067c82a1ecSDimitry Andric using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); 4077c82a1ecSDimitry Andric template <class _FromArgs, class _ToArgs> 4087c82a1ecSDimitry Andric using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); 4097c82a1ecSDimitry Andric template <class _FromArgs, class _ToArgs> 4107c82a1ecSDimitry Andric using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); 4117a984708SDavid Chisnall}; 4127a984708SDavid Chisnall 4137a984708SDavid Chisnall// __tuple_convertible 4147a984708SDavid Chisnall 4157a984708SDavid Chisnalltemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 4167a984708SDavid Chisnall bool = __tuple_like<_Up>::value> 4177a984708SDavid Chisnallstruct __tuple_convertible 4187a984708SDavid Chisnall : public false_type {}; 4197a984708SDavid Chisnall 4207a984708SDavid Chisnalltemplate <class _Tp, class _Up> 4217a984708SDavid Chisnallstruct __tuple_convertible<_Tp, _Up, true, true> 4227c82a1ecSDimitry Andric : public __tuple_sfinae_base::__convertible< 423d72607e9SDimitry Andric typename __make_tuple_types<_Tp>::type 424d72607e9SDimitry Andric , typename __make_tuple_types<_Up>::type 425d72607e9SDimitry Andric > 426d72607e9SDimitry Andric{}; 427d72607e9SDimitry Andric 4287c82a1ecSDimitry Andric// __tuple_constructible 4297c82a1ecSDimitry Andric 430b03f91a8SDavid Chisnalltemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 431b03f91a8SDavid Chisnall bool = __tuple_like<_Up>::value> 432b03f91a8SDavid Chisnallstruct __tuple_constructible 433b03f91a8SDavid Chisnall : public false_type {}; 434b03f91a8SDavid Chisnall 435b03f91a8SDavid Chisnalltemplate <class _Tp, class _Up> 436b03f91a8SDavid Chisnallstruct __tuple_constructible<_Tp, _Up, true, true> 4377c82a1ecSDimitry Andric : public __tuple_sfinae_base::__constructible< 438d72607e9SDimitry Andric typename __make_tuple_types<_Tp>::type 439d72607e9SDimitry Andric , typename __make_tuple_types<_Up>::type 440d72607e9SDimitry Andric > 441d72607e9SDimitry Andric{}; 442d72607e9SDimitry Andric 4437c82a1ecSDimitry Andric// __tuple_assignable 4447c82a1ecSDimitry Andric 4457a984708SDavid Chisnalltemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 4467a984708SDavid Chisnall bool = __tuple_like<_Up>::value> 4477a984708SDavid Chisnallstruct __tuple_assignable 4487a984708SDavid Chisnall : public false_type {}; 4497a984708SDavid Chisnall 4507a984708SDavid Chisnalltemplate <class _Tp, class _Up> 4517a984708SDavid Chisnallstruct __tuple_assignable<_Tp, _Up, true, true> 4527c82a1ecSDimitry Andric : public __tuple_sfinae_base::__assignable< 4537c82a1ecSDimitry Andric typename __make_tuple_types<_Tp>::type 4547c82a1ecSDimitry Andric , typename __make_tuple_types<_Up&>::type 4557c82a1ecSDimitry Andric > 4567a984708SDavid Chisnall{}; 4577a984708SDavid Chisnall 458aed8d94eSDimitry Andric 459aed8d94eSDimitry Andrictemplate <size_t _Ip, class ..._Tp> 460aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > 461aed8d94eSDimitry Andric{ 462aed8d94eSDimitry Andricpublic: 463aed8d94eSDimitry Andric typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; 464aed8d94eSDimitry Andric}; 465aed8d94eSDimitry Andric 466aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 11 467aed8d94eSDimitry Andrictemplate <size_t _Ip, class ..._Tp> 468aed8d94eSDimitry Andricusing tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; 469aed8d94eSDimitry Andric#endif 470aed8d94eSDimitry Andric 471aed8d94eSDimitry Andrictemplate <bool _IsTuple, class _SizeTrait, size_t _Expected> 472aed8d94eSDimitry Andricstruct __tuple_like_with_size_imp : false_type {}; 473aed8d94eSDimitry Andric 474aed8d94eSDimitry Andrictemplate <class _SizeTrait, size_t _Expected> 475aed8d94eSDimitry Andricstruct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> 476aed8d94eSDimitry Andric : integral_constant<bool, _SizeTrait::value == _Expected> {}; 477aed8d94eSDimitry Andric 478aed8d94eSDimitry Andrictemplate <class _Tuple, size_t _ExpectedSize, 479aed8d94eSDimitry Andric class _RawTuple = typename __uncvref<_Tuple>::type> 480aed8d94eSDimitry Andricusing __tuple_like_with_size = __tuple_like_with_size_imp< 481aed8d94eSDimitry Andric __tuple_like<_RawTuple>::value, 482aed8d94eSDimitry Andric tuple_size<_RawTuple>, _ExpectedSize 483aed8d94eSDimitry Andric >; 484aed8d94eSDimitry Andric 485aed8d94eSDimitry Andricstruct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { 486aed8d94eSDimitry Andric template <class ...> 487aed8d94eSDimitry Andric static constexpr bool __enable_default() { return false; } 488aed8d94eSDimitry Andric template <class ...> 489aed8d94eSDimitry Andric static constexpr bool __enable_explicit() { return false; } 490aed8d94eSDimitry Andric template <class ...> 491aed8d94eSDimitry Andric static constexpr bool __enable_implicit() { return false; } 492aed8d94eSDimitry Andric template <class ...> 493aed8d94eSDimitry Andric static constexpr bool __enable_assign() { return false; } 494aed8d94eSDimitry Andric}; 495540d2a8bSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 496aed8d94eSDimitry Andric 497aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14 498aed8d94eSDimitry Andric 499aed8d94eSDimitry Andrictemplate <bool _CanCopy, bool _CanMove> 500aed8d94eSDimitry Andricstruct __sfinae_ctor_base {}; 501aed8d94eSDimitry Andrictemplate <> 502aed8d94eSDimitry Andricstruct __sfinae_ctor_base<false, false> { 503aed8d94eSDimitry Andric __sfinae_ctor_base() = default; 504aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; 505aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; 506aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; 507aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; 508aed8d94eSDimitry Andric}; 509aed8d94eSDimitry Andrictemplate <> 510aed8d94eSDimitry Andricstruct __sfinae_ctor_base<true, false> { 511aed8d94eSDimitry Andric __sfinae_ctor_base() = default; 512aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base const&) = default; 513aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; 514aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; 515aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; 516aed8d94eSDimitry Andric}; 517aed8d94eSDimitry Andrictemplate <> 518aed8d94eSDimitry Andricstruct __sfinae_ctor_base<false, true> { 519aed8d94eSDimitry Andric __sfinae_ctor_base() = default; 520aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; 521aed8d94eSDimitry Andric __sfinae_ctor_base(__sfinae_ctor_base &&) = default; 522aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; 523aed8d94eSDimitry Andric __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; 524aed8d94eSDimitry Andric}; 525aed8d94eSDimitry Andric 526aed8d94eSDimitry Andrictemplate <bool _CanCopy, bool _CanMove> 527aed8d94eSDimitry Andricstruct __sfinae_assign_base {}; 528aed8d94eSDimitry Andrictemplate <> 529aed8d94eSDimitry Andricstruct __sfinae_assign_base<false, false> { 530aed8d94eSDimitry Andric __sfinae_assign_base() = default; 531aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base const&) = default; 532aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base &&) = default; 533aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; 534aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; 535aed8d94eSDimitry Andric}; 536aed8d94eSDimitry Andrictemplate <> 537aed8d94eSDimitry Andricstruct __sfinae_assign_base<true, false> { 538aed8d94eSDimitry Andric __sfinae_assign_base() = default; 539aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base const&) = default; 540aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base &&) = default; 541aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default; 542aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; 543aed8d94eSDimitry Andric}; 544aed8d94eSDimitry Andrictemplate <> 545aed8d94eSDimitry Andricstruct __sfinae_assign_base<false, true> { 546aed8d94eSDimitry Andric __sfinae_assign_base() = default; 547aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base const&) = default; 548aed8d94eSDimitry Andric __sfinae_assign_base(__sfinae_assign_base &&) = default; 549aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; 550aed8d94eSDimitry Andric __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default; 551aed8d94eSDimitry Andric}; 552aed8d94eSDimitry Andric#endif // _LIBCPP_STD_VER > 14 553aed8d94eSDimitry Andric 554854fa44bSDimitry Andric_LIBCPP_END_NAMESPACE_STD 555854fa44bSDimitry Andric 5567a984708SDavid Chisnall#endif // _LIBCPP___TUPLE 557