xref: /freebsd-12.1/contrib/libc++/include/tuple (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===--------------------------- tuple ------------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is distributed under the University of Illinois Open Source
77a984708SDavid Chisnall// License. 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/*
157a984708SDavid Chisnall    tuple synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnalltemplate <class... T>
217a984708SDavid Chisnallclass tuple {
227a984708SDavid Chisnallpublic:
237a984708SDavid Chisnall    constexpr tuple();
244f7ab58eSDimitry Andric    explicit tuple(const T&...);  // constexpr in C++14
257a984708SDavid Chisnall    template <class... U>
264f7ab58eSDimitry Andric        explicit tuple(U&&...);  // constexpr in C++14
277a984708SDavid Chisnall    tuple(const tuple&) = default;
287a984708SDavid Chisnall    tuple(tuple&&) = default;
297a984708SDavid Chisnall    template <class... U>
304f7ab58eSDimitry Andric        tuple(const tuple<U...>&);  // constexpr in C++14
317a984708SDavid Chisnall    template <class... U>
324f7ab58eSDimitry Andric        tuple(tuple<U...>&&);  // constexpr in C++14
337a984708SDavid Chisnall    template <class U1, class U2>
344f7ab58eSDimitry Andric        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
357a984708SDavid Chisnall    template <class U1, class U2>
364f7ab58eSDimitry Andric        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
377a984708SDavid Chisnall
387a984708SDavid Chisnall    // allocator-extended constructors
397a984708SDavid Chisnall    template <class Alloc>
407a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a);
417a984708SDavid Chisnall    template <class Alloc>
427a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, const T&...);
437a984708SDavid Chisnall    template <class Alloc, class... U>
447a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, U&&...);
457a984708SDavid Chisnall    template <class Alloc>
467a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, const tuple&);
477a984708SDavid Chisnall    template <class Alloc>
487a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, tuple&&);
497a984708SDavid Chisnall    template <class Alloc, class... U>
507a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
517a984708SDavid Chisnall    template <class Alloc, class... U>
527a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
537a984708SDavid Chisnall    template <class Alloc, class U1, class U2>
547a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
557a984708SDavid Chisnall    template <class Alloc, class U1, class U2>
567a984708SDavid Chisnall        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
577a984708SDavid Chisnall
587a984708SDavid Chisnall    tuple& operator=(const tuple&);
597a984708SDavid Chisnall    tuple&
607a984708SDavid Chisnall        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
617a984708SDavid Chisnall    template <class... U>
627a984708SDavid Chisnall        tuple& operator=(const tuple<U...>&);
637a984708SDavid Chisnall    template <class... U>
647a984708SDavid Chisnall        tuple& operator=(tuple<U...>&&);
657a984708SDavid Chisnall    template <class U1, class U2>
667a984708SDavid Chisnall        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
677a984708SDavid Chisnall    template <class U1, class U2>
687a984708SDavid Chisnall        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2
697a984708SDavid Chisnall
707a984708SDavid Chisnall    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
717a984708SDavid Chisnall};
727a984708SDavid Chisnall
7330785c0eSDimitry Andricinline constexpr unspecified ignore;
747a984708SDavid Chisnall
754f7ab58eSDimitry Andrictemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
764f7ab58eSDimitry Andrictemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
77d72607e9SDimitry Andrictemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
784f7ab58eSDimitry Andrictemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
797a984708SDavid Chisnall
807c82a1ecSDimitry Andric// [tuple.apply], calling a function with a tuple of arguments:
817c82a1ecSDimitry Andrictemplate <class F, class Tuple>
827c82a1ecSDimitry Andric  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
837c82a1ecSDimitry Andrictemplate <class T, class Tuple>
847c82a1ecSDimitry Andric  constexpr T make_from_tuple(Tuple&& t); // C++17
857c82a1ecSDimitry Andric
867a984708SDavid Chisnall// 20.4.1.4, tuple helper classes:
87*b5893f02SDimitry Andrictemplate <class T> struct tuple_size; // undefined
88*b5893f02SDimitry Andrictemplate <class... T> struct tuple_size<tuple<T...>>;
897c82a1ecSDimitry Andrictemplate <class T>
9030785c0eSDimitry Andric inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
919729cf09SDimitry Andrictemplate <size_t I, class T> class tuple_element; // undefined
929729cf09SDimitry Andrictemplate <size_t I, class... T> class tuple_element<I, tuple<T...>>;
939729cf09SDimitry Andrictemplate <size_t I, class T>
949729cf09SDimitry Andric  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
957a984708SDavid Chisnall
967a984708SDavid Chisnall// 20.4.1.5, element access:
979729cf09SDimitry Andrictemplate <size_t I, class... T>
987a984708SDavid Chisnall    typename tuple_element<I, tuple<T...>>::type&
994f7ab58eSDimitry Andric    get(tuple<T...>&) noexcept; // constexpr in C++14
1009729cf09SDimitry Andrictemplate <size_t I, class... T>
1019729cf09SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&
1024f7ab58eSDimitry Andric    get(const tuple<T...>&) noexcept; // constexpr in C++14
1039729cf09SDimitry Andrictemplate <size_t I, class... T>
1047a984708SDavid Chisnall    typename tuple_element<I, tuple<T...>>::type&&
1054f7ab58eSDimitry Andric    get(tuple<T...>&&) noexcept; // constexpr in C++14
1069729cf09SDimitry Andrictemplate <size_t I, class... T>
1079729cf09SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&&
1089729cf09SDimitry Andric    get(const tuple<T...>&&) noexcept; // constexpr in C++14
1094f7ab58eSDimitry Andric
1104f7ab58eSDimitry Andrictemplate <class T1, class... T>
1114f7ab58eSDimitry Andric    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
1124f7ab58eSDimitry Andrictemplate <class T1, class... T>
1139729cf09SDimitry Andric    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
1144f7ab58eSDimitry Andrictemplate <class T1, class... T>
1154f7ab58eSDimitry Andric    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
1169729cf09SDimitry Andrictemplate <class T1, class... T>
1179729cf09SDimitry Andric    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
1187a984708SDavid Chisnall
1197a984708SDavid Chisnall// 20.4.1.6, relational operators:
1204f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
1214f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
1224f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
1234f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
1244f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
1254f7ab58eSDimitry Andrictemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
1267a984708SDavid Chisnall
1277a984708SDavid Chisnalltemplate <class... Types, class Alloc>
1287a984708SDavid Chisnall  struct uses_allocator<tuple<Types...>, Alloc>;
1297a984708SDavid Chisnall
1307a984708SDavid Chisnalltemplate <class... Types>
1317a984708SDavid Chisnall  void
1327a984708SDavid Chisnall  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1337a984708SDavid Chisnall
1347a984708SDavid Chisnall}  // std
1357a984708SDavid Chisnall
1367a984708SDavid Chisnall*/
1377a984708SDavid Chisnall
1387a984708SDavid Chisnall#include <__config>
1397a984708SDavid Chisnall#include <__tuple>
1407a984708SDavid Chisnall#include <cstddef>
1417a984708SDavid Chisnall#include <type_traits>
14294e3ee44SDavid Chisnall#include <__functional_base>
14394e3ee44SDavid Chisnall#include <utility>
144*b5893f02SDimitry Andric#include <version>
1457a984708SDavid Chisnall
1467a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1477a984708SDavid Chisnall#pragma GCC system_header
1487a984708SDavid Chisnall#endif
1497a984708SDavid Chisnall
1507a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
1517a984708SDavid Chisnall
152540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1537a984708SDavid Chisnall
154d72607e9SDimitry Andric
1557a984708SDavid Chisnall// __tuple_leaf
1567a984708SDavid Chisnall
157854fa44bSDimitry Andrictemplate <size_t _Ip, class _Hp,
158854fa44bSDimitry Andric          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
15994e3ee44SDavid Chisnall         >
1607a984708SDavid Chisnallclass __tuple_leaf;
1617a984708SDavid Chisnall
1627a984708SDavid Chisnalltemplate <size_t _Ip, class _Hp, bool _Ep>
1637a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
1647a984708SDavid Chisnallvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
1657a984708SDavid Chisnall    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
1667a984708SDavid Chisnall{
1677a984708SDavid Chisnall    swap(__x.get(), __y.get());
1687a984708SDavid Chisnall}
1697a984708SDavid Chisnall
1707a984708SDavid Chisnalltemplate <size_t _Ip, class _Hp, bool>
1717a984708SDavid Chisnallclass __tuple_leaf
1727a984708SDavid Chisnall{
173f9448bf3SDimitry Andric    _Hp __value_;
1747a984708SDavid Chisnall
175aed8d94eSDimitry Andric    template <class _Tp>
176aed8d94eSDimitry Andric    static constexpr bool __can_bind_reference() {
1774ba319b5SDimitry Andric#if __has_keyword(__reference_binds_to_temporary)
1784ba319b5SDimitry Andric      return !__reference_binds_to_temporary(_Hp, _Tp);
1794ba319b5SDimitry Andric#else
1804ba319b5SDimitry Andric      return true;
1814ba319b5SDimitry Andric#endif
182aed8d94eSDimitry Andric    }
183aed8d94eSDimitry Andric
1847a984708SDavid Chisnall    __tuple_leaf& operator=(const __tuple_leaf&);
1857a984708SDavid Chisnallpublic:
186936e9439SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
187f9448bf3SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
1887a984708SDavid Chisnall       {static_assert(!is_reference<_Hp>::value,
1897a984708SDavid Chisnall              "Attempted to default construct a reference element in a tuple");}
1907a984708SDavid Chisnall
1917a984708SDavid Chisnall    template <class _Alloc>
1927a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
1937a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
194f9448bf3SDimitry Andric            : __value_()
1957a984708SDavid Chisnall        {static_assert(!is_reference<_Hp>::value,
1967a984708SDavid Chisnall              "Attempted to default construct a reference element in a tuple");}
1977a984708SDavid Chisnall
1987a984708SDavid Chisnall    template <class _Alloc>
1997a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2007a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
201f9448bf3SDimitry Andric            : __value_(allocator_arg_t(), __a)
2027a984708SDavid Chisnall        {static_assert(!is_reference<_Hp>::value,
2037a984708SDavid Chisnall              "Attempted to default construct a reference element in a tuple");}
2047a984708SDavid Chisnall
2057a984708SDavid Chisnall    template <class _Alloc>
2067a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2077a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
208f9448bf3SDimitry Andric            : __value_(__a)
2097a984708SDavid Chisnall        {static_assert(!is_reference<_Hp>::value,
2107a984708SDavid Chisnall              "Attempted to default construct a reference element in a tuple");}
2117a984708SDavid Chisnall
2127a984708SDavid Chisnall    template <class _Tp,
213d72607e9SDimitry Andric              class = typename enable_if<
214d72607e9SDimitry Andric                  __lazy_and<
2154ba319b5SDimitry Andric                      __lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>>
216d72607e9SDimitry Andric                    , is_constructible<_Hp, _Tp>
217d72607e9SDimitry Andric                    >::value
218d72607e9SDimitry Andric                >::type
219d72607e9SDimitry Andric            >
2204f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
221936e9439SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
222f9448bf3SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
2234ba319b5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
2244ba319b5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2257a984708SDavid Chisnall
2267a984708SDavid Chisnall    template <class _Tp, class _Alloc>
2277a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2287a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
229f9448bf3SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
2304ba319b5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
2314ba319b5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2327a984708SDavid Chisnall
2337a984708SDavid Chisnall    template <class _Tp, class _Alloc>
2347a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2357a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
236f9448bf3SDimitry Andric            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
237aed8d94eSDimitry Andric        {static_assert(!is_reference<_Hp>::value,
238aed8d94eSDimitry Andric            "Attempted to uses-allocator construct a reference element in a tuple");}
2397a984708SDavid Chisnall
2407a984708SDavid Chisnall    template <class _Tp, class _Alloc>
2417a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2427a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
243f9448bf3SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t), __a)
244aed8d94eSDimitry Andric        {static_assert(!is_reference<_Hp>::value,
245aed8d94eSDimitry Andric           "Attempted to uses-allocator construct a reference element in a tuple");}
2467a984708SDavid Chisnall
247d72607e9SDimitry Andric    __tuple_leaf(const __tuple_leaf& __t) = default;
248d72607e9SDimitry Andric    __tuple_leaf(__tuple_leaf&& __t) = default;
2497a984708SDavid Chisnall
2507a984708SDavid Chisnall    template <class _Tp>
2517a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2527a984708SDavid Chisnall        __tuple_leaf&
253936e9439SDimitry Andric        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
2547a984708SDavid Chisnall        {
255f9448bf3SDimitry Andric            __value_ = _VSTD::forward<_Tp>(__t);
2567a984708SDavid Chisnall            return *this;
2577a984708SDavid Chisnall        }
2587a984708SDavid Chisnall
2597a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2607a984708SDavid Chisnall    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
2617a984708SDavid Chisnall    {
2627a984708SDavid Chisnall        _VSTD::swap(*this, __t);
2637a984708SDavid Chisnall        return 0;
2647a984708SDavid Chisnall    }
2657a984708SDavid Chisnall
266f9448bf3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
267f9448bf3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
2687a984708SDavid Chisnall};
2697a984708SDavid Chisnall
2707a984708SDavid Chisnalltemplate <size_t _Ip, class _Hp>
2717a984708SDavid Chisnallclass __tuple_leaf<_Ip, _Hp, true>
2727a984708SDavid Chisnall    : private _Hp
2737a984708SDavid Chisnall{
2747a984708SDavid Chisnall
2757a984708SDavid Chisnall    __tuple_leaf& operator=(const __tuple_leaf&);
2767a984708SDavid Chisnallpublic:
277936e9439SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
278936e9439SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
2797a984708SDavid Chisnall
2807a984708SDavid Chisnall    template <class _Alloc>
2817a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2827a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
2837a984708SDavid Chisnall
2847a984708SDavid Chisnall    template <class _Alloc>
2857a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2867a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
2877a984708SDavid Chisnall            : _Hp(allocator_arg_t(), __a) {}
2887a984708SDavid Chisnall
2897a984708SDavid Chisnall    template <class _Alloc>
2907a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2917a984708SDavid Chisnall        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
2927a984708SDavid Chisnall            : _Hp(__a) {}
2937a984708SDavid Chisnall
2947a984708SDavid Chisnall    template <class _Tp,
295d72607e9SDimitry Andric              class = typename enable_if<
296d72607e9SDimitry Andric                  __lazy_and<
2974ba319b5SDimitry Andric                        __lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>>
298d72607e9SDimitry Andric                      , is_constructible<_Hp, _Tp>
299d72607e9SDimitry Andric                    >::value
300d72607e9SDimitry Andric                >::type
301d72607e9SDimitry Andric            >
3024f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
303936e9439SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3047a984708SDavid Chisnall            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3057a984708SDavid Chisnall
3067a984708SDavid Chisnall    template <class _Tp, class _Alloc>
3077a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3087a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
3097a984708SDavid Chisnall            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3107a984708SDavid Chisnall
3117a984708SDavid Chisnall    template <class _Tp, class _Alloc>
3127a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3137a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
3147a984708SDavid Chisnall            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3157a984708SDavid Chisnall
3167a984708SDavid Chisnall    template <class _Tp, class _Alloc>
3177a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3187a984708SDavid Chisnall        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
3197a984708SDavid Chisnall            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3207a984708SDavid Chisnall
321d72607e9SDimitry Andric    __tuple_leaf(__tuple_leaf const &) = default;
322d72607e9SDimitry Andric    __tuple_leaf(__tuple_leaf &&) = default;
323d72607e9SDimitry Andric
3247a984708SDavid Chisnall    template <class _Tp>
3257a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3267a984708SDavid Chisnall        __tuple_leaf&
327936e9439SDimitry Andric        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
3287a984708SDavid Chisnall        {
3297a984708SDavid Chisnall            _Hp::operator=(_VSTD::forward<_Tp>(__t));
3307a984708SDavid Chisnall            return *this;
3317a984708SDavid Chisnall        }
3327a984708SDavid Chisnall
3337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3347a984708SDavid Chisnall    int
3357a984708SDavid Chisnall    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3367a984708SDavid Chisnall    {
3377a984708SDavid Chisnall        _VSTD::swap(*this, __t);
3387a984708SDavid Chisnall        return 0;
3397a984708SDavid Chisnall    }
3407a984708SDavid Chisnall
3414f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
3424f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3437a984708SDavid Chisnall};
3447a984708SDavid Chisnall
3457a984708SDavid Chisnalltemplate <class ..._Tp>
3467a984708SDavid Chisnall_LIBCPP_INLINE_VISIBILITY
347936e9439SDimitry Andricvoid __swallow(_Tp&&...) _NOEXCEPT {}
3487a984708SDavid Chisnall
3497c82a1ecSDimitry Andrictemplate <class ..._Tp>
3507c82a1ecSDimitry Andricstruct __lazy_all : __all<_Tp::value...> {};
3517a984708SDavid Chisnall
352d72607e9SDimitry Andrictemplate <class _Tp>
353d72607e9SDimitry Andricstruct __all_default_constructible;
3547a984708SDavid Chisnall
355d72607e9SDimitry Andrictemplate <class ..._Tp>
356d72607e9SDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>>
357d72607e9SDimitry Andric    : __all<is_default_constructible<_Tp>::value...>
358d72607e9SDimitry Andric{ };
3597a984708SDavid Chisnall
3607a984708SDavid Chisnall// __tuple_impl
3617a984708SDavid Chisnall
3627a984708SDavid Chisnalltemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3637a984708SDavid Chisnall
3647a984708SDavid Chisnalltemplate<size_t ..._Indx, class ..._Tp>
365540d2a8bSDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3667a984708SDavid Chisnall    : public __tuple_leaf<_Indx, _Tp>...
3677a984708SDavid Chisnall{
368936e9439SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
369936e9439SDimitry Andric    _LIBCPP_CONSTEXPR __tuple_impl()
370936e9439SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
371936e9439SDimitry Andric
3727a984708SDavid Chisnall    template <size_t ..._Uf, class ..._Tf,
3737a984708SDavid Chisnall              size_t ..._Ul, class ..._Tl, class ..._Up>
3744f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3757a984708SDavid Chisnall        explicit
3767a984708SDavid Chisnall        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3777a984708SDavid Chisnall                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
378936e9439SDimitry Andric                     _Up&&... __u)
379936e9439SDimitry Andric                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
380936e9439SDimitry Andric                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
3817a984708SDavid Chisnall            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
3827a984708SDavid Chisnall            __tuple_leaf<_Ul, _Tl>()...
3837a984708SDavid Chisnall            {}
3847a984708SDavid Chisnall
3857a984708SDavid Chisnall    template <class _Alloc, size_t ..._Uf, class ..._Tf,
3867a984708SDavid Chisnall              size_t ..._Ul, class ..._Tl, class ..._Up>
3877a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3887a984708SDavid Chisnall        explicit
3897a984708SDavid Chisnall        __tuple_impl(allocator_arg_t, const _Alloc& __a,
3907a984708SDavid Chisnall                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3917a984708SDavid Chisnall                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3927a984708SDavid Chisnall                     _Up&&... __u) :
3937a984708SDavid Chisnall            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
3947a984708SDavid Chisnall            _VSTD::forward<_Up>(__u))...,
3957a984708SDavid Chisnall            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
3967a984708SDavid Chisnall            {}
3977a984708SDavid Chisnall
3987a984708SDavid Chisnall    template <class _Tuple,
3997a984708SDavid Chisnall              class = typename enable_if
4007a984708SDavid Chisnall                      <
4011bf9f7c1SDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4027a984708SDavid Chisnall                      >::type
4037a984708SDavid Chisnall             >
4044f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
405936e9439SDimitry Andric        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
406936e9439SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
4077a984708SDavid Chisnall            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
4087a984708SDavid Chisnall                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4097a984708SDavid Chisnall            {}
4107a984708SDavid Chisnall
4117a984708SDavid Chisnall    template <class _Alloc, class _Tuple,
4127a984708SDavid Chisnall              class = typename enable_if
4137a984708SDavid Chisnall                      <
4147c82a1ecSDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4157a984708SDavid Chisnall                      >::type
4167a984708SDavid Chisnall             >
4177a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
4187a984708SDavid Chisnall        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4197a984708SDavid Chisnall            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4207a984708SDavid Chisnall                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
4217a984708SDavid Chisnall                                       _VSTD::forward<typename tuple_element<_Indx,
4227a984708SDavid Chisnall                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4237a984708SDavid Chisnall            {}
4247a984708SDavid Chisnall
4257a984708SDavid Chisnall    template <class _Tuple>
4267a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
4277a984708SDavid Chisnall        typename enable_if
4287a984708SDavid Chisnall        <
4297a984708SDavid Chisnall            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
4307a984708SDavid Chisnall            __tuple_impl&
4317a984708SDavid Chisnall        >::type
432936e9439SDimitry Andric        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
433936e9439SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
4347a984708SDavid Chisnall        {
4357a984708SDavid Chisnall            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
4367a984708SDavid Chisnall                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
4377a984708SDavid Chisnall            return *this;
4387a984708SDavid Chisnall        }
4397a984708SDavid Chisnall
4404f7ab58eSDimitry Andric    __tuple_impl(const __tuple_impl&) = default;
4414f7ab58eSDimitry Andric    __tuple_impl(__tuple_impl&&) = default;
4424f7ab58eSDimitry Andric
4437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
44494e3ee44SDavid Chisnall    __tuple_impl&
445936e9439SDimitry Andric    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
44694e3ee44SDavid Chisnall    {
44794e3ee44SDavid Chisnall        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
44894e3ee44SDavid Chisnall        return *this;
44994e3ee44SDavid Chisnall    }
45094e3ee44SDavid Chisnall
45194e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4524f7ab58eSDimitry Andric    __tuple_impl&
4534f7ab58eSDimitry Andric    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
4544f7ab58eSDimitry Andric    {
4554f7ab58eSDimitry Andric        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
4564f7ab58eSDimitry Andric        return *this;
4574f7ab58eSDimitry Andric    }
4584f7ab58eSDimitry Andric
4594f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4607a984708SDavid Chisnall    void swap(__tuple_impl& __t)
4617a984708SDavid Chisnall        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4627a984708SDavid Chisnall    {
4637a984708SDavid Chisnall        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4647a984708SDavid Chisnall    }
4657a984708SDavid Chisnall};
4667a984708SDavid Chisnall
4677c82a1ecSDimitry Andric
4687c82a1ecSDimitry Andric
4697a984708SDavid Chisnalltemplate <class ..._Tp>
470aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple
4717a984708SDavid Chisnall{
472f9448bf3SDimitry Andric    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4737a984708SDavid Chisnall
474f9448bf3SDimitry Andric    _BaseT __base_;
4757a984708SDavid Chisnall
476aed8d94eSDimitry Andric#if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION)
477aed8d94eSDimitry Andric    static constexpr bool _EnableImplicitReducedArityExtension = true;
478aed8d94eSDimitry Andric#else
479aed8d94eSDimitry Andric    static constexpr bool _EnableImplicitReducedArityExtension = false;
480aed8d94eSDimitry Andric#endif
481aed8d94eSDimitry Andric
4827c82a1ecSDimitry Andric    template <class ..._Args>
4837c82a1ecSDimitry Andric    struct _PackExpandsToThisTuple : false_type {};
4847c82a1ecSDimitry Andric
4857c82a1ecSDimitry Andric    template <class _Arg>
4867c82a1ecSDimitry Andric    struct _PackExpandsToThisTuple<_Arg>
4877c82a1ecSDimitry Andric        : is_same<typename __uncvref<_Arg>::type, tuple> {};
4887c82a1ecSDimitry Andric
4897c82a1ecSDimitry Andric    template <bool _MaybeEnable, class _Dummy = void>
4907c82a1ecSDimitry Andric    struct _CheckArgsConstructor : __check_tuple_constructor_fail {};
4917c82a1ecSDimitry Andric
4927c82a1ecSDimitry Andric    template <class _Dummy>
4937c82a1ecSDimitry Andric    struct _CheckArgsConstructor<true, _Dummy>
4947c82a1ecSDimitry Andric    {
4957c82a1ecSDimitry Andric        template <class ..._Args>
496aed8d94eSDimitry Andric        static constexpr bool __enable_default() {
497aed8d94eSDimitry Andric            return __all<is_default_constructible<_Args>::value...>::value;
498aed8d94eSDimitry Andric        }
499aed8d94eSDimitry Andric
500aed8d94eSDimitry Andric        template <class ..._Args>
5017c82a1ecSDimitry Andric        static constexpr bool __enable_explicit() {
5027c82a1ecSDimitry Andric            return
5037c82a1ecSDimitry Andric                __tuple_constructible<
5047c82a1ecSDimitry Andric                    tuple<_Args...>,
5057c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple,
5067c82a1ecSDimitry Andric                             sizeof...(_Args) < sizeof...(_Tp) ?
5077c82a1ecSDimitry Andric                                 sizeof...(_Args) :
5087c82a1ecSDimitry Andric                                 sizeof...(_Tp)>::type
5097c82a1ecSDimitry Andric                >::value &&
5107c82a1ecSDimitry Andric                !__tuple_convertible<
5117c82a1ecSDimitry Andric                    tuple<_Args...>,
5127c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple,
5137c82a1ecSDimitry Andric                             sizeof...(_Args) < sizeof...(_Tp) ?
5147c82a1ecSDimitry Andric                                 sizeof...(_Args) :
5157c82a1ecSDimitry Andric                                 sizeof...(_Tp)>::type
5167c82a1ecSDimitry Andric                >::value &&
5177c82a1ecSDimitry Andric                __all_default_constructible<
5187c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp),
5197c82a1ecSDimitry Andric                             sizeof...(_Args) < sizeof...(_Tp) ?
5207c82a1ecSDimitry Andric                                 sizeof...(_Args) :
5217c82a1ecSDimitry Andric                                 sizeof...(_Tp)>::type
5227c82a1ecSDimitry Andric                >::value;
5237c82a1ecSDimitry Andric        }
5247c82a1ecSDimitry Andric
5257c82a1ecSDimitry Andric        template <class ..._Args>
5267c82a1ecSDimitry Andric        static constexpr bool __enable_implicit() {
5277c82a1ecSDimitry Andric            return
5287c82a1ecSDimitry Andric                __tuple_convertible<
5297c82a1ecSDimitry Andric                    tuple<_Args...>,
5307c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple,
5317c82a1ecSDimitry Andric                             sizeof...(_Args) < sizeof...(_Tp) ?
5327c82a1ecSDimitry Andric                                 sizeof...(_Args) :
5337c82a1ecSDimitry Andric                                 sizeof...(_Tp)>::type
5347c82a1ecSDimitry Andric                >::value &&
5357c82a1ecSDimitry Andric                __all_default_constructible<
5367c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp),
5377c82a1ecSDimitry Andric                             sizeof...(_Args) < sizeof...(_Tp) ?
5387c82a1ecSDimitry Andric                                 sizeof...(_Args) :
5397c82a1ecSDimitry Andric                                 sizeof...(_Tp)>::type
5407c82a1ecSDimitry Andric                >::value;
5417c82a1ecSDimitry Andric        }
5427c82a1ecSDimitry Andric    };
5437c82a1ecSDimitry Andric
5447c82a1ecSDimitry Andric    template <bool _MaybeEnable,
5457c82a1ecSDimitry Andric              bool = sizeof...(_Tp) == 1,
5467c82a1ecSDimitry Andric              class _Dummy = void>
5477c82a1ecSDimitry Andric    struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {};
5487c82a1ecSDimitry Andric
5497c82a1ecSDimitry Andric    template <class _Dummy>
5507c82a1ecSDimitry Andric    struct _CheckTupleLikeConstructor<true, false, _Dummy>
5517c82a1ecSDimitry Andric    {
5527c82a1ecSDimitry Andric        template <class _Tuple>
5537c82a1ecSDimitry Andric        static constexpr bool __enable_implicit() {
5547c82a1ecSDimitry Andric            return __tuple_convertible<_Tuple, tuple>::value;
5557c82a1ecSDimitry Andric        }
5567c82a1ecSDimitry Andric
5577c82a1ecSDimitry Andric        template <class _Tuple>
5587c82a1ecSDimitry Andric        static constexpr bool __enable_explicit() {
5597c82a1ecSDimitry Andric            return __tuple_constructible<_Tuple, tuple>::value
5607c82a1ecSDimitry Andric               && !__tuple_convertible<_Tuple, tuple>::value;
5617c82a1ecSDimitry Andric        }
5627c82a1ecSDimitry Andric    };
5637c82a1ecSDimitry Andric
5647c82a1ecSDimitry Andric    template <class _Dummy>
5657c82a1ecSDimitry Andric    struct _CheckTupleLikeConstructor<true, true, _Dummy>
5667c82a1ecSDimitry Andric    {
5677c82a1ecSDimitry Andric        // This trait is used to disable the tuple-like constructor when
5687c82a1ecSDimitry Andric        // the UTypes... constructor should be selected instead.
5697c82a1ecSDimitry Andric        // See LWG issue #2549.
5707c82a1ecSDimitry Andric        template <class _Tuple>
5717c82a1ecSDimitry Andric        using _PreferTupleLikeConstructor = __lazy_or<
5727c82a1ecSDimitry Andric            // Don't attempt the two checks below if the tuple we are given
5737c82a1ecSDimitry Andric            // has the same type as this tuple.
5747c82a1ecSDimitry Andric            is_same<typename __uncvref<_Tuple>::type, tuple>,
5757c82a1ecSDimitry Andric            __lazy_and<
5767c82a1ecSDimitry Andric                __lazy_not<is_constructible<_Tp..., _Tuple>>,
5777c82a1ecSDimitry Andric                __lazy_not<is_convertible<_Tuple, _Tp...>>
5787c82a1ecSDimitry Andric            >
5797c82a1ecSDimitry Andric        >;
5807c82a1ecSDimitry Andric
5817c82a1ecSDimitry Andric        template <class _Tuple>
5827c82a1ecSDimitry Andric        static constexpr bool __enable_implicit() {
5837c82a1ecSDimitry Andric            return __lazy_and<
5847c82a1ecSDimitry Andric                __tuple_convertible<_Tuple, tuple>,
5857c82a1ecSDimitry Andric                _PreferTupleLikeConstructor<_Tuple>
5867c82a1ecSDimitry Andric            >::value;
5877c82a1ecSDimitry Andric        }
5887c82a1ecSDimitry Andric
5897c82a1ecSDimitry Andric        template <class _Tuple>
5907c82a1ecSDimitry Andric        static constexpr bool __enable_explicit() {
5917c82a1ecSDimitry Andric            return __lazy_and<
5927c82a1ecSDimitry Andric                __tuple_constructible<_Tuple, tuple>,
5937c82a1ecSDimitry Andric                _PreferTupleLikeConstructor<_Tuple>,
5947c82a1ecSDimitry Andric                __lazy_not<__tuple_convertible<_Tuple, tuple>>
5957c82a1ecSDimitry Andric            >::value;
5967c82a1ecSDimitry Andric        }
5977c82a1ecSDimitry Andric    };
5987c82a1ecSDimitry Andric
5994f7ab58eSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
60094e3ee44SDavid Chisnall        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
6014f7ab58eSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
60294e3ee44SDavid Chisnall        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
6034f7ab58eSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
60494e3ee44SDavid Chisnall        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
6059729cf09SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
6069729cf09SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
6077a984708SDavid Chisnallpublic:
6087a984708SDavid Chisnall
609854fa44bSDimitry Andric    template <bool _Dummy = true, class = typename enable_if<
610aed8d94eSDimitry Andric        _CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>()
611d72607e9SDimitry Andric    >::type>
6127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
613936e9439SDimitry Andric    _LIBCPP_CONSTEXPR tuple()
614936e9439SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
615936e9439SDimitry Andric
616aed8d94eSDimitry Andric    tuple(tuple const&) = default;
617aed8d94eSDimitry Andric    tuple(tuple&&) = default;
618aed8d94eSDimitry Andric
6197c82a1ecSDimitry Andric    template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if<
6207c82a1ecSDimitry Andric        __lazy_and<
6217c82a1ecSDimitry Andric            is_same<allocator_arg_t, _AllocArgT>,
6227c82a1ecSDimitry Andric            __lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...>
6237c82a1ecSDimitry Andric       >::value
6247c82a1ecSDimitry Andric    >::type>
6257c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
6267c82a1ecSDimitry Andric    tuple(_AllocArgT, _Alloc const& __a)
627f9448bf3SDimitry Andric      : __base_(allocator_arg_t(), __a,
6287c82a1ecSDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
6297c82a1ecSDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
6307c82a1ecSDimitry Andric                    __tuple_types<_Tp...>()) {}
6317c82a1ecSDimitry Andric
6327c82a1ecSDimitry Andric    template <bool _Dummy = true,
6337c82a1ecSDimitry Andric              typename enable_if
6347c82a1ecSDimitry Andric                      <
6357c82a1ecSDimitry Andric                         _CheckArgsConstructor<
6367c82a1ecSDimitry Andric                            _Dummy
637b817d7a5SDimitry Andric                         >::template __enable_implicit<_Tp const&...>(),
6387c82a1ecSDimitry Andric                         bool
6397c82a1ecSDimitry Andric                      >::type = false
6407c82a1ecSDimitry Andric        >
6417c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
6427c82a1ecSDimitry Andric    tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
643f9448bf3SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
6447c82a1ecSDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
6457c82a1ecSDimitry Andric                typename __make_tuple_indices<0>::type(),
6467c82a1ecSDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
6477c82a1ecSDimitry Andric                __t...
6487c82a1ecSDimitry Andric               ) {}
6497c82a1ecSDimitry Andric
6507c82a1ecSDimitry Andric    template <bool _Dummy = true,
6517c82a1ecSDimitry Andric              typename enable_if
6527c82a1ecSDimitry Andric                      <
6537c82a1ecSDimitry Andric                         _CheckArgsConstructor<
6547c82a1ecSDimitry Andric                            _Dummy
655b817d7a5SDimitry Andric                         >::template __enable_explicit<_Tp const&...>(),
6567c82a1ecSDimitry Andric                         bool
6577c82a1ecSDimitry Andric                      >::type = false
6587c82a1ecSDimitry Andric        >
6594f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
660936e9439SDimitry Andric    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
661f9448bf3SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
6627a984708SDavid Chisnall                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
6637a984708SDavid Chisnall                typename __make_tuple_indices<0>::type(),
6647a984708SDavid Chisnall                typename __make_tuple_types<tuple, 0>::type(),
6657a984708SDavid Chisnall                __t...
6667a984708SDavid Chisnall               ) {}
6677a984708SDavid Chisnall
6687c82a1ecSDimitry Andric    template <class _Alloc, bool _Dummy = true,
6697c82a1ecSDimitry Andric              typename enable_if
6707c82a1ecSDimitry Andric                      <
6717c82a1ecSDimitry Andric                         _CheckArgsConstructor<
6727c82a1ecSDimitry Andric                            _Dummy
673b817d7a5SDimitry Andric                         >::template __enable_implicit<_Tp const&...>(),
6747c82a1ecSDimitry Andric                         bool
6757c82a1ecSDimitry Andric                      >::type = false
6767c82a1ecSDimitry Andric        >
6777a984708SDavid Chisnall      _LIBCPP_INLINE_VISIBILITY
6787a984708SDavid Chisnall      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
679f9448bf3SDimitry Andric        : __base_(allocator_arg_t(), __a,
6807a984708SDavid Chisnall                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
6817a984708SDavid Chisnall                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
6827a984708SDavid Chisnall                typename __make_tuple_indices<0>::type(),
6837a984708SDavid Chisnall                typename __make_tuple_types<tuple, 0>::type(),
6847a984708SDavid Chisnall                __t...
6857a984708SDavid Chisnall               ) {}
6867a984708SDavid Chisnall
6877c82a1ecSDimitry Andric    template <class _Alloc, bool _Dummy = true,
6887c82a1ecSDimitry Andric              typename enable_if
6897c82a1ecSDimitry Andric                      <
6907c82a1ecSDimitry Andric                         _CheckArgsConstructor<
6917c82a1ecSDimitry Andric                            _Dummy
692b817d7a5SDimitry Andric                         >::template __enable_explicit<_Tp const&...>(),
6937c82a1ecSDimitry Andric                         bool
6947c82a1ecSDimitry Andric                      >::type = false
6957c82a1ecSDimitry Andric        >
6967c82a1ecSDimitry Andric      _LIBCPP_INLINE_VISIBILITY
6977c82a1ecSDimitry Andric      explicit
6987c82a1ecSDimitry Andric      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
699f9448bf3SDimitry Andric        : __base_(allocator_arg_t(), __a,
7007c82a1ecSDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
7017c82a1ecSDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
7027c82a1ecSDimitry Andric                typename __make_tuple_indices<0>::type(),
7037c82a1ecSDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
7047c82a1ecSDimitry Andric                __t...
7057c82a1ecSDimitry Andric               ) {}
7067c82a1ecSDimitry Andric
7077a984708SDavid Chisnall    template <class ..._Up,
708aed8d94eSDimitry Andric              bool _PackIsTuple = _PackExpandsToThisTuple<_Up...>::value,
709b03f91a8SDavid Chisnall              typename enable_if
7107a984708SDavid Chisnall                      <
7117c82a1ecSDimitry Andric                         _CheckArgsConstructor<
712aed8d94eSDimitry Andric                             sizeof...(_Up) == sizeof...(_Tp)
713aed8d94eSDimitry Andric                             && !_PackIsTuple
714aed8d94eSDimitry Andric                         >::template __enable_implicit<_Up...>() ||
715aed8d94eSDimitry Andric                        _CheckArgsConstructor<
716aed8d94eSDimitry Andric                            _EnableImplicitReducedArityExtension
717aed8d94eSDimitry Andric                            && sizeof...(_Up) < sizeof...(_Tp)
718aed8d94eSDimitry Andric                            && !_PackIsTuple
7197c82a1ecSDimitry Andric                         >::template __enable_implicit<_Up...>(),
720b03f91a8SDavid Chisnall                         bool
721b03f91a8SDavid Chisnall                      >::type = false
722b03f91a8SDavid Chisnall             >
7234f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
724b03f91a8SDavid Chisnall        tuple(_Up&&... __u)
725936e9439SDimitry Andric            _NOEXCEPT_((
726f9448bf3SDimitry Andric                is_nothrow_constructible<_BaseT,
727936e9439SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type,
728936e9439SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
729936e9439SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
730936e9439SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
731936e9439SDimitry Andric                    _Up...
732936e9439SDimitry Andric                >::value
733936e9439SDimitry Andric            ))
734f9448bf3SDimitry Andric            : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
735b03f91a8SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
736b03f91a8SDavid Chisnall                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
737b03f91a8SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
738b03f91a8SDavid Chisnall                    _VSTD::forward<_Up>(__u)...) {}
739b03f91a8SDavid Chisnall
740b03f91a8SDavid Chisnall    template <class ..._Up,
741b03f91a8SDavid Chisnall              typename enable_if
742b03f91a8SDavid Chisnall                      <
7437c82a1ecSDimitry Andric                         _CheckArgsConstructor<
7447c82a1ecSDimitry Andric                             sizeof...(_Up) <= sizeof...(_Tp)
7457c82a1ecSDimitry Andric                             && !_PackExpandsToThisTuple<_Up...>::value
746aed8d94eSDimitry Andric                         >::template __enable_explicit<_Up...>() ||
747aed8d94eSDimitry Andric                         _CheckArgsConstructor<
748aed8d94eSDimitry Andric                            !_EnableImplicitReducedArityExtension
749aed8d94eSDimitry Andric                            && sizeof...(_Up) < sizeof...(_Tp)
750540d2a8bSDimitry Andric                            && !_PackExpandsToThisTuple<_Up...>::value
751aed8d94eSDimitry Andric                         >::template __enable_implicit<_Up...>(),
752b03f91a8SDavid Chisnall                         bool
753b03f91a8SDavid Chisnall                      >::type = false
7547a984708SDavid Chisnall             >
7554f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
7567a984708SDavid Chisnall        explicit
7577a984708SDavid Chisnall        tuple(_Up&&... __u)
758936e9439SDimitry Andric            _NOEXCEPT_((
759f9448bf3SDimitry Andric                is_nothrow_constructible<_BaseT,
760936e9439SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type,
761936e9439SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
762936e9439SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
763936e9439SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
764936e9439SDimitry Andric                    _Up...
765936e9439SDimitry Andric                >::value
766936e9439SDimitry Andric            ))
767f9448bf3SDimitry Andric            : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
7687a984708SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
7697a984708SDavid Chisnall                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
7707a984708SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
7717a984708SDavid Chisnall                    _VSTD::forward<_Up>(__u)...) {}
7727a984708SDavid Chisnall
7737a984708SDavid Chisnall    template <class _Alloc, class ..._Up,
7747c82a1ecSDimitry Andric              typename enable_if
7757a984708SDavid Chisnall                      <
7767c82a1ecSDimitry Andric                         _CheckArgsConstructor<
7777c82a1ecSDimitry Andric                             sizeof...(_Up) == sizeof...(_Tp) &&
7787c82a1ecSDimitry Andric                             !_PackExpandsToThisTuple<_Up...>::value
7797c82a1ecSDimitry Andric                         >::template __enable_implicit<_Up...>(),
7807c82a1ecSDimitry Andric                         bool
7817c82a1ecSDimitry Andric                      >::type = false
7827a984708SDavid Chisnall             >
7837a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
7847a984708SDavid Chisnall        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
785f9448bf3SDimitry Andric            : __base_(allocator_arg_t(), __a,
7867a984708SDavid Chisnall                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
7877a984708SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
7887a984708SDavid Chisnall                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
7897a984708SDavid Chisnall                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
7907a984708SDavid Chisnall                    _VSTD::forward<_Up>(__u)...) {}
7917a984708SDavid Chisnall
7927c82a1ecSDimitry Andric    template <class _Alloc, class ..._Up,
7937c82a1ecSDimitry Andric              typename enable_if
7947c82a1ecSDimitry Andric                      <
7957c82a1ecSDimitry Andric                         _CheckArgsConstructor<
7967c82a1ecSDimitry Andric                             sizeof...(_Up) == sizeof...(_Tp) &&
7977c82a1ecSDimitry Andric                             !_PackExpandsToThisTuple<_Up...>::value
7987c82a1ecSDimitry Andric                         >::template __enable_explicit<_Up...>(),
7997c82a1ecSDimitry Andric                         bool
8007c82a1ecSDimitry Andric                      >::type = false
8017c82a1ecSDimitry Andric             >
8027c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
8037c82a1ecSDimitry Andric        explicit
8047c82a1ecSDimitry Andric        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
805f9448bf3SDimitry Andric            : __base_(allocator_arg_t(), __a,
8067c82a1ecSDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
8077c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
8087c82a1ecSDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
8097c82a1ecSDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
8107c82a1ecSDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
8117c82a1ecSDimitry Andric
8127a984708SDavid Chisnall    template <class _Tuple,
813b03f91a8SDavid Chisnall              typename enable_if
8147a984708SDavid Chisnall                      <
8157c82a1ecSDimitry Andric                         _CheckTupleLikeConstructor<
8167c82a1ecSDimitry Andric                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
8177c82a1ecSDimitry Andric                             && !_PackExpandsToThisTuple<_Tuple>::value
8187c82a1ecSDimitry Andric                         >::template __enable_implicit<_Tuple>(),
819b03f91a8SDavid Chisnall                         bool
820b03f91a8SDavid Chisnall                      >::type = false
8217a984708SDavid Chisnall             >
8224f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
823f9448bf3SDimitry Andric        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
824f9448bf3SDimitry Andric            : __base_(_VSTD::forward<_Tuple>(__t)) {}
8257a984708SDavid Chisnall
826b03f91a8SDavid Chisnall    template <class _Tuple,
827b03f91a8SDavid Chisnall              typename enable_if
828b03f91a8SDavid Chisnall                      <
8297c82a1ecSDimitry Andric                         _CheckTupleLikeConstructor<
8307c82a1ecSDimitry Andric                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
8317c82a1ecSDimitry Andric                             && !_PackExpandsToThisTuple<_Tuple>::value
8327c82a1ecSDimitry Andric                         >::template __enable_explicit<_Tuple>(),
833b03f91a8SDavid Chisnall                         bool
834b03f91a8SDavid Chisnall                      >::type = false
835b03f91a8SDavid Chisnall             >
8364f7ab58eSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
837b03f91a8SDavid Chisnall        explicit
838f9448bf3SDimitry Andric        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
839f9448bf3SDimitry Andric            : __base_(_VSTD::forward<_Tuple>(__t)) {}
840b03f91a8SDavid Chisnall
8417a984708SDavid Chisnall    template <class _Alloc, class _Tuple,
8427c82a1ecSDimitry Andric              typename enable_if
8437a984708SDavid Chisnall                      <
8447c82a1ecSDimitry Andric                         _CheckTupleLikeConstructor<
8457c82a1ecSDimitry Andric                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
8467c82a1ecSDimitry Andric                         >::template __enable_implicit<_Tuple>(),
8477c82a1ecSDimitry Andric                         bool
8487c82a1ecSDimitry Andric                      >::type = false
8497a984708SDavid Chisnall             >
8507a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
8517a984708SDavid Chisnall        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
852f9448bf3SDimitry Andric            : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
8537a984708SDavid Chisnall
8547c82a1ecSDimitry Andric    template <class _Alloc, class _Tuple,
8557c82a1ecSDimitry Andric              typename enable_if
8567c82a1ecSDimitry Andric                      <
8577c82a1ecSDimitry Andric                         _CheckTupleLikeConstructor<
8587c82a1ecSDimitry Andric                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
8597c82a1ecSDimitry Andric                         >::template __enable_explicit<_Tuple>(),
8607c82a1ecSDimitry Andric                         bool
8617c82a1ecSDimitry Andric                      >::type = false
8627c82a1ecSDimitry Andric             >
8637c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
8647c82a1ecSDimitry Andric        explicit
8657c82a1ecSDimitry Andric        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
866f9448bf3SDimitry Andric            : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
8677c82a1ecSDimitry Andric
868aed8d94eSDimitry Andric    using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>;
869aed8d94eSDimitry Andric    using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>;
870aed8d94eSDimitry Andric
871aed8d94eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
872aed8d94eSDimitry Andric    tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t)
873aed8d94eSDimitry Andric        _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
874aed8d94eSDimitry Andric    {
875f9448bf3SDimitry Andric        __base_.operator=(__t.__base_);
876aed8d94eSDimitry Andric        return *this;
877aed8d94eSDimitry Andric    }
878aed8d94eSDimitry Andric
879aed8d94eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
880aed8d94eSDimitry Andric    tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t)
881aed8d94eSDimitry Andric        _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
882aed8d94eSDimitry Andric    {
883f9448bf3SDimitry Andric        __base_.operator=(static_cast<_BaseT&&>(__t.__base_));
884aed8d94eSDimitry Andric        return *this;
885aed8d94eSDimitry Andric    }
886aed8d94eSDimitry Andric
8877a984708SDavid Chisnall    template <class _Tuple,
8887a984708SDavid Chisnall              class = typename enable_if
8897a984708SDavid Chisnall                      <
8907a984708SDavid Chisnall                         __tuple_assignable<_Tuple, tuple>::value
8917a984708SDavid Chisnall                      >::type
8927a984708SDavid Chisnall             >
8937a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
8947a984708SDavid Chisnall        tuple&
895f9448bf3SDimitry Andric        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<_BaseT&, _Tuple>::value))
8967a984708SDavid Chisnall        {
897f9448bf3SDimitry Andric            __base_.operator=(_VSTD::forward<_Tuple>(__t));
8987a984708SDavid Chisnall            return *this;
8997a984708SDavid Chisnall        }
9007a984708SDavid Chisnall
9017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9027a984708SDavid Chisnall    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
903f9448bf3SDimitry Andric        {__base_.swap(__t.__base_);}
9047a984708SDavid Chisnall};
9057a984708SDavid Chisnall
9067a984708SDavid Chisnalltemplate <>
907aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<>
9087a984708SDavid Chisnall{
9097a984708SDavid Chisnallpublic:
9107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
911936e9439SDimitry Andric    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
9127a984708SDavid Chisnall    template <class _Alloc>
9137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
914936e9439SDimitry Andric        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
9157a984708SDavid Chisnall    template <class _Alloc>
9167a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
917936e9439SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
91894e3ee44SDavid Chisnall    template <class _Up>
9197a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
920936e9439SDimitry Andric        tuple(array<_Up, 0>) _NOEXCEPT {}
92194e3ee44SDavid Chisnall    template <class _Alloc, class _Up>
9227a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
923936e9439SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
9247a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9257a984708SDavid Chisnall    void swap(tuple&) _NOEXCEPT {}
9267a984708SDavid Chisnall};
9277a984708SDavid Chisnall
928b2c7081bSDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
929db17bf38SDimitry Andric// NOTE: These are not yet standardized, but are required to simulate the
930db17bf38SDimitry Andric// implicit deduction guide that should be generated had libc++ declared the
931db17bf38SDimitry Andric// tuple-like constructors "correctly"
932db17bf38SDimitry Andrictemplate <class _Alloc, class ..._Args>
933db17bf38SDimitry Andrictuple(allocator_arg_t, const _Alloc&, tuple<_Args...> const&) -> tuple<_Args...>;
934db17bf38SDimitry Andrictemplate <class _Alloc, class ..._Args>
935db17bf38SDimitry Andrictuple(allocator_arg_t, const _Alloc&, tuple<_Args...>&&) -> tuple<_Args...>;
936db17bf38SDimitry Andric#endif
937db17bf38SDimitry Andric
9387a984708SDavid Chisnalltemplate <class ..._Tp>
9397a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
9407a984708SDavid Chisnalltypename enable_if
9417a984708SDavid Chisnall<
9427a984708SDavid Chisnall    __all<__is_swappable<_Tp>::value...>::value,
9437a984708SDavid Chisnall    void
9447a984708SDavid Chisnall>::type
9457a984708SDavid Chisnallswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
9467a984708SDavid Chisnall                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
9477a984708SDavid Chisnall    {__t.swap(__u);}
9487a984708SDavid Chisnall
9497a984708SDavid Chisnall// get
9507a984708SDavid Chisnall
9517a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp>
9524f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
9537a984708SDavid Chisnalltypename tuple_element<_Ip, tuple<_Tp...> >::type&
95494e3ee44SDavid Chisnallget(tuple<_Tp...>& __t) _NOEXCEPT
9557a984708SDavid Chisnall{
9567a984708SDavid Chisnall    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
957f9448bf3SDimitry Andric    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
9587a984708SDavid Chisnall}
9597a984708SDavid Chisnall
9607a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp>
9614f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
9627a984708SDavid Chisnallconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
96394e3ee44SDavid Chisnallget(const tuple<_Tp...>& __t) _NOEXCEPT
9647a984708SDavid Chisnall{
9657a984708SDavid Chisnall    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
966f9448bf3SDimitry Andric    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
9677a984708SDavid Chisnall}
9687a984708SDavid Chisnall
9697a984708SDavid Chisnalltemplate <size_t _Ip, class ..._Tp>
9704f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
9717a984708SDavid Chisnalltypename tuple_element<_Ip, tuple<_Tp...> >::type&&
97294e3ee44SDavid Chisnallget(tuple<_Tp...>&& __t) _NOEXCEPT
9737a984708SDavid Chisnall{
9747a984708SDavid Chisnall    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
9757a984708SDavid Chisnall    return static_cast<type&&>(
976f9448bf3SDimitry Andric             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
9777a984708SDavid Chisnall}
9787a984708SDavid Chisnall
9799729cf09SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
9809729cf09SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
9819729cf09SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
9829729cf09SDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT
9839729cf09SDimitry Andric{
9849729cf09SDimitry Andric    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
9859729cf09SDimitry Andric    return static_cast<const type&&>(
986f9448bf3SDimitry Andric             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
9879729cf09SDimitry Andric}
9889729cf09SDimitry Andric
9894f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9904f7ab58eSDimitry Andric
9917c82a1ecSDimitry Andricnamespace __find_detail {
9927c82a1ecSDimitry Andric
9937c82a1ecSDimitry Andricstatic constexpr size_t __not_found = -1;
9947c82a1ecSDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1;
9957c82a1ecSDimitry Andric
9967c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9977c82a1ecSDimitry Andricconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
9987c82a1ecSDimitry Andric    return !__matches ? __res :
9997c82a1ecSDimitry Andric        (__res == __not_found ? __curr_i : __ambiguous);
10007c82a1ecSDimitry Andric}
10017c82a1ecSDimitry Andric
10027c82a1ecSDimitry Andrictemplate <size_t _Nx>
10037c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10047c82a1ecSDimitry Andricconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
10057c82a1ecSDimitry Andric  return __i == _Nx ? __not_found :
10067c82a1ecSDimitry Andric      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
10077c82a1ecSDimitry Andric}
10087c82a1ecSDimitry Andric
10097c82a1ecSDimitry Andrictemplate <class _T1, class ..._Args>
10107c82a1ecSDimitry Andricstruct __find_exactly_one_checked {
1011b2c7081bSDimitry Andric    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
10127c82a1ecSDimitry Andric    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
10137c82a1ecSDimitry Andric    static_assert(value != __not_found, "type not found in type list" );
10147c82a1ecSDimitry Andric    static_assert(value != __ambiguous, "type occurs more than once in type list");
10154f7ab58eSDimitry Andric};
10164f7ab58eSDimitry Andric
10177c82a1ecSDimitry Andrictemplate <class _T1>
10187c82a1ecSDimitry Andricstruct __find_exactly_one_checked<_T1> {
10197c82a1ecSDimitry Andric    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
10204f7ab58eSDimitry Andric};
10214f7ab58eSDimitry Andric
10227c82a1ecSDimitry Andric} // namespace __find_detail;
10234f7ab58eSDimitry Andric
10244f7ab58eSDimitry Andrictemplate <typename _T1, typename... _Args>
10257c82a1ecSDimitry Andricstruct __find_exactly_one_t
10267c82a1ecSDimitry Andric    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
10274f7ab58eSDimitry Andric};
10284f7ab58eSDimitry Andric
10294f7ab58eSDimitry Andrictemplate <class _T1, class... _Args>
10304f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10314f7ab58eSDimitry Andricconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
10324f7ab58eSDimitry Andric{
10334f7ab58eSDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
10344f7ab58eSDimitry Andric}
10354f7ab58eSDimitry Andric
10364f7ab58eSDimitry Andrictemplate <class _T1, class... _Args>
10374f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10384f7ab58eSDimitry Andricconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
10394f7ab58eSDimitry Andric{
10404f7ab58eSDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
10414f7ab58eSDimitry Andric}
10424f7ab58eSDimitry Andric
10434f7ab58eSDimitry Andrictemplate <class _T1, class... _Args>
10444f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10454f7ab58eSDimitry Andricconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
10464f7ab58eSDimitry Andric{
10474f7ab58eSDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
10484f7ab58eSDimitry Andric}
10494f7ab58eSDimitry Andric
10509729cf09SDimitry Andrictemplate <class _T1, class... _Args>
10519729cf09SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10529729cf09SDimitry Andricconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
10539729cf09SDimitry Andric{
10549729cf09SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
10559729cf09SDimitry Andric}
10569729cf09SDimitry Andric
10574f7ab58eSDimitry Andric#endif
10584f7ab58eSDimitry Andric
10597a984708SDavid Chisnall// tie
10607a984708SDavid Chisnall
10617a984708SDavid Chisnalltemplate <class ..._Tp>
1062d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
10637a984708SDavid Chisnalltuple<_Tp&...>
1064936e9439SDimitry Andrictie(_Tp&... __t) _NOEXCEPT
10657a984708SDavid Chisnall{
10667a984708SDavid Chisnall    return tuple<_Tp&...>(__t...);
10677a984708SDavid Chisnall}
10687a984708SDavid Chisnall
10697a984708SDavid Chisnalltemplate <class _Up>
10707a984708SDavid Chisnallstruct __ignore_t
10717a984708SDavid Chisnall{
10727a984708SDavid Chisnall    template <class _Tp>
1073540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
10747a984708SDavid Chisnall    const __ignore_t& operator=(_Tp&&) const {return *this;}
10757a984708SDavid Chisnall};
10767a984708SDavid Chisnall
1077540d2a8bSDimitry Andricnamespace {
107830785c0eSDimitry Andric  _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1079540d2a8bSDimitry Andric}
10807a984708SDavid Chisnall
10817a984708SDavid Chisnalltemplate <class... _Tp>
10824f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1083*b5893f02SDimitry Andrictuple<typename __unwrap_ref_decay<_Tp>::type...>
10847a984708SDavid Chisnallmake_tuple(_Tp&&... __t)
10857a984708SDavid Chisnall{
1086*b5893f02SDimitry Andric    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
10877a984708SDavid Chisnall}
10887a984708SDavid Chisnall
10897a984708SDavid Chisnalltemplate <class... _Tp>
10904f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
10917a984708SDavid Chisnalltuple<_Tp&&...>
1092936e9439SDimitry Andricforward_as_tuple(_Tp&&... __t) _NOEXCEPT
10937a984708SDavid Chisnall{
10947a984708SDavid Chisnall    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
10957a984708SDavid Chisnall}
10967a984708SDavid Chisnall
109794e3ee44SDavid Chisnalltemplate <size_t _Ip>
10987a984708SDavid Chisnallstruct __tuple_equal
10997a984708SDavid Chisnall{
11007a984708SDavid Chisnall    template <class _Tp, class _Up>
11014f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11027a984708SDavid Chisnall    bool operator()(const _Tp& __x, const _Up& __y)
11037a984708SDavid Chisnall    {
1104d72607e9SDimitry Andric        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
11057a984708SDavid Chisnall    }
11067a984708SDavid Chisnall};
11077a984708SDavid Chisnall
11087a984708SDavid Chisnalltemplate <>
11097a984708SDavid Chisnallstruct __tuple_equal<0>
11107a984708SDavid Chisnall{
11117a984708SDavid Chisnall    template <class _Tp, class _Up>
11124f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11137a984708SDavid Chisnall    bool operator()(const _Tp&, const _Up&)
11147a984708SDavid Chisnall    {
11157a984708SDavid Chisnall        return true;
11167a984708SDavid Chisnall    }
11177a984708SDavid Chisnall};
11187a984708SDavid Chisnall
11197a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11204f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11217a984708SDavid Chisnallbool
11227a984708SDavid Chisnalloperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11237a984708SDavid Chisnall{
11247a984708SDavid Chisnall    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
11257a984708SDavid Chisnall}
11267a984708SDavid Chisnall
11277a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11284f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11297a984708SDavid Chisnallbool
11307a984708SDavid Chisnalloperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11317a984708SDavid Chisnall{
11327a984708SDavid Chisnall    return !(__x == __y);
11337a984708SDavid Chisnall}
11347a984708SDavid Chisnall
113594e3ee44SDavid Chisnalltemplate <size_t _Ip>
11367a984708SDavid Chisnallstruct __tuple_less
11377a984708SDavid Chisnall{
11387a984708SDavid Chisnall    template <class _Tp, class _Up>
11394f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11407a984708SDavid Chisnall    bool operator()(const _Tp& __x, const _Up& __y)
11417a984708SDavid Chisnall    {
1142854fa44bSDimitry Andric        const size_t __idx = tuple_size<_Tp>::value - _Ip;
1143854fa44bSDimitry Andric        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
1144854fa44bSDimitry Andric            return true;
1145854fa44bSDimitry Andric        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
1146854fa44bSDimitry Andric            return false;
1147854fa44bSDimitry Andric        return __tuple_less<_Ip-1>()(__x, __y);
11487a984708SDavid Chisnall    }
11497a984708SDavid Chisnall};
11507a984708SDavid Chisnall
11517a984708SDavid Chisnalltemplate <>
11527a984708SDavid Chisnallstruct __tuple_less<0>
11537a984708SDavid Chisnall{
11547a984708SDavid Chisnall    template <class _Tp, class _Up>
11554f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11567a984708SDavid Chisnall    bool operator()(const _Tp&, const _Up&)
11577a984708SDavid Chisnall    {
11587a984708SDavid Chisnall        return false;
11597a984708SDavid Chisnall    }
11607a984708SDavid Chisnall};
11617a984708SDavid Chisnall
11627a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11634f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11647a984708SDavid Chisnallbool
11657a984708SDavid Chisnalloperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11667a984708SDavid Chisnall{
11677a984708SDavid Chisnall    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
11687a984708SDavid Chisnall}
11697a984708SDavid Chisnall
11707a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11714f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11727a984708SDavid Chisnallbool
11737a984708SDavid Chisnalloperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11747a984708SDavid Chisnall{
11757a984708SDavid Chisnall    return __y < __x;
11767a984708SDavid Chisnall}
11777a984708SDavid Chisnall
11787a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11794f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11807a984708SDavid Chisnallbool
11817a984708SDavid Chisnalloperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11827a984708SDavid Chisnall{
11837a984708SDavid Chisnall    return !(__x < __y);
11847a984708SDavid Chisnall}
11857a984708SDavid Chisnall
11867a984708SDavid Chisnalltemplate <class ..._Tp, class ..._Up>
11874f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11887a984708SDavid Chisnallbool
11897a984708SDavid Chisnalloperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
11907a984708SDavid Chisnall{
11917a984708SDavid Chisnall    return !(__y < __x);
11927a984708SDavid Chisnall}
11937a984708SDavid Chisnall
11947a984708SDavid Chisnall// tuple_cat
11957a984708SDavid Chisnall
11967a984708SDavid Chisnalltemplate <class _Tp, class _Up> struct __tuple_cat_type;
11977a984708SDavid Chisnall
11987a984708SDavid Chisnalltemplate <class ..._Ttypes, class ..._Utypes>
11997a984708SDavid Chisnallstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
12007a984708SDavid Chisnall{
12017a984708SDavid Chisnall    typedef tuple<_Ttypes..., _Utypes...> type;
12027a984708SDavid Chisnall};
12037a984708SDavid Chisnall
12047a984708SDavid Chisnalltemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
12057a984708SDavid Chisnallstruct __tuple_cat_return_1
12067a984708SDavid Chisnall{
12077a984708SDavid Chisnall};
12087a984708SDavid Chisnall
12097a984708SDavid Chisnalltemplate <class ..._Types, class _Tuple0>
12107a984708SDavid Chisnallstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
12117a984708SDavid Chisnall{
12127a984708SDavid Chisnall    typedef typename __tuple_cat_type<tuple<_Types...>,
12137a984708SDavid Chisnall            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
12147a984708SDavid Chisnall                                                                           type;
12157a984708SDavid Chisnall};
12167a984708SDavid Chisnall
12177a984708SDavid Chisnalltemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
12187a984708SDavid Chisnallstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
12197a984708SDavid Chisnall    : public __tuple_cat_return_1<
12207a984708SDavid Chisnall                 typename __tuple_cat_type<
12217a984708SDavid Chisnall                     tuple<_Types...>,
12227a984708SDavid Chisnall                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
12237a984708SDavid Chisnall                 >::type,
12247a984708SDavid Chisnall                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
12257a984708SDavid Chisnall                 _Tuple1, _Tuples...>
12267a984708SDavid Chisnall{
12277a984708SDavid Chisnall};
12287a984708SDavid Chisnall
12297a984708SDavid Chisnalltemplate <class ..._Tuples> struct __tuple_cat_return;
12307a984708SDavid Chisnall
12317a984708SDavid Chisnalltemplate <class _Tuple0, class ..._Tuples>
12327a984708SDavid Chisnallstruct __tuple_cat_return<_Tuple0, _Tuples...>
12337a984708SDavid Chisnall    : public __tuple_cat_return_1<tuple<>,
12347a984708SDavid Chisnall         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
12357a984708SDavid Chisnall                                                                     _Tuples...>
12367a984708SDavid Chisnall{
12377a984708SDavid Chisnall};
12387a984708SDavid Chisnall
12397a984708SDavid Chisnalltemplate <>
12407a984708SDavid Chisnallstruct __tuple_cat_return<>
12417a984708SDavid Chisnall{
12427a984708SDavid Chisnall    typedef tuple<> type;
12437a984708SDavid Chisnall};
12447a984708SDavid Chisnall
12454f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12467a984708SDavid Chisnalltuple<>
12477a984708SDavid Chisnalltuple_cat()
12487a984708SDavid Chisnall{
12497a984708SDavid Chisnall    return tuple<>();
12507a984708SDavid Chisnall}
12517a984708SDavid Chisnall
125294e3ee44SDavid Chisnalltemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
12537a984708SDavid Chisnallstruct __tuple_cat_return_ref_imp;
12547a984708SDavid Chisnall
12557a984708SDavid Chisnalltemplate <class ..._Types, size_t ..._I0, class _Tuple0>
12567a984708SDavid Chisnallstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
12577a984708SDavid Chisnall{
12587a984708SDavid Chisnall    typedef typename remove_reference<_Tuple0>::type _T0;
12597a984708SDavid Chisnall    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
12607a984708SDavid Chisnall                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
12617a984708SDavid Chisnall};
12627a984708SDavid Chisnall
12637a984708SDavid Chisnalltemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
12647a984708SDavid Chisnallstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
12657a984708SDavid Chisnall                                  _Tuple0, _Tuple1, _Tuples...>
12667a984708SDavid Chisnall    : public __tuple_cat_return_ref_imp<
12677a984708SDavid Chisnall         tuple<_Types..., typename __apply_cv<_Tuple0,
12687a984708SDavid Chisnall               typename tuple_element<_I0,
12697a984708SDavid Chisnall                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
12707a984708SDavid Chisnall         typename __make_tuple_indices<tuple_size<typename
12717a984708SDavid Chisnall                                 remove_reference<_Tuple1>::type>::value>::type,
12727a984708SDavid Chisnall         _Tuple1, _Tuples...>
12737a984708SDavid Chisnall{
12747a984708SDavid Chisnall};
12757a984708SDavid Chisnall
12767a984708SDavid Chisnalltemplate <class _Tuple0, class ..._Tuples>
12777a984708SDavid Chisnallstruct __tuple_cat_return_ref
12787a984708SDavid Chisnall    : public __tuple_cat_return_ref_imp<tuple<>,
12797a984708SDavid Chisnall               typename __make_tuple_indices<
12807a984708SDavid Chisnall                        tuple_size<typename remove_reference<_Tuple0>::type>::value
12817a984708SDavid Chisnall               >::type, _Tuple0, _Tuples...>
12827a984708SDavid Chisnall{
12837a984708SDavid Chisnall};
12847a984708SDavid Chisnall
12857a984708SDavid Chisnalltemplate <class _Types, class _I0, class _J0>
12867a984708SDavid Chisnallstruct __tuple_cat;
12877a984708SDavid Chisnall
12887a984708SDavid Chisnalltemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
12897a984708SDavid Chisnallstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
12907a984708SDavid Chisnall{
12917a984708SDavid Chisnall    template <class _Tuple0>
12924f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12937a984708SDavid Chisnall    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
12947a984708SDavid Chisnall    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
12957a984708SDavid Chisnall    {
1296d72607e9SDimitry Andric        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1297d72607e9SDimitry Andric                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
12987a984708SDavid Chisnall    }
12997a984708SDavid Chisnall
13007a984708SDavid Chisnall    template <class _Tuple0, class _Tuple1, class ..._Tuples>
13014f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13027a984708SDavid Chisnall    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
13037a984708SDavid Chisnall    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
13047a984708SDavid Chisnall    {
13057a984708SDavid Chisnall        typedef typename remove_reference<_Tuple0>::type _T0;
13067a984708SDavid Chisnall        typedef typename remove_reference<_Tuple1>::type _T1;
13077a984708SDavid Chisnall        return __tuple_cat<
13087a984708SDavid Chisnall           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
13097a984708SDavid Chisnall           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
13107a984708SDavid Chisnall           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
13114f7ab58eSDimitry Andric                           (forward_as_tuple(
1312d72607e9SDimitry Andric                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1313d72607e9SDimitry Andric                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
13147a984708SDavid Chisnall                            ),
13157a984708SDavid Chisnall                            _VSTD::forward<_Tuple1>(__t1),
13167a984708SDavid Chisnall                            _VSTD::forward<_Tuples>(__tpls)...);
13177a984708SDavid Chisnall    }
13187a984708SDavid Chisnall};
13197a984708SDavid Chisnall
13207a984708SDavid Chisnalltemplate <class _Tuple0, class... _Tuples>
13214f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13227a984708SDavid Chisnalltypename __tuple_cat_return<_Tuple0, _Tuples...>::type
13237a984708SDavid Chisnalltuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
13247a984708SDavid Chisnall{
13257a984708SDavid Chisnall    typedef typename remove_reference<_Tuple0>::type _T0;
13267a984708SDavid Chisnall    return __tuple_cat<tuple<>, __tuple_indices<>,
13277a984708SDavid Chisnall                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
13287a984708SDavid Chisnall                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
13297a984708SDavid Chisnall                                            _VSTD::forward<_Tuples>(__tpls)...);
13307a984708SDavid Chisnall}
13317a984708SDavid Chisnall
13327a984708SDavid Chisnalltemplate <class ..._Tp, class _Alloc>
1333aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
13347a984708SDavid Chisnall    : true_type {};
13357a984708SDavid Chisnall
13367a984708SDavid Chisnalltemplate <class _T1, class _T2>
13377a984708SDavid Chisnalltemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
13387a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13397a984708SDavid Chisnallpair<_T1, _T2>::pair(piecewise_construct_t,
13407a984708SDavid Chisnall                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
13417a984708SDavid Chisnall                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1342d72607e9SDimitry Andric    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1343d72607e9SDimitry Andric      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
13447a984708SDavid Chisnall{
13457a984708SDavid Chisnall}
13467a984708SDavid Chisnall
13477c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 14
13487c82a1ecSDimitry Andrictemplate <class _Tp>
134930785c0eSDimitry Andric_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
13507c82a1ecSDimitry Andric
13517c82a1ecSDimitry Andric#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
13527c82a1ecSDimitry Andric
13537c82a1ecSDimitry Andrictemplate <class _Fn, class _Tuple, size_t ..._Id>
13547c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13557c82a1ecSDimitry Andricconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
13567c82a1ecSDimitry Andric                                            __tuple_indices<_Id...>)
13577c82a1ecSDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
13587c82a1ecSDimitry Andric    _VSTD::__invoke_constexpr(
13597c82a1ecSDimitry Andric        _VSTD::forward<_Fn>(__f),
13607c82a1ecSDimitry Andric        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
13617c82a1ecSDimitry Andric)
13627c82a1ecSDimitry Andric
13637c82a1ecSDimitry Andrictemplate <class _Fn, class _Tuple>
13647c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13657c82a1ecSDimitry Andricconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
13667c82a1ecSDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
13677c82a1ecSDimitry Andric    _VSTD::__apply_tuple_impl(
13687c82a1ecSDimitry Andric        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
13694ba319b5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
13707c82a1ecSDimitry Andric)
13717c82a1ecSDimitry Andric
13727c82a1ecSDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx>
13737c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13747c82a1ecSDimitry Andricconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
13757c82a1ecSDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
13767c82a1ecSDimitry Andric    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
13777c82a1ecSDimitry Andric)
13787c82a1ecSDimitry Andric
13797c82a1ecSDimitry Andrictemplate <class _Tp, class _Tuple>
13807c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13817c82a1ecSDimitry Andricconstexpr _Tp make_from_tuple(_Tuple&& __t)
13827c82a1ecSDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
13837c82a1ecSDimitry Andric    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
13844ba319b5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
13857c82a1ecSDimitry Andric)
13867c82a1ecSDimitry Andric
13877c82a1ecSDimitry Andric#undef _LIBCPP_NOEXCEPT_RETURN
13887c82a1ecSDimitry Andric
13897c82a1ecSDimitry Andric#endif // _LIBCPP_STD_VER > 14
13907c82a1ecSDimitry Andric
1391540d2a8bSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
1392540d2a8bSDimitry Andric
13937a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
13947a984708SDavid Chisnall
13957a984708SDavid Chisnall#endif  // _LIBCPP_TUPLE
1396