xref: /llvm-project-15.0.7/libcxx/include/tuple (revision ef89e8ca)
13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===--------------------------- tuple ------------------------------------===//
33e519524SHoward Hinnant//
42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_TUPLE
113e519524SHoward Hinnant#define _LIBCPP_TUPLE
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    tuple synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnanttemplate <class... T>
203e519524SHoward Hinnantclass tuple {
213e519524SHoward Hinnantpublic:
22e16f2cb6SLouis Dionne    explicit(see-below) constexpr tuple();
23e35c5121SLouis Dionne    explicit(see-below) tuple(const T&...);  // constexpr in C++14
243e519524SHoward Hinnant    template <class... U>
25e35c5121SLouis Dionne        explicit(see-below) tuple(U&&...);  // constexpr in C++14
263e519524SHoward Hinnant    tuple(const tuple&) = default;
2727d0a2a7SHoward Hinnant    tuple(tuple&&) = default;
283e519524SHoward Hinnant    template <class... U>
29e35c5121SLouis Dionne        explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
303e519524SHoward Hinnant    template <class... U>
31e35c5121SLouis Dionne        explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
323e519524SHoward Hinnant    template <class U1, class U2>
33e35c5121SLouis Dionne        explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
343e519524SHoward Hinnant    template <class U1, class U2>
35e35c5121SLouis Dionne        explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
363e519524SHoward Hinnant
373e519524SHoward Hinnant    // allocator-extended constructors
383e519524SHoward Hinnant    template <class Alloc>
393e519524SHoward Hinnant        tuple(allocator_arg_t, const Alloc& a);
403e519524SHoward Hinnant    template <class Alloc>
4106e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
423e519524SHoward Hinnant    template <class Alloc, class... U>
4306e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
443e519524SHoward Hinnant    template <class Alloc>
4506e2b737SArthur O'Dwyer        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
463e519524SHoward Hinnant    template <class Alloc>
4706e2b737SArthur O'Dwyer        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
483e519524SHoward Hinnant    template <class Alloc, class... U>
4906e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
503e519524SHoward Hinnant    template <class Alloc, class... U>
5106e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
523e519524SHoward Hinnant    template <class Alloc, class U1, class U2>
5306e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
543e519524SHoward Hinnant    template <class Alloc, class U1, class U2>
5506e2b737SArthur O'Dwyer        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
563e519524SHoward Hinnant
5706e2b737SArthur O'Dwyer    tuple& operator=(const tuple&);                                                       // constexpr in C++20
5806e2b737SArthur O'Dwyer    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
593e519524SHoward Hinnant    template <class... U>
6006e2b737SArthur O'Dwyer        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
613e519524SHoward Hinnant    template <class... U>
6206e2b737SArthur O'Dwyer        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
633e519524SHoward Hinnant    template <class U1, class U2>
6406e2b737SArthur O'Dwyer        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
653e519524SHoward Hinnant    template <class U1, class U2>
6606e2b737SArthur O'Dwyer        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
673e519524SHoward Hinnant
68a0839b14SLouis Dionne    template<class U, size_t N>
69a0839b14SLouis Dionne        tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70a0839b14SLouis Dionne    template<class U, size_t N>
71a0839b14SLouis Dionne        tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72a0839b14SLouis Dionne
7306e2b737SArthur O'Dwyer    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
743e519524SHoward Hinnant};
753e519524SHoward Hinnant
761308011eSLouis Dionnetemplate <class ...T>
771308011eSLouis Dionnetuple(T...) -> tuple<T...>;                                         // since C++17
781308011eSLouis Dionnetemplate <class T1, class T2>
791308011eSLouis Dionnetuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
801308011eSLouis Dionnetemplate <class Alloc, class ...T>
811308011eSLouis Dionnetuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
821308011eSLouis Dionnetemplate <class Alloc, class T1, class T2>
831308011eSLouis Dionnetuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
841308011eSLouis Dionnetemplate <class Alloc, class ...T>
851308011eSLouis Dionnetuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
861308011eSLouis Dionne
8740a01d53SMarshall Clowinline constexpr unspecified ignore;
883e519524SHoward Hinnant
8975eff748SMarshall Clowtemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
90de9320aaSMarshall Clowtemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
910d1560e1SMarshall Clowtemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
9275eff748SMarshall Clowtemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
933e519524SHoward Hinnant
9403e29a29SEric Fiselier// [tuple.apply], calling a function with a tuple of arguments:
9503e29a29SEric Fiseliertemplate <class F, class Tuple>
9603e29a29SEric Fiselier  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
9703e29a29SEric Fiseliertemplate <class T, class Tuple>
9803e29a29SEric Fiselier  constexpr T make_from_tuple(Tuple&& t); // C++17
9903e29a29SEric Fiselier
1003e519524SHoward Hinnant// 20.4.1.4, tuple helper classes:
101e4957601SMarshall Clowtemplate <class T> struct tuple_size; // undefined
102e4957601SMarshall Clowtemplate <class... T> struct tuple_size<tuple<T...>>;
10303e29a29SEric Fiseliertemplate <class T>
10440a01d53SMarshall Clow inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
1052b0c7abbSLouis Dionnetemplate <size_t I, class T> struct tuple_element; // undefined
1062b0c7abbSLouis Dionnetemplate <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
107bfb3f2bfSMarshall Clowtemplate <size_t I, class T>
108bfb3f2bfSMarshall Clow  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
1093e519524SHoward Hinnant
1103e519524SHoward Hinnant// 20.4.1.5, element access:
111bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
11227d0a2a7SHoward Hinnant    typename tuple_element<I, tuple<T...>>::type&
1138bf1f08aSMarshall Clow    get(tuple<T...>&) noexcept; // constexpr in C++14
114bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
115bfb3f2bfSMarshall Clow    const typename tuple_element<I, tuple<T...>>::type&
1168bf1f08aSMarshall Clow    get(const tuple<T...>&) noexcept; // constexpr in C++14
117bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
11827d0a2a7SHoward Hinnant    typename tuple_element<I, tuple<T...>>::type&&
1198bf1f08aSMarshall Clow    get(tuple<T...>&&) noexcept; // constexpr in C++14
120545b8861SEric Fiseliertemplate <size_t I, class... T>
121545b8861SEric Fiselier    const typename tuple_element<I, tuple<T...>>::type&&
122545b8861SEric Fiselier    get(const tuple<T...>&&) noexcept; // constexpr in C++14
1233e519524SHoward Hinnant
124e99520c7SMarshall Clowtemplate <class T1, class... T>
125e99520c7SMarshall Clow    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
126e99520c7SMarshall Clowtemplate <class T1, class... T>
127bfb3f2bfSMarshall Clow    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
128e99520c7SMarshall Clowtemplate <class T1, class... T>
129e99520c7SMarshall Clow    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
130545b8861SEric Fiseliertemplate <class T1, class... T>
131545b8861SEric Fiselier    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
132e99520c7SMarshall Clow
1333e519524SHoward Hinnant// 20.4.1.6, relational operators:
13475eff748SMarshall Clowtemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
13575eff748SMarshall Clowtemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
13675eff748SMarshall Clowtemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
13775eff748SMarshall Clowtemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
13875eff748SMarshall Clowtemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
13975eff748SMarshall Clowtemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
1403e519524SHoward Hinnant
1413e519524SHoward Hinnanttemplate <class... Types, class Alloc>
1423e519524SHoward Hinnant  struct uses_allocator<tuple<Types...>, Alloc>;
1433e519524SHoward Hinnant
1443e519524SHoward Hinnanttemplate <class... Types>
14527d0a2a7SHoward Hinnant  void
14627d0a2a7SHoward Hinnant  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1473e519524SHoward Hinnant
1483e519524SHoward Hinnant}  // std
1493e519524SHoward Hinnant
1503e519524SHoward Hinnant*/
1513e519524SHoward Hinnant
1523e519524SHoward Hinnant#include <__config>
1533e519524SHoward Hinnant#include <__tuple>
1542d0f1fa4SArthur O'Dwyer#include <compare>
1553e519524SHoward Hinnant#include <cstddef>
1563e519524SHoward Hinnant#include <type_traits>
157a87b5e34SHoward Hinnant#include <__functional_base>
158a87b5e34SHoward Hinnant#include <utility>
159f56972e2SMarshall Clow#include <version>
1603e519524SHoward Hinnant
161073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1623e519524SHoward Hinnant#pragma GCC system_header
163073458b1SHoward Hinnant#endif
1643e519524SHoward Hinnant
1653e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1663e519524SHoward Hinnant
16729870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1683e519524SHoward Hinnant
16905c8dad2SMarshall Clow
1703e519524SHoward Hinnant// __tuple_leaf
1713e519524SHoward Hinnant
172ee187e24SEric Fiseliertemplate <size_t _Ip, class _Hp,
173ee187e24SEric Fiselier          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
17442b8bb50SHoward Hinnant         >
1753e519524SHoward Hinnantclass __tuple_leaf;
1763e519524SHoward Hinnant
1773e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool _Ep>
17806e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1793e519524SHoward Hinnantvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
18027d0a2a7SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
1813e519524SHoward Hinnant{
1823e519524SHoward Hinnant    swap(__x.get(), __y.get());
1833e519524SHoward Hinnant}
1843e519524SHoward Hinnant
1853e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool>
1863e519524SHoward Hinnantclass __tuple_leaf
1873e519524SHoward Hinnant{
188def3c375SEric Fiselier    _Hp __value_;
1893e519524SHoward Hinnant
190074f8d77SEric Fiselier    template <class _Tp>
191074f8d77SEric Fiselier    static constexpr bool __can_bind_reference() {
192292617e7SEric Fiselier#if __has_keyword(__reference_binds_to_temporary)
193292617e7SEric Fiselier      return !__reference_binds_to_temporary(_Hp, _Tp);
194b1539e0aSEric Fiselier#else
195b1539e0aSEric Fiselier      return true;
196292617e7SEric Fiselier#endif
197074f8d77SEric Fiselier    }
198074f8d77SEric Fiselier
19906e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2003e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2013e519524SHoward Hinnantpublic:
20206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
203def3c375SEric Fiselier             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2043e519524SHoward Hinnant       {static_assert(!is_reference<_Hp>::value,
2053e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2063e519524SHoward Hinnant
2073e519524SHoward Hinnant    template <class _Alloc>
20806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2093e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
210def3c375SEric Fiselier            : __value_()
2113e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2123e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2133e519524SHoward Hinnant
2143e519524SHoward Hinnant    template <class _Alloc>
21506e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2163e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
217def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a)
2183e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2193e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2203e519524SHoward Hinnant
2213e519524SHoward Hinnant    template <class _Alloc>
22206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2233e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
224def3c375SEric Fiselier            : __value_(__a)
2253e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2263e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2273e519524SHoward Hinnant
22830ad985bSHoward Hinnant    template <class _Tp,
2293359a17bSEric Fiselier              class = _EnableIf<
2303359a17bSEric Fiselier                  _And<
2313359a17bSEric Fiselier                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
2323359a17bSEric Fiselier                      is_constructible<_Hp, _Tp>
233567bb79bSEric Fiselier                    >::value
2343359a17bSEric Fiselier                >
235567bb79bSEric Fiselier            >
23675eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2378a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
238def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
239292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
240292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2413e519524SHoward Hinnant
2423e519524SHoward Hinnant    template <class _Tp, class _Alloc>
24306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2443e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
245def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
246292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
247292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2483e519524SHoward Hinnant
2493e519524SHoward Hinnant    template <class _Tp, class _Alloc>
25006e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2513e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
252def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
253074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
254074f8d77SEric Fiselier            "Attempted to uses-allocator construct a reference element in a tuple");}
2553e519524SHoward Hinnant
2563e519524SHoward Hinnant    template <class _Tp, class _Alloc>
25706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2583e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
259def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t), __a)
260074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
261074f8d77SEric Fiselier           "Attempted to uses-allocator construct a reference element in a tuple");}
2623e519524SHoward Hinnant
2637546a111SMarshall Clow    __tuple_leaf(const __tuple_leaf& __t) = default;
2647546a111SMarshall Clow    __tuple_leaf(__tuple_leaf&& __t) = default;
2653e519524SHoward Hinnant
26606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
26727d0a2a7SHoward Hinnant    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
2683e519524SHoward Hinnant    {
269ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
2703e519524SHoward Hinnant        return 0;
2713e519524SHoward Hinnant    }
2723e519524SHoward Hinnant
273def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
274def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
2753e519524SHoward Hinnant};
2763e519524SHoward Hinnant
2773e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp>
2783e519524SHoward Hinnantclass __tuple_leaf<_Ip, _Hp, true>
2793e519524SHoward Hinnant    : private _Hp
2803e519524SHoward Hinnant{
28106e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2823e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2833e519524SHoward Hinnantpublic:
28406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
285a0f4c45cSHoward Hinnant             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
2863e519524SHoward Hinnant
2873e519524SHoward Hinnant    template <class _Alloc>
28806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2893e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
2903e519524SHoward Hinnant
2913e519524SHoward Hinnant    template <class _Alloc>
29206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2933e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
2943e519524SHoward Hinnant            : _Hp(allocator_arg_t(), __a) {}
2953e519524SHoward Hinnant
2963e519524SHoward Hinnant    template <class _Alloc>
29706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2983e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
2993e519524SHoward Hinnant            : _Hp(__a) {}
3003e519524SHoward Hinnant
30130ad985bSHoward Hinnant    template <class _Tp,
3023359a17bSEric Fiselier              class = _EnableIf<
3033359a17bSEric Fiselier                  _And<
3043359a17bSEric Fiselier                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3053359a17bSEric Fiselier                    is_constructible<_Hp, _Tp>
306567bb79bSEric Fiselier                  >::value
3073359a17bSEric Fiselier                >
308567bb79bSEric Fiselier            >
30975eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3108a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
311ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3123e519524SHoward Hinnant
3133e519524SHoward Hinnant    template <class _Tp, class _Alloc>
31406e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3153e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
316ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3173e519524SHoward Hinnant
3183e519524SHoward Hinnant    template <class _Tp, class _Alloc>
31906e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3203e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
321ce48a113SHoward Hinnant            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3223e519524SHoward Hinnant
3233e519524SHoward Hinnant    template <class _Tp, class _Alloc>
32406e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3253e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
326ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3273e519524SHoward Hinnant
328567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf const &) = default;
329567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf &&) = default;
330567bb79bSEric Fiselier
33106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
33227d0a2a7SHoward Hinnant    int
33327d0a2a7SHoward Hinnant    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3343e519524SHoward Hinnant    {
335ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
3363e519524SHoward Hinnant        return 0;
3373e519524SHoward Hinnant    }
3383e519524SHoward Hinnant
33975eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
34075eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3413e519524SHoward Hinnant};
3423e519524SHoward Hinnant
343789847ddSHoward Hinnanttemplate <class ..._Tp>
34406e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3458a9ee148SHoward Hinnantvoid __swallow(_Tp&&...) _NOEXCEPT {}
3463e519524SHoward Hinnant
34714c5ec51SMarshall Clowtemplate <class _Tp>
34814c5ec51SMarshall Clowstruct __all_default_constructible;
34927d0a2a7SHoward Hinnant
35014c5ec51SMarshall Clowtemplate <class ..._Tp>
35114c5ec51SMarshall Clowstruct __all_default_constructible<__tuple_types<_Tp...>>
35214c5ec51SMarshall Clow    : __all<is_default_constructible<_Tp>::value...>
35314c5ec51SMarshall Clow{ };
35427d0a2a7SHoward Hinnant
3553e519524SHoward Hinnant// __tuple_impl
3563e519524SHoward Hinnant
3573e519524SHoward Hinnanttemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3583e519524SHoward Hinnant
3593e519524SHoward Hinnanttemplate<size_t ..._Indx, class ..._Tp>
360b43f17c8SEric Fiselierstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3613e519524SHoward Hinnant    : public __tuple_leaf<_Indx, _Tp>...
3623e519524SHoward Hinnant{
363a62ebe04SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
36406e2b737SArthur O'Dwyer    constexpr __tuple_impl()
365a0f4c45cSHoward Hinnant        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
366a62ebe04SHoward Hinnant
3673e519524SHoward Hinnant    template <size_t ..._Uf, class ..._Tf,
3683e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
36975eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3703e519524SHoward Hinnant        explicit
3713e519524SHoward Hinnant        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3723e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3738a9ee148SHoward Hinnant                     _Up&&... __u)
3748a9ee148SHoward Hinnant                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
3758a9ee148SHoward Hinnant                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
376ce48a113SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
3773e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>()...
3783e519524SHoward Hinnant            {}
3793e519524SHoward Hinnant
3803e519524SHoward Hinnant    template <class _Alloc, size_t ..._Uf, class ..._Tf,
3813e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
38206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3833e519524SHoward Hinnant        explicit
3843e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a,
3853e519524SHoward Hinnant                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3863e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3873e519524SHoward Hinnant                     _Up&&... __u) :
3883e519524SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
389ce48a113SHoward Hinnant            _VSTD::forward<_Up>(__u))...,
3903e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
3913e519524SHoward Hinnant            {}
3923e519524SHoward Hinnant
3933e519524SHoward Hinnant    template <class _Tuple,
3943e519524SHoward Hinnant              class = typename enable_if
3953e519524SHoward Hinnant                      <
396f3b02b17SHoward Hinnant                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
3973e519524SHoward Hinnant                      >::type
3983e519524SHoward Hinnant             >
39975eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4008a9ee148SHoward Hinnant        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4018a9ee148SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
402ce48a113SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
403ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4043e519524SHoward Hinnant            {}
4053e519524SHoward Hinnant
4063e519524SHoward Hinnant    template <class _Alloc, class _Tuple,
4073e519524SHoward Hinnant              class = typename enable_if
4083e519524SHoward Hinnant                      <
4099795699aSEric Fiselier                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4103e519524SHoward Hinnant                      >::type
4113e519524SHoward Hinnant             >
41206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4133e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4143e519524SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4153e519524SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
416ce48a113SHoward Hinnant                                       _VSTD::forward<typename tuple_element<_Indx,
417ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4183e519524SHoward Hinnant            {}
4193e519524SHoward Hinnant
4204478b25aSHoward Hinnant    __tuple_impl(const __tuple_impl&) = default;
4214478b25aSHoward Hinnant    __tuple_impl(__tuple_impl&&) = default;
4224478b25aSHoward Hinnant
42306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4243e519524SHoward Hinnant    void swap(__tuple_impl& __t)
42527d0a2a7SHoward Hinnant        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4263e519524SHoward Hinnant    {
427a0839b14SLouis Dionne        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4283e519524SHoward Hinnant    }
4293e519524SHoward Hinnant};
4303e519524SHoward Hinnant
431a0839b14SLouis Dionnetemplate<class _Dest, class _Source, size_t ..._Np>
43206e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
433a0839b14SLouis Dionnevoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
434a0839b14SLouis Dionne    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
435a0839b14SLouis Dionne}
43674cba642SEric Fiselier
437a0839b14SLouis Dionnetemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
43806e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
439a0839b14SLouis Dionnevoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
440a0839b14SLouis Dionne    _VSTD::__swallow(((
441618862e8SLouis Dionne        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
442a0839b14SLouis Dionne    ), void(), 0)...);
443a0839b14SLouis Dionne}
44474cba642SEric Fiselier
4453e519524SHoward Hinnanttemplate <class ..._Tp>
446e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple
4473e519524SHoward Hinnant{
448def3c375SEric Fiselier    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4493e519524SHoward Hinnant
450def3c375SEric Fiselier    _BaseT __base_;
4513e519524SHoward Hinnant
4528bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
453c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
4548bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
455c206366fSHoward Hinnant        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
4568bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
457c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
458545b8861SEric Fiselier    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
459545b8861SEric Fiselier        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
4603e519524SHoward Hinnantpublic:
461a3ab5120SLouis Dionne    // [tuple.cnstr]
4623e519524SHoward Hinnant
463a3ab5120SLouis Dionne    // tuple() constructors (including allocator_arg_t variants)
464a3ab5120SLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
465a3ab5120SLouis Dionne        _And<
466a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
467a3ab5120SLouis Dionne        >::value
468a3ab5120SLouis Dionne    , int> = 0>
469*ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
470e16f2cb6SLouis Dionne    tuple()
471a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
472a3ab5120SLouis Dionne    { }
473e16f2cb6SLouis Dionne
474a3ab5120SLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
475a3ab5120SLouis Dionne              template<class...> class _IsDefault = is_default_constructible, _EnableIf<
476a3ab5120SLouis Dionne        _And<
477a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
478a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
479a3ab5120SLouis Dionne        >::value
480a3ab5120SLouis Dionne    , int> = 0>
481a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
482a3ab5120SLouis Dionne    explicit tuple()
483a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
484a3ab5120SLouis Dionne    { }
485a62ebe04SHoward Hinnant
486a3ab5120SLouis Dionne    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
487a3ab5120SLouis Dionne        _And<
488a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
489a3ab5120SLouis Dionne        >::value
490a3ab5120SLouis Dionne    , int> = 0>
491a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
492a3ab5120SLouis Dionne    tuple(allocator_arg_t, _Alloc const& __a)
493a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
494a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
495a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
496a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
497a3ab5120SLouis Dionne
498a3ab5120SLouis Dionne    template <class _Alloc,
499a3ab5120SLouis Dionne              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
500a3ab5120SLouis Dionne              template<class...> class _IsDefault = is_default_constructible, _EnableIf<
501a3ab5120SLouis Dionne        _And<
502a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
503a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
504a3ab5120SLouis Dionne        >::value
505a3ab5120SLouis Dionne    , int> = 0>
506a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
507a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, _Alloc const& __a)
508a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
509a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
510a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
511a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
512a3ab5120SLouis Dionne
513a3ab5120SLouis Dionne    // tuple(const T&...) constructors (including allocator_arg_t variants)
514a3ab5120SLouis Dionne    template <template<class...> class _And = _And, _EnableIf<
515a3ab5120SLouis Dionne        _And<
516a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
517a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
518a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
519a3ab5120SLouis Dionne        >::value
520a3ab5120SLouis Dionne    , int> = 0>
521a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
522a3ab5120SLouis Dionne    tuple(const _Tp& ... __t)
523a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
524a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
525a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
526a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
527a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
528a3ab5120SLouis Dionne                __t...
529a3ab5120SLouis Dionne               ) {}
530a3ab5120SLouis Dionne
531a3ab5120SLouis Dionne    template <template<class...> class _And = _And, _EnableIf<
532a3ab5120SLouis Dionne        _And<
533a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
534a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
535a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
536a3ab5120SLouis Dionne        >::value
537a3ab5120SLouis Dionne    , int> = 0>
538a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
539a3ab5120SLouis Dionne    explicit tuple(const _Tp& ... __t)
540a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
541a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
542a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
543a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
544a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
545a3ab5120SLouis Dionne                __t...
546a3ab5120SLouis Dionne               ) {}
547a3ab5120SLouis Dionne
548a3ab5120SLouis Dionne    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
549a3ab5120SLouis Dionne        _And<
550a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
551a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
552a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
553a3ab5120SLouis Dionne        >::value
554a3ab5120SLouis Dionne    , int> = 0>
555a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
556a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
557a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
558a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
559a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
560a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
561a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
562a3ab5120SLouis Dionne                __t...
563a3ab5120SLouis Dionne               ) {}
564a3ab5120SLouis Dionne
565a3ab5120SLouis Dionne    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
566a3ab5120SLouis Dionne        _And<
567a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
568a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
569a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
570a3ab5120SLouis Dionne        >::value
571a3ab5120SLouis Dionne    , int> = 0>
572a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
573a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
574a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
575a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
576a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
577a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
578a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
579a3ab5120SLouis Dionne                __t...
580a3ab5120SLouis Dionne               ) {}
581a3ab5120SLouis Dionne
582a3ab5120SLouis Dionne    // tuple(U&& ...) constructors (including allocator_arg_t variants)
583a3ab5120SLouis Dionne    template <class ..._Up> struct _IsThisTuple : false_type { };
584a3ab5120SLouis Dionne    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
585a3ab5120SLouis Dionne
586a3ab5120SLouis Dionne    template <class ..._Up>
587a3ab5120SLouis Dionne    struct _EnableUTypesCtor : _And<
588a3ab5120SLouis Dionne        _BoolConstant<sizeof...(_Tp) >= 1>,
589a3ab5120SLouis Dionne        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
590a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
591a3ab5120SLouis Dionne    > { };
592a3ab5120SLouis Dionne
593a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
594a3ab5120SLouis Dionne        _And<
595a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
596a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
597a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
598a3ab5120SLouis Dionne        >::value
599a3ab5120SLouis Dionne    , int> = 0>
600a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
601a3ab5120SLouis Dionne    tuple(_Up&&... __u)
602a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
603a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
604a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
605a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
606a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
607a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
608a3ab5120SLouis Dionne
609a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
610a3ab5120SLouis Dionne        _And<
611a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
612a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
613a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
614a3ab5120SLouis Dionne        >::value
615a3ab5120SLouis Dionne    , int> = 0>
616a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
617a3ab5120SLouis Dionne    explicit tuple(_Up&&... __u)
618a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
619a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
620a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
621a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
622a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
623a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
624a3ab5120SLouis Dionne
625a3ab5120SLouis Dionne    template <class _Alloc, class ..._Up, _EnableIf<
626a3ab5120SLouis Dionne        _And<
627a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
628a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
629a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
630a3ab5120SLouis Dionne        >::value
631a3ab5120SLouis Dionne    , int> = 0>
632a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
633a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
634a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
635a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
636a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
637a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
638a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
639a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
640a3ab5120SLouis Dionne
641a3ab5120SLouis Dionne    template <class _Alloc, class ..._Up, _EnableIf<
642a3ab5120SLouis Dionne        _And<
643a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
644a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
645a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
646a3ab5120SLouis Dionne        >::value
647a3ab5120SLouis Dionne    , int> = 0>
648a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
649a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
650a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
651a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
652a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
653a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
654a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
655a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
656a3ab5120SLouis Dionne
657a3ab5120SLouis Dionne    // Copy and move constructors (including the allocator_arg_t variants)
658a3ab5120SLouis Dionne    tuple(const tuple&) = default;
659aedcbf89SEric Fiselier    tuple(tuple&&) = default;
660aedcbf89SEric Fiselier
661a3ab5120SLouis Dionne    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
662a3ab5120SLouis Dionne        _And<is_copy_constructible<_Tp>...>::value
663a3ab5120SLouis Dionne    , int> = 0>
664a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
665a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, __t)
666a3ab5120SLouis Dionne    { }
66790fb2bafSEric Fiselier
668a3ab5120SLouis Dionne    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
669a3ab5120SLouis Dionne        _And<is_move_constructible<_Tp>...>::value
670a3ab5120SLouis Dionne    , int> = 0>
671a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
672a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
673a3ab5120SLouis Dionne    { }
67459e26308SLouis Dionne
675a3ab5120SLouis Dionne    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
676a3ab5120SLouis Dionne    template <class ..._Up>
677a3ab5120SLouis Dionne    struct _EnableCopyFromOtherTuple : _And<
678a3ab5120SLouis Dionne        _Or<
679a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
680a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
681a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
682a3ab5120SLouis Dionne            _Lazy<_And,
683a3ab5120SLouis Dionne                _Not<is_same<_Tp, _Up> >...,
684a3ab5120SLouis Dionne                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
685a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
6869795699aSEric Fiselier            >
687a3ab5120SLouis Dionne        >,
688a3ab5120SLouis Dionne        is_constructible<_Tp, const _Up&>...
689a3ab5120SLouis Dionne    > { };
6909795699aSEric Fiselier
691a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
692a3ab5120SLouis Dionne        _And<
693a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
694a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
695a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
6968a9ee148SHoward Hinnant        >::value
697a3ab5120SLouis Dionne    , int> = 0>
69875eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
699a3ab5120SLouis Dionne    tuple(const tuple<_Up...>& __t)
700a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
701a3ab5120SLouis Dionne        : __base_(__t)
702a3ab5120SLouis Dionne    { }
703a3ab5120SLouis Dionne
704a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
705a3ab5120SLouis Dionne        _And<
706a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
707a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
708a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
7098a9ee148SHoward Hinnant        >::value
710a3ab5120SLouis Dionne    , int> = 0>
71175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
712a3ab5120SLouis Dionne    explicit tuple(const tuple<_Up...>& __t)
713a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
714a3ab5120SLouis Dionne        : __base_(__t)
715a3ab5120SLouis Dionne    { }
7163e519524SHoward Hinnant
717a3ab5120SLouis Dionne    template <class ..._Up, class _Alloc, _EnableIf<
718a3ab5120SLouis Dionne        _And<
719a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
720a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
721a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
722a3ab5120SLouis Dionne        >::value
723a3ab5120SLouis Dionne    , int> = 0>
72406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
725a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
726a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
727a3ab5120SLouis Dionne    { }
7283e519524SHoward Hinnant
729a3ab5120SLouis Dionne    template <class ..._Up, class _Alloc, _EnableIf<
730a3ab5120SLouis Dionne        _And<
731a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
732a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
733a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
734a3ab5120SLouis Dionne        >::value
735a3ab5120SLouis Dionne    , int> = 0>
73606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
737a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
738a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
739a3ab5120SLouis Dionne    { }
740a3ab5120SLouis Dionne
741a3ab5120SLouis Dionne    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
742a3ab5120SLouis Dionne    template <class ..._Up>
743a3ab5120SLouis Dionne    struct _EnableMoveFromOtherTuple : _And<
744a3ab5120SLouis Dionne        _Or<
745a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
746a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
747a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
748a3ab5120SLouis Dionne            _Lazy<_And,
749a3ab5120SLouis Dionne                _Not<is_same<_Tp, _Up> >...,
750a3ab5120SLouis Dionne                _Not<is_convertible<tuple<_Up>, _Tp> >...,
751a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, tuple<_Up> > >...
752a3ab5120SLouis Dionne            >
753a3ab5120SLouis Dionne        >,
754a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
755a3ab5120SLouis Dionne    > { };
756a3ab5120SLouis Dionne
757a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
758a3ab5120SLouis Dionne        _And<
759a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
760a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
761a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
762a3ab5120SLouis Dionne        >::value
763a3ab5120SLouis Dionne    , int> = 0>
764a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
765a3ab5120SLouis Dionne    tuple(tuple<_Up...>&& __t)
766a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
767a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
768a3ab5120SLouis Dionne    { }
769a3ab5120SLouis Dionne
770a3ab5120SLouis Dionne    template <class ..._Up, _EnableIf<
771a3ab5120SLouis Dionne        _And<
772a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
773a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
774a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
775a3ab5120SLouis Dionne        >::value
776a3ab5120SLouis Dionne    , int> = 0>
777a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
778a3ab5120SLouis Dionne    explicit tuple(tuple<_Up...>&& __t)
779a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
780a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
781a3ab5120SLouis Dionne    { }
782a3ab5120SLouis Dionne
783a3ab5120SLouis Dionne    template <class _Alloc, class ..._Up, _EnableIf<
784a3ab5120SLouis Dionne        _And<
785a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
786a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
787a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
788a3ab5120SLouis Dionne        >::value
789a3ab5120SLouis Dionne    , int> = 0>
790a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
791a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
792a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
793a3ab5120SLouis Dionne    { }
794a3ab5120SLouis Dionne
795a3ab5120SLouis Dionne    template <class _Alloc, class ..._Up, _EnableIf<
796a3ab5120SLouis Dionne        _And<
797a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
798a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
799a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
800a3ab5120SLouis Dionne        >::value
801a3ab5120SLouis Dionne    , int> = 0>
802a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
803a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
804a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
805a3ab5120SLouis Dionne    { }
806a3ab5120SLouis Dionne
807a3ab5120SLouis Dionne    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
808a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
809a3ab5120SLouis Dionne    struct _EnableImplicitCopyFromPair : _And<
810a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
811a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
812a3ab5120SLouis Dionne        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
813a3ab5120SLouis Dionne        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
814a3ab5120SLouis Dionne    > { };
815a3ab5120SLouis Dionne
816a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
817a3ab5120SLouis Dionne    struct _EnableExplicitCopyFromPair : _And<
818a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
819a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
820a3ab5120SLouis Dionne        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
821a3ab5120SLouis Dionne        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
822a3ab5120SLouis Dionne    > { };
823a3ab5120SLouis Dionne
824a3ab5120SLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
825a3ab5120SLouis Dionne        _And<
826a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
827a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
828a3ab5120SLouis Dionne        >::value
829a3ab5120SLouis Dionne    , int> = 0>
830a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
831a3ab5120SLouis Dionne    tuple(const pair<_Up1, _Up2>& __p)
832a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
833a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
834a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
835a3ab5120SLouis Dionne        >::value))
836a3ab5120SLouis Dionne        : __base_(__p)
837a3ab5120SLouis Dionne    { }
838a3ab5120SLouis Dionne
839a3ab5120SLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
840a3ab5120SLouis Dionne        _And<
841a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
842a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
843a3ab5120SLouis Dionne        >::value
844a3ab5120SLouis Dionne    , int> = 0>
845a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
846a3ab5120SLouis Dionne    explicit tuple(const pair<_Up1, _Up2>& __p)
847a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
848a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
849a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
850a3ab5120SLouis Dionne        >::value))
851a3ab5120SLouis Dionne        : __base_(__p)
852a3ab5120SLouis Dionne    { }
853a3ab5120SLouis Dionne
854a3ab5120SLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
855a3ab5120SLouis Dionne        _And<
856a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
857a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
858a3ab5120SLouis Dionne        >::value
859a3ab5120SLouis Dionne    , int> = 0>
860a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
861a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
862a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
863a3ab5120SLouis Dionne    { }
864a3ab5120SLouis Dionne
865a3ab5120SLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
866a3ab5120SLouis Dionne        _And<
867a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
868a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
869a3ab5120SLouis Dionne        >::value
870a3ab5120SLouis Dionne    , int> = 0>
871a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
872a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
873a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
874a3ab5120SLouis Dionne    { }
875a3ab5120SLouis Dionne
876a3ab5120SLouis Dionne    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
877a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
878a3ab5120SLouis Dionne    struct _EnableImplicitMoveFromPair : _And<
879a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
880a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
881a3ab5120SLouis Dionne        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
882a3ab5120SLouis Dionne        is_convertible<_Up2, _SecondType<_DependentTp...> >
883a3ab5120SLouis Dionne    > { };
884a3ab5120SLouis Dionne
885a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
886a3ab5120SLouis Dionne    struct _EnableExplicitMoveFromPair : _And<
887a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
888a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
889a3ab5120SLouis Dionne        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
890a3ab5120SLouis Dionne        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
891a3ab5120SLouis Dionne    > { };
892a3ab5120SLouis Dionne
893a3ab5120SLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
894a3ab5120SLouis Dionne        _And<
895a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
896a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
897a3ab5120SLouis Dionne        >::value
898a3ab5120SLouis Dionne    , int> = 0>
899*ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
900a3ab5120SLouis Dionne    tuple(pair<_Up1, _Up2>&& __p)
901a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
902a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
903a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
904a3ab5120SLouis Dionne        >::value))
905a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
906a3ab5120SLouis Dionne    { }
907a3ab5120SLouis Dionne
908a3ab5120SLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
909a3ab5120SLouis Dionne        _And<
910a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
911a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
912a3ab5120SLouis Dionne        >::value
913a3ab5120SLouis Dionne    , int> = 0>
914*ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
915a3ab5120SLouis Dionne    explicit tuple(pair<_Up1, _Up2>&& __p)
916a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
917a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
918a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
919a3ab5120SLouis Dionne        >::value))
920a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
921a3ab5120SLouis Dionne    { }
922a3ab5120SLouis Dionne
923a3ab5120SLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
924a3ab5120SLouis Dionne        _And<
925a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
926a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
927a3ab5120SLouis Dionne        >::value
928a3ab5120SLouis Dionne    , int> = 0>
929a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
930a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
931a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
932a3ab5120SLouis Dionne    { }
933a3ab5120SLouis Dionne
934a3ab5120SLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
935a3ab5120SLouis Dionne        _And<
936a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
937a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
938a3ab5120SLouis Dionne        >::value
939a3ab5120SLouis Dionne    , int> = 0>
940a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
941a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
942a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
943a3ab5120SLouis Dionne    { }
9449795699aSEric Fiselier
945a0839b14SLouis Dionne    // [tuple.assign]
94606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
947a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
948a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
949aedcbf89SEric Fiselier    {
950a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
951a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
952aedcbf89SEric Fiselier        return *this;
953aedcbf89SEric Fiselier    }
954aedcbf89SEric Fiselier
95506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
956a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
957a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
958aedcbf89SEric Fiselier    {
959a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
960a0839b14SLouis Dionne            __tuple_types<_Tp...>(),
961a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
962aedcbf89SEric Fiselier        return *this;
963aedcbf89SEric Fiselier    }
964aedcbf89SEric Fiselier
965a0839b14SLouis Dionne    template<class... _Up, _EnableIf<
966a0839b14SLouis Dionne        _And<
967a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
968a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
969a0839b14SLouis Dionne        >::value
970a0839b14SLouis Dionne    ,int> = 0>
97106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
972a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...> const& __tuple)
973a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
9743e519524SHoward Hinnant    {
975a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
976a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9773e519524SHoward Hinnant        return *this;
9783e519524SHoward Hinnant    }
9793e519524SHoward Hinnant
980a0839b14SLouis Dionne    template<class... _Up, _EnableIf<
981a0839b14SLouis Dionne        _And<
982a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
983a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
984a0839b14SLouis Dionne        >::value
985a0839b14SLouis Dionne    ,int> = 0>
98606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
987a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...>&& __tuple)
988a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
989a0839b14SLouis Dionne    {
990a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
991a0839b14SLouis Dionne            __tuple_types<_Up...>(),
992a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
993a0839b14SLouis Dionne        return *this;
994a0839b14SLouis Dionne    }
995a0839b14SLouis Dionne
996a0839b14SLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
997a0839b14SLouis Dionne        _And<_Dep,
998a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
999a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1000a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1001a0839b14SLouis Dionne        >::value
1002a0839b14SLouis Dionne    ,int> = 0>
100306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1004a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1005a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1006a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1007a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1008a0839b14SLouis Dionne        >::value))
1009a0839b14SLouis Dionne    {
1010a0839b14SLouis Dionne        _VSTD::get<0>(*this) = __pair.first;
1011a0839b14SLouis Dionne        _VSTD::get<1>(*this) = __pair.second;
1012a0839b14SLouis Dionne        return *this;
1013a0839b14SLouis Dionne    }
1014a0839b14SLouis Dionne
1015a0839b14SLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1016a0839b14SLouis Dionne        _And<_Dep,
1017a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1018a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1019a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1020a0839b14SLouis Dionne        >::value
1021a0839b14SLouis Dionne    ,int> = 0>
102206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1023a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1024a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1025a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1026a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1027a0839b14SLouis Dionne        >::value))
1028a0839b14SLouis Dionne    {
1029618862e8SLouis Dionne        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1030618862e8SLouis Dionne        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1031a0839b14SLouis Dionne        return *this;
1032a0839b14SLouis Dionne    }
1033a0839b14SLouis Dionne
1034a0839b14SLouis Dionne    // EXTENSION
1035a0839b14SLouis Dionne    template<class _Up, size_t _Np, class = _EnableIf<
1036a0839b14SLouis Dionne        _And<
1037a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1038a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
1039a0839b14SLouis Dionne        >::value
1040a0839b14SLouis Dionne    > >
104106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1042a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np> const& __array)
1043a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1044a0839b14SLouis Dionne    {
1045a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __array,
1046a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1047a0839b14SLouis Dionne        return *this;
1048a0839b14SLouis Dionne    }
1049a0839b14SLouis Dionne
1050a0839b14SLouis Dionne    // EXTENSION
1051a0839b14SLouis Dionne    template<class _Up, size_t _Np, class = void, class = _EnableIf<
1052a0839b14SLouis Dionne        _And<
1053a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1054a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
1055a0839b14SLouis Dionne        >::value
1056a0839b14SLouis Dionne    > >
105706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1058a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np>&& __array)
1059a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1060a0839b14SLouis Dionne    {
1061a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1062a0839b14SLouis Dionne            __tuple_types<_If<true, _Up, _Tp>...>(),
1063a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1064a0839b14SLouis Dionne        return *this;
1065a0839b14SLouis Dionne    }
1066a0839b14SLouis Dionne
1067a0839b14SLouis Dionne    // [tuple.swap]
106806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
106927d0a2a7SHoward Hinnant    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1070def3c375SEric Fiselier        {__base_.swap(__t.__base_);}
10713e519524SHoward Hinnant};
10723e519524SHoward Hinnant
10733e519524SHoward Hinnanttemplate <>
1074e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple<>
10753e519524SHoward Hinnant{
10763e519524SHoward Hinnantpublic:
107706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr
107806e2b737SArthur O'Dwyer        tuple() _NOEXCEPT = default;
10793e519524SHoward Hinnant    template <class _Alloc>
108006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10818a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
10823e519524SHoward Hinnant    template <class _Alloc>
108306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10848a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1085c003db1fSHoward Hinnant    template <class _Up>
108606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10878a9ee148SHoward Hinnant        tuple(array<_Up, 0>) _NOEXCEPT {}
1088c003db1fSHoward Hinnant    template <class _Alloc, class _Up>
108906e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10908a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
109106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
109227d0a2a7SHoward Hinnant    void swap(tuple&) _NOEXCEPT {}
10933e519524SHoward Hinnant};
10943e519524SHoward Hinnant
1095af65856eSEric Fiselier#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
10961308011eSLouis Dionnetemplate <class ..._Tp>
10971308011eSLouis Dionnetuple(_Tp...) -> tuple<_Tp...>;
10981308011eSLouis Dionnetemplate <class _Tp1, class _Tp2>
10991308011eSLouis Dionnetuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11001308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11011308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
11021308011eSLouis Dionnetemplate <class _Alloc, class _Tp1, class _Tp2>
11031308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11041308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11051308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1106baaee206SEric Fiselier#endif
1107baaee206SEric Fiselier
11083e519524SHoward Hinnanttemplate <class ..._Tp>
110906e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1110bc95cf0dSHoward Hinnanttypename enable_if
1111bc95cf0dSHoward Hinnant<
1112bc95cf0dSHoward Hinnant    __all<__is_swappable<_Tp>::value...>::value,
11133e519524SHoward Hinnant    void
1114bc95cf0dSHoward Hinnant>::type
111527d0a2a7SHoward Hinnantswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
111627d0a2a7SHoward Hinnant                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
111727d0a2a7SHoward Hinnant    {__t.swap(__u);}
11183e519524SHoward Hinnant
11193e519524SHoward Hinnant// get
11203e519524SHoward Hinnant
11213e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11228bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11233e519524SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&
1124c206366fSHoward Hinnantget(tuple<_Tp...>& __t) _NOEXCEPT
11253e519524SHoward Hinnant{
112614d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1127def3c375SEric Fiselier    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
11283e519524SHoward Hinnant}
11293e519524SHoward Hinnant
11303e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11318bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11323e519524SHoward Hinnantconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
1133c206366fSHoward Hinnantget(const tuple<_Tp...>& __t) _NOEXCEPT
11343e519524SHoward Hinnant{
113514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1136def3c375SEric Fiselier    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
11373e519524SHoward Hinnant}
11383e519524SHoward Hinnant
1139601afb30SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11408bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1141601afb30SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&&
1142c206366fSHoward Hinnantget(tuple<_Tp...>&& __t) _NOEXCEPT
1143601afb30SHoward Hinnant{
114414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11452a3f1bc1SHoward Hinnant    return static_cast<type&&>(
1146def3c375SEric Fiselier             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1147601afb30SHoward Hinnant}
1148601afb30SHoward Hinnant
1149545b8861SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
1150545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1151545b8861SEric Fiselierconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1152545b8861SEric Fiselierget(const tuple<_Tp...>&& __t) _NOEXCEPT
1153545b8861SEric Fiselier{
115414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1155545b8861SEric Fiselier    return static_cast<const type&&>(
1156def3c375SEric Fiselier             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1157545b8861SEric Fiselier}
1158545b8861SEric Fiselier
1159e99520c7SMarshall Clow#if _LIBCPP_STD_VER > 11
1160e99520c7SMarshall Clow
1161f447e62eSEric Fiseliernamespace __find_detail {
1162f447e62eSEric Fiselier
1163f447e62eSEric Fiselierstatic constexpr size_t __not_found = -1;
1164f447e62eSEric Fiselierstatic constexpr size_t __ambiguous = __not_found - 1;
1165f447e62eSEric Fiselier
1166f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1167f447e62eSEric Fiselierconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1168f447e62eSEric Fiselier    return !__matches ? __res :
1169f447e62eSEric Fiselier        (__res == __not_found ? __curr_i : __ambiguous);
1170f447e62eSEric Fiselier}
1171f447e62eSEric Fiselier
1172f447e62eSEric Fiseliertemplate <size_t _Nx>
1173f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1174f447e62eSEric Fiselierconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1175f447e62eSEric Fiselier  return __i == _Nx ? __not_found :
1176f447e62eSEric Fiselier      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1177f447e62eSEric Fiselier}
1178f447e62eSEric Fiselier
1179f447e62eSEric Fiseliertemplate <class _T1, class ..._Args>
1180f447e62eSEric Fiselierstruct __find_exactly_one_checked {
118100c872f3SCasey Carter    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1182f447e62eSEric Fiselier    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1183f447e62eSEric Fiselier    static_assert(value != __not_found, "type not found in type list" );
1184f447e62eSEric Fiselier    static_assert(value != __ambiguous, "type occurs more than once in type list");
1185e99520c7SMarshall Clow};
1186e99520c7SMarshall Clow
11874f905b8dSEric Fiseliertemplate <class _T1>
11884f905b8dSEric Fiselierstruct __find_exactly_one_checked<_T1> {
11894f905b8dSEric Fiselier    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
11904f905b8dSEric Fiselier};
11914f905b8dSEric Fiselier
1192f447e62eSEric Fiselier} // namespace __find_detail;
1193e99520c7SMarshall Clow
1194e99520c7SMarshall Clowtemplate <typename _T1, typename... _Args>
1195f447e62eSEric Fiselierstruct __find_exactly_one_t
1196f447e62eSEric Fiselier    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1197e99520c7SMarshall Clow};
1198e99520c7SMarshall Clow
1199e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1200e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1201e99520c7SMarshall Clowconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
1202e99520c7SMarshall Clow{
1203e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1204e99520c7SMarshall Clow}
1205e99520c7SMarshall Clow
1206e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1207e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1208e99520c7SMarshall Clowconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1209e99520c7SMarshall Clow{
1210e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1211e99520c7SMarshall Clow}
1212e99520c7SMarshall Clow
1213e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1214e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1215e99520c7SMarshall Clowconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1216e99520c7SMarshall Clow{
12171c682f0fSMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1218e99520c7SMarshall Clow}
1219e99520c7SMarshall Clow
1220545b8861SEric Fiseliertemplate <class _T1, class... _Args>
1221545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1222545b8861SEric Fiselierconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1223545b8861SEric Fiselier{
1224545b8861SEric Fiselier    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1225545b8861SEric Fiselier}
1226545b8861SEric Fiselier
1227e99520c7SMarshall Clow#endif
1228e99520c7SMarshall Clow
12293e519524SHoward Hinnant// tie
12303e519524SHoward Hinnant
12313e519524SHoward Hinnanttemplate <class ..._Tp>
12320d1560e1SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12333e519524SHoward Hinnanttuple<_Tp&...>
12348a9ee148SHoward Hinnanttie(_Tp&... __t) _NOEXCEPT
12353e519524SHoward Hinnant{
12363e519524SHoward Hinnant    return tuple<_Tp&...>(__t...);
12373e519524SHoward Hinnant}
12383e519524SHoward Hinnant
12393e519524SHoward Hinnanttemplate <class _Up>
12403e519524SHoward Hinnantstruct __ignore_t
12413e519524SHoward Hinnant{
12423e519524SHoward Hinnant    template <class _Tp>
12439af60c4aSEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12443e519524SHoward Hinnant    const __ignore_t& operator=(_Tp&&) const {return *this;}
12453e519524SHoward Hinnant};
12463e519524SHoward Hinnant
12479af60c4aSEric Fiseliernamespace {
124840a01d53SMarshall Clow  _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
12499af60c4aSEric Fiselier}
12503e519524SHoward Hinnant
12513e519524SHoward Hinnanttemplate <class... _Tp>
125275eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1253bb9ca6d0SLouis Dionnetuple<typename __unwrap_ref_decay<_Tp>::type...>
12543e519524SHoward Hinnantmake_tuple(_Tp&&... __t)
12553e519524SHoward Hinnant{
1256bb9ca6d0SLouis Dionne    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
12573e519524SHoward Hinnant}
12583e519524SHoward Hinnant
12591102fbbdSHoward Hinnanttemplate <class... _Tp>
126075eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
126175eff748SMarshall Clowtuple<_Tp&&...>
12628a9ee148SHoward Hinnantforward_as_tuple(_Tp&&... __t) _NOEXCEPT
12631102fbbdSHoward Hinnant{
1264ce48a113SHoward Hinnant    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
12651102fbbdSHoward Hinnant}
12661102fbbdSHoward Hinnant
1267c003db1fSHoward Hinnanttemplate <size_t _Ip>
12683e519524SHoward Hinnantstruct __tuple_equal
12693e519524SHoward Hinnant{
12703e519524SHoward Hinnant    template <class _Tp, class _Up>
127175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12723e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
12733e519524SHoward Hinnant    {
1274f9af6140SMarshall Clow        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
12753e519524SHoward Hinnant    }
12763e519524SHoward Hinnant};
12773e519524SHoward Hinnant
12783e519524SHoward Hinnanttemplate <>
12793e519524SHoward Hinnantstruct __tuple_equal<0>
12803e519524SHoward Hinnant{
12813e519524SHoward Hinnant    template <class _Tp, class _Up>
128275eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12833e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
12843e519524SHoward Hinnant    {
12853e519524SHoward Hinnant        return true;
12863e519524SHoward Hinnant    }
12873e519524SHoward Hinnant};
12883e519524SHoward Hinnant
12893e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
129075eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12913e519524SHoward Hinnantbool
12923e519524SHoward Hinnantoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
12933e519524SHoward Hinnant{
1294aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
12953e519524SHoward Hinnant    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
12963e519524SHoward Hinnant}
12973e519524SHoward Hinnant
12983e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
129975eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13003e519524SHoward Hinnantbool
13013e519524SHoward Hinnantoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13023e519524SHoward Hinnant{
13033e519524SHoward Hinnant    return !(__x == __y);
13043e519524SHoward Hinnant}
13053e519524SHoward Hinnant
1306c003db1fSHoward Hinnanttemplate <size_t _Ip>
13073e519524SHoward Hinnantstruct __tuple_less
13083e519524SHoward Hinnant{
13093e519524SHoward Hinnant    template <class _Tp, class _Up>
131075eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13113e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
13123e519524SHoward Hinnant    {
131353afae49SDuncan P. N. Exon Smith        const size_t __idx = tuple_size<_Tp>::value - _Ip;
131453afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
131553afae49SDuncan P. N. Exon Smith            return true;
131653afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
131753afae49SDuncan P. N. Exon Smith            return false;
131853afae49SDuncan P. N. Exon Smith        return __tuple_less<_Ip-1>()(__x, __y);
13193e519524SHoward Hinnant    }
13203e519524SHoward Hinnant};
13213e519524SHoward Hinnant
13223e519524SHoward Hinnanttemplate <>
13233e519524SHoward Hinnantstruct __tuple_less<0>
13243e519524SHoward Hinnant{
13253e519524SHoward Hinnant    template <class _Tp, class _Up>
132675eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13273e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
13283e519524SHoward Hinnant    {
13293e519524SHoward Hinnant        return false;
13303e519524SHoward Hinnant    }
13313e519524SHoward Hinnant};
13323e519524SHoward Hinnant
13333e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
133475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13353e519524SHoward Hinnantbool
13363e519524SHoward Hinnantoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13373e519524SHoward Hinnant{
1338aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13393e519524SHoward Hinnant    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
13403e519524SHoward Hinnant}
13413e519524SHoward Hinnant
13423e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
134375eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13443e519524SHoward Hinnantbool
13453e519524SHoward Hinnantoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13463e519524SHoward Hinnant{
13473e519524SHoward Hinnant    return __y < __x;
13483e519524SHoward Hinnant}
13493e519524SHoward Hinnant
13503e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
135175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13523e519524SHoward Hinnantbool
13533e519524SHoward Hinnantoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13543e519524SHoward Hinnant{
13553e519524SHoward Hinnant    return !(__x < __y);
13563e519524SHoward Hinnant}
13573e519524SHoward Hinnant
13583e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
135975eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13603e519524SHoward Hinnantbool
13613e519524SHoward Hinnantoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13623e519524SHoward Hinnant{
13633e519524SHoward Hinnant    return !(__y < __x);
13643e519524SHoward Hinnant}
13653e519524SHoward Hinnant
13663e519524SHoward Hinnant// tuple_cat
13673e519524SHoward Hinnant
13687f64810bSHoward Hinnanttemplate <class _Tp, class _Up> struct __tuple_cat_type;
13697f64810bSHoward Hinnant
13707f64810bSHoward Hinnanttemplate <class ..._Ttypes, class ..._Utypes>
13717f64810bSHoward Hinnantstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
13723e519524SHoward Hinnant{
137314d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type;
13747f64810bSHoward Hinnant};
13757f64810bSHoward Hinnant
13767f64810bSHoward Hinnanttemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
13777f64810bSHoward Hinnantstruct __tuple_cat_return_1
13787f64810bSHoward Hinnant{
13797f64810bSHoward Hinnant};
13807f64810bSHoward Hinnant
13817f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0>
13827f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
13837f64810bSHoward Hinnant{
138414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>,
13857e528bc4SEric Fiselier            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
13867f64810bSHoward Hinnant                                                                           type;
13877f64810bSHoward Hinnant};
13887f64810bSHoward Hinnant
13897f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
13907f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
13917f64810bSHoward Hinnant    : public __tuple_cat_return_1<
13927f64810bSHoward Hinnant                 typename __tuple_cat_type<
13937f64810bSHoward Hinnant                     tuple<_Types...>,
13947e528bc4SEric Fiselier                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
13957f64810bSHoward Hinnant                 >::type,
13967f64810bSHoward Hinnant                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
13977f64810bSHoward Hinnant                 _Tuple1, _Tuples...>
13987f64810bSHoward Hinnant{
13997f64810bSHoward Hinnant};
14007f64810bSHoward Hinnant
14017f64810bSHoward Hinnanttemplate <class ..._Tuples> struct __tuple_cat_return;
14027f64810bSHoward Hinnant
14037f64810bSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
14047f64810bSHoward Hinnantstruct __tuple_cat_return<_Tuple0, _Tuples...>
14057f64810bSHoward Hinnant    : public __tuple_cat_return_1<tuple<>,
14067f64810bSHoward Hinnant         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
14077f64810bSHoward Hinnant                                                                     _Tuples...>
14087f64810bSHoward Hinnant{
14097f64810bSHoward Hinnant};
14107f64810bSHoward Hinnant
14117f64810bSHoward Hinnanttemplate <>
14127f64810bSHoward Hinnantstruct __tuple_cat_return<>
14137f64810bSHoward Hinnant{
141414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE tuple<> type;
14157f64810bSHoward Hinnant};
14167f64810bSHoward Hinnant
141775eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14187f64810bSHoward Hinnanttuple<>
14197f64810bSHoward Hinnanttuple_cat()
14207f64810bSHoward Hinnant{
14217f64810bSHoward Hinnant    return tuple<>();
14223e519524SHoward Hinnant}
14233e519524SHoward Hinnant
1424c003db1fSHoward Hinnanttemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1425ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp;
14263e519524SHoward Hinnant
1427ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1428ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
14293e519524SHoward Hinnant{
143014d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1431ba31cbdbSHoward Hinnant    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1432ba31cbdbSHoward Hinnant                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1433ba31cbdbSHoward Hinnant};
1434ba31cbdbSHoward Hinnant
1435ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1436ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1437ba31cbdbSHoward Hinnant                                  _Tuple0, _Tuple1, _Tuples...>
1438ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<
1439ba31cbdbSHoward Hinnant         tuple<_Types..., typename __apply_cv<_Tuple0,
1440ba31cbdbSHoward Hinnant               typename tuple_element<_I0,
1441ba31cbdbSHoward Hinnant                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1442ba31cbdbSHoward Hinnant         typename __make_tuple_indices<tuple_size<typename
1443ba31cbdbSHoward Hinnant                                 remove_reference<_Tuple1>::type>::value>::type,
1444ba31cbdbSHoward Hinnant         _Tuple1, _Tuples...>
1445ba31cbdbSHoward Hinnant{
1446ba31cbdbSHoward Hinnant};
1447ba31cbdbSHoward Hinnant
1448ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
1449ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref
1450ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<tuple<>,
1451ba31cbdbSHoward Hinnant               typename __make_tuple_indices<
1452ba31cbdbSHoward Hinnant                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1453ba31cbdbSHoward Hinnant               >::type, _Tuple0, _Tuples...>
1454ba31cbdbSHoward Hinnant{
1455ba31cbdbSHoward Hinnant};
1456ba31cbdbSHoward Hinnant
1457ba31cbdbSHoward Hinnanttemplate <class _Types, class _I0, class _J0>
1458ba31cbdbSHoward Hinnantstruct __tuple_cat;
1459ba31cbdbSHoward Hinnant
1460ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1461ba31cbdbSHoward Hinnantstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1462ba31cbdbSHoward Hinnant{
1463ba31cbdbSHoward Hinnant    template <class _Tuple0>
146475eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1465ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1466ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1467ba31cbdbSHoward Hinnant    {
1468e658b3ebSDavid Blaikie        return _VSTD::forward_as_tuple(
1469e658b3ebSDavid Blaikie            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1470f9af6140SMarshall Clow            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
14713e519524SHoward Hinnant    }
14723e519524SHoward Hinnant
14737f64810bSHoward Hinnant    template <class _Tuple0, class _Tuple1, class ..._Tuples>
147475eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1475ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1476ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
14773e519524SHoward Hinnant    {
147814d48692SEric Fiselier        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
147914d48692SEric Fiselier        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1;
1480ba31cbdbSHoward Hinnant        return __tuple_cat<
1481e658b3ebSDavid Blaikie            tuple<_Types...,
1482e658b3ebSDavid Blaikie                  typename __apply_cv<_Tuple0, typename tuple_element<
1483e658b3ebSDavid Blaikie                                                   _J0, _T0>::type>::type&&...>,
1484e658b3ebSDavid Blaikie            typename __make_tuple_indices<sizeof...(_Types) +
1485e658b3ebSDavid Blaikie                                          tuple_size<_T0>::value>::type,
1486e658b3ebSDavid Blaikie            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1487e658b3ebSDavid Blaikie            _VSTD::forward_as_tuple(
1488f9af6140SMarshall Clow                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1489e658b3ebSDavid Blaikie                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1490e658b3ebSDavid Blaikie            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1491ba31cbdbSHoward Hinnant    }
1492ba31cbdbSHoward Hinnant};
1493ba31cbdbSHoward Hinnant
1494ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class... _Tuples>
149575eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1496ba31cbdbSHoward Hinnanttypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1497ba31cbdbSHoward Hinnanttuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1498ba31cbdbSHoward Hinnant{
149914d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1500ba31cbdbSHoward Hinnant    return __tuple_cat<tuple<>, __tuple_indices<>,
1501ba31cbdbSHoward Hinnant                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1502ce48a113SHoward Hinnant                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1503ce48a113SHoward Hinnant                                            _VSTD::forward<_Tuples>(__tpls)...);
15043e519524SHoward Hinnant}
15053e519524SHoward Hinnant
15063e519524SHoward Hinnanttemplate <class ..._Tp, class _Alloc>
1507e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
15083e519524SHoward Hinnant    : true_type {};
15093e519524SHoward Hinnant
15103e519524SHoward Hinnanttemplate <class _T1, class _T2>
15113e519524SHoward Hinnanttemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1512737a4501SMichael Schellenberger Costainline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15133e519524SHoward Hinnantpair<_T1, _T2>::pair(piecewise_construct_t,
15143e519524SHoward Hinnant                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
15153e519524SHoward Hinnant                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1516f9af6140SMarshall Clow    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1517f9af6140SMarshall Clow      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
15183e519524SHoward Hinnant{
15193e519524SHoward Hinnant}
15203e519524SHoward Hinnant
152103e29a29SEric Fiselier#if _LIBCPP_STD_VER > 14
152203e29a29SEric Fiseliertemplate <class _Tp>
152340a01d53SMarshall Clow_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
152403e29a29SEric Fiselier
152503e29a29SEric Fiselier#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
152603e29a29SEric Fiselier
152703e29a29SEric Fiseliertemplate <class _Fn, class _Tuple, size_t ..._Id>
152803e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
152903e29a29SEric Fiselierconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
153003e29a29SEric Fiselier                                            __tuple_indices<_Id...>)
153103e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
153203e29a29SEric Fiselier    _VSTD::__invoke_constexpr(
153303e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f),
153403e29a29SEric Fiselier        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
153503e29a29SEric Fiselier)
153603e29a29SEric Fiselier
153703e29a29SEric Fiseliertemplate <class _Fn, class _Tuple>
153803e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
153903e29a29SEric Fiselierconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
154003e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
154103e29a29SEric Fiselier    _VSTD::__apply_tuple_impl(
154203e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1543655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
154403e29a29SEric Fiselier)
154503e29a29SEric Fiselier
154603e29a29SEric Fiseliertemplate <class _Tp, class _Tuple, size_t... _Idx>
154703e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
154803e29a29SEric Fiselierconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
154903e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
155003e29a29SEric Fiselier    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
155103e29a29SEric Fiselier)
155203e29a29SEric Fiselier
155303e29a29SEric Fiseliertemplate <class _Tp, class _Tuple>
155403e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
155503e29a29SEric Fiselierconstexpr _Tp make_from_tuple(_Tuple&& __t)
155603e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
155703e29a29SEric Fiselier    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1558655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
155903e29a29SEric Fiselier)
156003e29a29SEric Fiselier
156103e29a29SEric Fiselier#undef _LIBCPP_NOEXCEPT_RETURN
156203e29a29SEric Fiselier
156303e29a29SEric Fiselier#endif // _LIBCPP_STD_VER > 14
156403e29a29SEric Fiselier
156529870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
156629870871SEric Fiselier
15673e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
15683e519524SHoward Hinnant
15693e519524SHoward Hinnant#endif // _LIBCPP_TUPLE
1570