xref: /freebsd-12.1/contrib/libc++/include/__tuple (revision b5893f02)
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