xref: /llvm-project-15.0.7/libcxx/include/tuple (revision b4e88d4d)
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>
15369d5a666SChristopher Di Bella#include <__functional/unwrap_ref.h>
154050b064fSChristopher Di Bella#include <__functional_base>
155050b064fSChristopher Di Bella#include <__memory/allocator_arg_t.h>
156050b064fSChristopher Di Bella#include <__memory/uses_allocator.h>
157050b064fSChristopher Di Bella#include <__tuple>
1586adbc83eSChristopher Di Bella#include <__utility/forward.h>
1596adbc83eSChristopher Di Bella#include <__utility/move.h>
1602d0f1fa4SArthur O'Dwyer#include <compare>
1613e519524SHoward Hinnant#include <cstddef>
1623e519524SHoward Hinnant#include <type_traits>
163a87b5e34SHoward Hinnant#include <utility>
164f56972e2SMarshall Clow#include <version>
1653e519524SHoward Hinnant
166073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1673e519524SHoward Hinnant#pragma GCC system_header
168073458b1SHoward Hinnant#endif
1693e519524SHoward Hinnant
1703e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1713e519524SHoward Hinnant
17229870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1733e519524SHoward Hinnant
17405c8dad2SMarshall Clow
1753e519524SHoward Hinnant// __tuple_leaf
1763e519524SHoward Hinnant
177ee187e24SEric Fiseliertemplate <size_t _Ip, class _Hp,
178ee187e24SEric Fiselier          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
17942b8bb50SHoward Hinnant         >
1803e519524SHoward Hinnantclass __tuple_leaf;
1813e519524SHoward Hinnant
1823e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool _Ep>
18306e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1843e519524SHoward Hinnantvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
18527d0a2a7SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
1863e519524SHoward Hinnant{
1873e519524SHoward Hinnant    swap(__x.get(), __y.get());
1883e519524SHoward Hinnant}
1893e519524SHoward Hinnant
1903e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool>
1913e519524SHoward Hinnantclass __tuple_leaf
1923e519524SHoward Hinnant{
193def3c375SEric Fiselier    _Hp __value_;
1943e519524SHoward Hinnant
195074f8d77SEric Fiselier    template <class _Tp>
196074f8d77SEric Fiselier    static constexpr bool __can_bind_reference() {
197292617e7SEric Fiselier#if __has_keyword(__reference_binds_to_temporary)
198292617e7SEric Fiselier      return !__reference_binds_to_temporary(_Hp, _Tp);
199b1539e0aSEric Fiselier#else
200b1539e0aSEric Fiselier      return true;
201292617e7SEric Fiselier#endif
202074f8d77SEric Fiselier    }
203074f8d77SEric Fiselier
20406e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2053e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2063e519524SHoward Hinnantpublic:
20706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
208def3c375SEric Fiselier             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2093e519524SHoward Hinnant       {static_assert(!is_reference<_Hp>::value,
2103e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2113e519524SHoward Hinnant
2123e519524SHoward Hinnant    template <class _Alloc>
21306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2143e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
215def3c375SEric Fiselier            : __value_()
2163e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2173e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2183e519524SHoward Hinnant
2193e519524SHoward Hinnant    template <class _Alloc>
22006e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2213e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
222def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a)
2233e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2243e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2253e519524SHoward Hinnant
2263e519524SHoward Hinnant    template <class _Alloc>
22706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2283e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
229def3c375SEric Fiselier            : __value_(__a)
2303e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2313e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2323e519524SHoward Hinnant
23330ad985bSHoward Hinnant    template <class _Tp,
234*b4e88d4dSLouis Dionne              class = __enable_if_t<
2353359a17bSEric Fiselier                  _And<
2363359a17bSEric Fiselier                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
2373359a17bSEric Fiselier                      is_constructible<_Hp, _Tp>
238567bb79bSEric Fiselier                    >::value
2393359a17bSEric Fiselier                >
240567bb79bSEric Fiselier            >
24175eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2428a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
243def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
244292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
245292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2463e519524SHoward Hinnant
2473e519524SHoward Hinnant    template <class _Tp, class _Alloc>
24806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2493e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
250def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
251292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
252292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2533e519524SHoward Hinnant
2543e519524SHoward Hinnant    template <class _Tp, class _Alloc>
25506e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2563e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
257def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
258074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
259074f8d77SEric Fiselier            "Attempted to uses-allocator construct a reference element in a tuple");}
2603e519524SHoward Hinnant
2613e519524SHoward Hinnant    template <class _Tp, class _Alloc>
26206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2633e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
264def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t), __a)
265074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
266074f8d77SEric Fiselier           "Attempted to uses-allocator construct a reference element in a tuple");}
2673e519524SHoward Hinnant
2687546a111SMarshall Clow    __tuple_leaf(const __tuple_leaf& __t) = default;
2697546a111SMarshall Clow    __tuple_leaf(__tuple_leaf&& __t) = default;
2703e519524SHoward Hinnant
27106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
27227d0a2a7SHoward Hinnant    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
2733e519524SHoward Hinnant    {
274ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
2753e519524SHoward Hinnant        return 0;
2763e519524SHoward Hinnant    }
2773e519524SHoward Hinnant
278def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
279def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
2803e519524SHoward Hinnant};
2813e519524SHoward Hinnant
2823e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp>
2833e519524SHoward Hinnantclass __tuple_leaf<_Ip, _Hp, true>
2843e519524SHoward Hinnant    : private _Hp
2853e519524SHoward Hinnant{
28606e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2873e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2883e519524SHoward Hinnantpublic:
28906e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
290a0f4c45cSHoward Hinnant             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
2913e519524SHoward Hinnant
2923e519524SHoward Hinnant    template <class _Alloc>
29306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2943e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
2953e519524SHoward Hinnant
2963e519524SHoward Hinnant    template <class _Alloc>
29706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2983e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
2993e519524SHoward Hinnant            : _Hp(allocator_arg_t(), __a) {}
3003e519524SHoward Hinnant
3013e519524SHoward Hinnant    template <class _Alloc>
30206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3033e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3043e519524SHoward Hinnant            : _Hp(__a) {}
3053e519524SHoward Hinnant
30630ad985bSHoward Hinnant    template <class _Tp,
307*b4e88d4dSLouis Dionne              class = __enable_if_t<
3083359a17bSEric Fiselier                  _And<
3093359a17bSEric Fiselier                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3103359a17bSEric Fiselier                    is_constructible<_Hp, _Tp>
311567bb79bSEric Fiselier                  >::value
3123359a17bSEric Fiselier                >
313567bb79bSEric Fiselier            >
31475eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3158a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
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, 0>, const _Alloc&, _Tp&& __t)
321ce48a113SHoward Hinnant            : _Hp(_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, 1>, const _Alloc& __a, _Tp&& __t)
326ce48a113SHoward Hinnant            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3273e519524SHoward Hinnant
3283e519524SHoward Hinnant    template <class _Tp, class _Alloc>
32906e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3303e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
331ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3323e519524SHoward Hinnant
333567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf const &) = default;
334567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf &&) = default;
335567bb79bSEric Fiselier
33606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
33727d0a2a7SHoward Hinnant    int
33827d0a2a7SHoward Hinnant    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3393e519524SHoward Hinnant    {
340ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
3413e519524SHoward Hinnant        return 0;
3423e519524SHoward Hinnant    }
3433e519524SHoward Hinnant
34475eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
34575eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3463e519524SHoward Hinnant};
3473e519524SHoward Hinnant
348789847ddSHoward Hinnanttemplate <class ..._Tp>
34906e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3508a9ee148SHoward Hinnantvoid __swallow(_Tp&&...) _NOEXCEPT {}
3513e519524SHoward Hinnant
35214c5ec51SMarshall Clowtemplate <class _Tp>
35314c5ec51SMarshall Clowstruct __all_default_constructible;
35427d0a2a7SHoward Hinnant
35514c5ec51SMarshall Clowtemplate <class ..._Tp>
35614c5ec51SMarshall Clowstruct __all_default_constructible<__tuple_types<_Tp...>>
35714c5ec51SMarshall Clow    : __all<is_default_constructible<_Tp>::value...>
35814c5ec51SMarshall Clow{ };
35927d0a2a7SHoward Hinnant
3603e519524SHoward Hinnant// __tuple_impl
3613e519524SHoward Hinnant
3623e519524SHoward Hinnanttemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3633e519524SHoward Hinnant
3643e519524SHoward Hinnanttemplate<size_t ..._Indx, class ..._Tp>
365b43f17c8SEric Fiselierstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3663e519524SHoward Hinnant    : public __tuple_leaf<_Indx, _Tp>...
3673e519524SHoward Hinnant{
368a62ebe04SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
36906e2b737SArthur O'Dwyer    constexpr __tuple_impl()
370a0f4c45cSHoward Hinnant        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
371a62ebe04SHoward Hinnant
3723e519524SHoward Hinnant    template <size_t ..._Uf, class ..._Tf,
3733e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
37475eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3753e519524SHoward Hinnant        explicit
3763e519524SHoward Hinnant        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3773e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3788a9ee148SHoward Hinnant                     _Up&&... __u)
3798a9ee148SHoward Hinnant                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
3808a9ee148SHoward Hinnant                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
381ce48a113SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
3823e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>()...
3833e519524SHoward Hinnant            {}
3843e519524SHoward Hinnant
3853e519524SHoward Hinnant    template <class _Alloc, size_t ..._Uf, class ..._Tf,
3863e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
38706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3883e519524SHoward Hinnant        explicit
3893e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a,
3903e519524SHoward Hinnant                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3913e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3923e519524SHoward Hinnant                     _Up&&... __u) :
3933e519524SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
394ce48a113SHoward Hinnant            _VSTD::forward<_Up>(__u))...,
3953e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
3963e519524SHoward Hinnant            {}
3973e519524SHoward Hinnant
3983e519524SHoward Hinnant    template <class _Tuple,
3993e519524SHoward Hinnant              class = typename enable_if
4003e519524SHoward Hinnant                      <
401f3b02b17SHoward Hinnant                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4023e519524SHoward Hinnant                      >::type
4033e519524SHoward Hinnant             >
40475eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4058a9ee148SHoward Hinnant        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4068a9ee148SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
407ce48a113SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
408ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4093e519524SHoward Hinnant            {}
4103e519524SHoward Hinnant
4113e519524SHoward Hinnant    template <class _Alloc, class _Tuple,
4123e519524SHoward Hinnant              class = typename enable_if
4133e519524SHoward Hinnant                      <
4149795699aSEric Fiselier                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4153e519524SHoward Hinnant                      >::type
4163e519524SHoward Hinnant             >
41706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4183e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4193e519524SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4203e519524SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
421ce48a113SHoward Hinnant                                       _VSTD::forward<typename tuple_element<_Indx,
422ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4233e519524SHoward Hinnant            {}
4243e519524SHoward Hinnant
4254478b25aSHoward Hinnant    __tuple_impl(const __tuple_impl&) = default;
4264478b25aSHoward Hinnant    __tuple_impl(__tuple_impl&&) = default;
4274478b25aSHoward Hinnant
42806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4293e519524SHoward Hinnant    void swap(__tuple_impl& __t)
43027d0a2a7SHoward Hinnant        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4313e519524SHoward Hinnant    {
432a0839b14SLouis Dionne        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4333e519524SHoward Hinnant    }
4343e519524SHoward Hinnant};
4353e519524SHoward Hinnant
436a0839b14SLouis Dionnetemplate<class _Dest, class _Source, size_t ..._Np>
43706e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
438a0839b14SLouis Dionnevoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
439a0839b14SLouis Dionne    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
440a0839b14SLouis Dionne}
44174cba642SEric Fiselier
442a0839b14SLouis Dionnetemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
44306e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444a0839b14SLouis Dionnevoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
445a0839b14SLouis Dionne    _VSTD::__swallow(((
446618862e8SLouis Dionne        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
447a0839b14SLouis Dionne    ), void(), 0)...);
448a0839b14SLouis Dionne}
44974cba642SEric Fiselier
4503e519524SHoward Hinnanttemplate <class ..._Tp>
451e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple
4523e519524SHoward Hinnant{
453def3c375SEric Fiselier    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4543e519524SHoward Hinnant
455def3c375SEric Fiselier    _BaseT __base_;
4563e519524SHoward Hinnant
4578bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
458c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
4598bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
460c206366fSHoward Hinnant        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
4618bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
462c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
463545b8861SEric Fiselier    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
464545b8861SEric Fiselier        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
4653e519524SHoward Hinnantpublic:
466a3ab5120SLouis Dionne    // [tuple.cnstr]
4673e519524SHoward Hinnant
468a3ab5120SLouis Dionne    // tuple() constructors (including allocator_arg_t variants)
469*b4e88d4dSLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
470a3ab5120SLouis Dionne        _And<
471a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
472a3ab5120SLouis Dionne        >::value
473a3ab5120SLouis Dionne    , int> = 0>
474ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
475e16f2cb6SLouis Dionne    tuple()
476a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
477a3ab5120SLouis Dionne    { }
478e16f2cb6SLouis Dionne
479a3ab5120SLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
480*b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
481a3ab5120SLouis Dionne        _And<
482a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
483a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
484a3ab5120SLouis Dionne        >::value
485a3ab5120SLouis Dionne    , int> = 0>
486a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
487a3ab5120SLouis Dionne    explicit tuple()
488a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
489a3ab5120SLouis Dionne    { }
490a62ebe04SHoward Hinnant
491*b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
492a3ab5120SLouis Dionne        _And<
493a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
494a3ab5120SLouis Dionne        >::value
495a3ab5120SLouis Dionne    , int> = 0>
496a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
497a3ab5120SLouis Dionne    tuple(allocator_arg_t, _Alloc const& __a)
498a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
499a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
500a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
501a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
502a3ab5120SLouis Dionne
503a3ab5120SLouis Dionne    template <class _Alloc,
504a3ab5120SLouis Dionne              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
505*b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
506a3ab5120SLouis Dionne        _And<
507a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
508a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
509a3ab5120SLouis Dionne        >::value
510a3ab5120SLouis Dionne    , int> = 0>
511a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
512a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, _Alloc const& __a)
513a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
514a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
515a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
516a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
517a3ab5120SLouis Dionne
518a3ab5120SLouis Dionne    // tuple(const T&...) constructors (including allocator_arg_t variants)
519*b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
520a3ab5120SLouis Dionne        _And<
521a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
522a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
523a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
524a3ab5120SLouis Dionne        >::value
525a3ab5120SLouis Dionne    , int> = 0>
526a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
527a3ab5120SLouis Dionne    tuple(const _Tp& ... __t)
528a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
529a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
530a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
531a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
532a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
533a3ab5120SLouis Dionne                __t...
534a3ab5120SLouis Dionne               ) {}
535a3ab5120SLouis Dionne
536*b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
537a3ab5120SLouis Dionne        _And<
538a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
539a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
540a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
541a3ab5120SLouis Dionne        >::value
542a3ab5120SLouis Dionne    , int> = 0>
543a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
544a3ab5120SLouis Dionne    explicit tuple(const _Tp& ... __t)
545a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
546a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
547a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
548a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
549a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
550a3ab5120SLouis Dionne                __t...
551a3ab5120SLouis Dionne               ) {}
552a3ab5120SLouis Dionne
553*b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
554a3ab5120SLouis Dionne        _And<
555a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
556a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
557a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
558a3ab5120SLouis Dionne        >::value
559a3ab5120SLouis Dionne    , int> = 0>
560a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
561a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
562a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
563a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
564a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
565a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
566a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
567a3ab5120SLouis Dionne                __t...
568a3ab5120SLouis Dionne               ) {}
569a3ab5120SLouis Dionne
570*b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
571a3ab5120SLouis Dionne        _And<
572a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
573a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
574a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
575a3ab5120SLouis Dionne        >::value
576a3ab5120SLouis Dionne    , int> = 0>
577a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
578a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
579a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
580a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
581a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
582a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
583a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
584a3ab5120SLouis Dionne                __t...
585a3ab5120SLouis Dionne               ) {}
586a3ab5120SLouis Dionne
587a3ab5120SLouis Dionne    // tuple(U&& ...) constructors (including allocator_arg_t variants)
588a3ab5120SLouis Dionne    template <class ..._Up> struct _IsThisTuple : false_type { };
589a3ab5120SLouis Dionne    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
590a3ab5120SLouis Dionne
591a3ab5120SLouis Dionne    template <class ..._Up>
592a3ab5120SLouis Dionne    struct _EnableUTypesCtor : _And<
593a3ab5120SLouis Dionne        _BoolConstant<sizeof...(_Tp) >= 1>,
594a3ab5120SLouis Dionne        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
595a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
596a3ab5120SLouis Dionne    > { };
597a3ab5120SLouis Dionne
598*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
599a3ab5120SLouis Dionne        _And<
600a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
601a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
602a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
603a3ab5120SLouis Dionne        >::value
604a3ab5120SLouis Dionne    , int> = 0>
605a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
606a3ab5120SLouis Dionne    tuple(_Up&&... __u)
607a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
608a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
609a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
610a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
611a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
612a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
613a3ab5120SLouis Dionne
614*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
615a3ab5120SLouis Dionne        _And<
616a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
617a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
618a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
619a3ab5120SLouis Dionne        >::value
620a3ab5120SLouis Dionne    , int> = 0>
621a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
622a3ab5120SLouis Dionne    explicit tuple(_Up&&... __u)
623a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
624a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
625a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
626a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
627a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
628a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
629a3ab5120SLouis Dionne
630*b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
631a3ab5120SLouis Dionne        _And<
632a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
633a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
634a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
635a3ab5120SLouis Dionne        >::value
636a3ab5120SLouis Dionne    , int> = 0>
637a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
638a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
639a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
640a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
641a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
642a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
643a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
644a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
645a3ab5120SLouis Dionne
646*b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
647a3ab5120SLouis Dionne        _And<
648a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
649a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
650a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
651a3ab5120SLouis Dionne        >::value
652a3ab5120SLouis Dionne    , int> = 0>
653a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
655a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
656a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
657a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
658a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
659a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
660a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
661a3ab5120SLouis Dionne
662a3ab5120SLouis Dionne    // Copy and move constructors (including the allocator_arg_t variants)
663a3ab5120SLouis Dionne    tuple(const tuple&) = default;
664aedcbf89SEric Fiselier    tuple(tuple&&) = default;
665aedcbf89SEric Fiselier
666*b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
667a3ab5120SLouis Dionne        _And<is_copy_constructible<_Tp>...>::value
668a3ab5120SLouis Dionne    , int> = 0>
669a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
670a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, __t)
671a3ab5120SLouis Dionne    { }
67290fb2bafSEric Fiselier
673*b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
674a3ab5120SLouis Dionne        _And<is_move_constructible<_Tp>...>::value
675a3ab5120SLouis Dionne    , int> = 0>
676a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
677a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
678a3ab5120SLouis Dionne    { }
67959e26308SLouis Dionne
680a3ab5120SLouis Dionne    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
681a3ab5120SLouis Dionne    template <class ..._Up>
682a3ab5120SLouis Dionne    struct _EnableCopyFromOtherTuple : _And<
68317f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
68417f2d1cbSLouis Dionne        _Lazy<_Or,
685a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
686a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
687a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
688a3ab5120SLouis Dionne            _Lazy<_And,
689a3ab5120SLouis Dionne                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
690a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
6919795699aSEric Fiselier            >
692a3ab5120SLouis Dionne        >,
693a3ab5120SLouis Dionne        is_constructible<_Tp, const _Up&>...
694a3ab5120SLouis Dionne    > { };
6959795699aSEric Fiselier
696*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
697a3ab5120SLouis Dionne        _And<
698a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
699a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
700a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
7018a9ee148SHoward Hinnant        >::value
702a3ab5120SLouis Dionne    , int> = 0>
70375eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
704a3ab5120SLouis Dionne    tuple(const tuple<_Up...>& __t)
705a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
706a3ab5120SLouis Dionne        : __base_(__t)
707a3ab5120SLouis Dionne    { }
708a3ab5120SLouis Dionne
709*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
710a3ab5120SLouis Dionne        _And<
711a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
712a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
713a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
7148a9ee148SHoward Hinnant        >::value
715a3ab5120SLouis Dionne    , int> = 0>
71675eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
717a3ab5120SLouis Dionne    explicit tuple(const tuple<_Up...>& __t)
718a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
719a3ab5120SLouis Dionne        : __base_(__t)
720a3ab5120SLouis Dionne    { }
7213e519524SHoward Hinnant
722*b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
723a3ab5120SLouis Dionne        _And<
724a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
725a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
726a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
727a3ab5120SLouis Dionne        >::value
728a3ab5120SLouis Dionne    , int> = 0>
72906e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
730a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
731a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
732a3ab5120SLouis Dionne    { }
7333e519524SHoward Hinnant
734*b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
735a3ab5120SLouis Dionne        _And<
736a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
737a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
738a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
739a3ab5120SLouis Dionne        >::value
740a3ab5120SLouis Dionne    , int> = 0>
74106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
742a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
743a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
744a3ab5120SLouis Dionne    { }
745a3ab5120SLouis Dionne
746a3ab5120SLouis Dionne    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
747a3ab5120SLouis Dionne    template <class ..._Up>
748a3ab5120SLouis Dionne    struct _EnableMoveFromOtherTuple : _And<
74917f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
75017f2d1cbSLouis Dionne        _Lazy<_Or,
751a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
752a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
753a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
754a3ab5120SLouis Dionne            _Lazy<_And,
755a3ab5120SLouis Dionne                _Not<is_convertible<tuple<_Up>, _Tp> >...,
756a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, tuple<_Up> > >...
757a3ab5120SLouis Dionne            >
758a3ab5120SLouis Dionne        >,
759a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
760a3ab5120SLouis Dionne    > { };
761a3ab5120SLouis Dionne
762*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
763a3ab5120SLouis Dionne        _And<
764a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
765a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
766a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
767a3ab5120SLouis Dionne        >::value
768a3ab5120SLouis Dionne    , int> = 0>
769a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
770a3ab5120SLouis Dionne    tuple(tuple<_Up...>&& __t)
771a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
772a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
773a3ab5120SLouis Dionne    { }
774a3ab5120SLouis Dionne
775*b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
776a3ab5120SLouis Dionne        _And<
777a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
778a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
779a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
780a3ab5120SLouis Dionne        >::value
781a3ab5120SLouis Dionne    , int> = 0>
782a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
783a3ab5120SLouis Dionne    explicit tuple(tuple<_Up...>&& __t)
784a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
785a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
786a3ab5120SLouis Dionne    { }
787a3ab5120SLouis Dionne
788*b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
789a3ab5120SLouis Dionne        _And<
790a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
791a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
792a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
793a3ab5120SLouis Dionne        >::value
794a3ab5120SLouis Dionne    , int> = 0>
795a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
796a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
797a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
798a3ab5120SLouis Dionne    { }
799a3ab5120SLouis Dionne
800*b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
801a3ab5120SLouis Dionne        _And<
802a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
803a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
804a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
805a3ab5120SLouis Dionne        >::value
806a3ab5120SLouis Dionne    , int> = 0>
807a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
808a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
809a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
810a3ab5120SLouis Dionne    { }
811a3ab5120SLouis Dionne
812a3ab5120SLouis Dionne    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
813a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
814a3ab5120SLouis Dionne    struct _EnableImplicitCopyFromPair : _And<
815a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
816a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
817a3ab5120SLouis Dionne        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
818a3ab5120SLouis Dionne        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
819a3ab5120SLouis Dionne    > { };
820a3ab5120SLouis Dionne
821a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
822a3ab5120SLouis Dionne    struct _EnableExplicitCopyFromPair : _And<
823a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
824a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
825a3ab5120SLouis Dionne        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
826a3ab5120SLouis Dionne        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
827a3ab5120SLouis Dionne    > { };
828a3ab5120SLouis Dionne
829*b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
830a3ab5120SLouis Dionne        _And<
831a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
832a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
833a3ab5120SLouis Dionne        >::value
834a3ab5120SLouis Dionne    , int> = 0>
835a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
836a3ab5120SLouis Dionne    tuple(const pair<_Up1, _Up2>& __p)
837a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
838a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
839a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
840a3ab5120SLouis Dionne        >::value))
841a3ab5120SLouis Dionne        : __base_(__p)
842a3ab5120SLouis Dionne    { }
843a3ab5120SLouis Dionne
844*b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
845a3ab5120SLouis Dionne        _And<
846a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
847a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
848a3ab5120SLouis Dionne        >::value
849a3ab5120SLouis Dionne    , int> = 0>
850a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
851a3ab5120SLouis Dionne    explicit tuple(const pair<_Up1, _Up2>& __p)
852a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
853a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
854a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
855a3ab5120SLouis Dionne        >::value))
856a3ab5120SLouis Dionne        : __base_(__p)
857a3ab5120SLouis Dionne    { }
858a3ab5120SLouis Dionne
859*b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
860a3ab5120SLouis Dionne        _And<
861a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
862a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
863a3ab5120SLouis Dionne        >::value
864a3ab5120SLouis Dionne    , int> = 0>
865a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
866a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
867a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
868a3ab5120SLouis Dionne    { }
869a3ab5120SLouis Dionne
870*b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
871a3ab5120SLouis Dionne        _And<
872a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
873a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
874a3ab5120SLouis Dionne        >::value
875a3ab5120SLouis Dionne    , int> = 0>
876a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
877a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
878a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
879a3ab5120SLouis Dionne    { }
880a3ab5120SLouis Dionne
881a3ab5120SLouis Dionne    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
882a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
883a3ab5120SLouis Dionne    struct _EnableImplicitMoveFromPair : _And<
884a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
885a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
886a3ab5120SLouis Dionne        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
887a3ab5120SLouis Dionne        is_convertible<_Up2, _SecondType<_DependentTp...> >
888a3ab5120SLouis Dionne    > { };
889a3ab5120SLouis Dionne
890a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
891a3ab5120SLouis Dionne    struct _EnableExplicitMoveFromPair : _And<
892a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
893a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
894a3ab5120SLouis Dionne        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
895a3ab5120SLouis Dionne        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
896a3ab5120SLouis Dionne    > { };
897a3ab5120SLouis Dionne
898*b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
899a3ab5120SLouis Dionne        _And<
900a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
901a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
902a3ab5120SLouis Dionne        >::value
903a3ab5120SLouis Dionne    , int> = 0>
904ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
905a3ab5120SLouis Dionne    tuple(pair<_Up1, _Up2>&& __p)
906a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
907a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
908a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
909a3ab5120SLouis Dionne        >::value))
910a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
911a3ab5120SLouis Dionne    { }
912a3ab5120SLouis Dionne
913*b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
914a3ab5120SLouis Dionne        _And<
915a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
916a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
917a3ab5120SLouis Dionne        >::value
918a3ab5120SLouis Dionne    , int> = 0>
919ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
920a3ab5120SLouis Dionne    explicit tuple(pair<_Up1, _Up2>&& __p)
921a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
922a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
923a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
924a3ab5120SLouis Dionne        >::value))
925a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
926a3ab5120SLouis Dionne    { }
927a3ab5120SLouis Dionne
928*b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
929a3ab5120SLouis Dionne        _And<
930a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
931a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
932a3ab5120SLouis Dionne        >::value
933a3ab5120SLouis Dionne    , int> = 0>
934a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
935a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
936a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
937a3ab5120SLouis Dionne    { }
938a3ab5120SLouis Dionne
939*b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
940a3ab5120SLouis Dionne        _And<
941a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
942a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
943a3ab5120SLouis Dionne        >::value
944a3ab5120SLouis Dionne    , int> = 0>
945a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
946a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
947a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
948a3ab5120SLouis Dionne    { }
9499795699aSEric Fiselier
950a0839b14SLouis Dionne    // [tuple.assign]
95106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
952a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
953a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
954aedcbf89SEric Fiselier    {
955a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
956a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
957aedcbf89SEric Fiselier        return *this;
958aedcbf89SEric Fiselier    }
959aedcbf89SEric Fiselier
96006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
961a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
962a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
963aedcbf89SEric Fiselier    {
964a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
965a0839b14SLouis Dionne            __tuple_types<_Tp...>(),
966a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
967aedcbf89SEric Fiselier        return *this;
968aedcbf89SEric Fiselier    }
969aedcbf89SEric Fiselier
970*b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
971a0839b14SLouis Dionne        _And<
972a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
973a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
974a0839b14SLouis Dionne        >::value
975a0839b14SLouis Dionne    ,int> = 0>
97606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
977a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...> const& __tuple)
978a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
9793e519524SHoward Hinnant    {
980a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
981a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9823e519524SHoward Hinnant        return *this;
9833e519524SHoward Hinnant    }
9843e519524SHoward Hinnant
985*b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
986a0839b14SLouis Dionne        _And<
987a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
988a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
989a0839b14SLouis Dionne        >::value
990a0839b14SLouis Dionne    ,int> = 0>
99106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
992a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...>&& __tuple)
993a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
994a0839b14SLouis Dionne    {
995a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
996a0839b14SLouis Dionne            __tuple_types<_Up...>(),
997a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
998a0839b14SLouis Dionne        return *this;
999a0839b14SLouis Dionne    }
1000a0839b14SLouis Dionne
1001*b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1002a0839b14SLouis Dionne        _And<_Dep,
1003a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1004a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1005a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1006a0839b14SLouis Dionne        >::value
1007a0839b14SLouis Dionne    ,int> = 0>
100806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1009a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1010a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1011a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1012a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1013a0839b14SLouis Dionne        >::value))
1014a0839b14SLouis Dionne    {
1015a0839b14SLouis Dionne        _VSTD::get<0>(*this) = __pair.first;
1016a0839b14SLouis Dionne        _VSTD::get<1>(*this) = __pair.second;
1017a0839b14SLouis Dionne        return *this;
1018a0839b14SLouis Dionne    }
1019a0839b14SLouis Dionne
1020*b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1021a0839b14SLouis Dionne        _And<_Dep,
1022a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1023a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1024a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1025a0839b14SLouis Dionne        >::value
1026a0839b14SLouis Dionne    ,int> = 0>
102706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1028a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1029a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1030a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1031a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1032a0839b14SLouis Dionne        >::value))
1033a0839b14SLouis Dionne    {
1034618862e8SLouis Dionne        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1035618862e8SLouis Dionne        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1036a0839b14SLouis Dionne        return *this;
1037a0839b14SLouis Dionne    }
1038a0839b14SLouis Dionne
1039a0839b14SLouis Dionne    // EXTENSION
1040*b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = __enable_if_t<
1041a0839b14SLouis Dionne        _And<
1042a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1043a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
1044a0839b14SLouis Dionne        >::value
1045a0839b14SLouis Dionne    > >
104606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1047a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np> const& __array)
1048a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1049a0839b14SLouis Dionne    {
1050a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __array,
1051a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1052a0839b14SLouis Dionne        return *this;
1053a0839b14SLouis Dionne    }
1054a0839b14SLouis Dionne
1055a0839b14SLouis Dionne    // EXTENSION
1056*b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1057a0839b14SLouis Dionne        _And<
1058a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1059a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
1060a0839b14SLouis Dionne        >::value
1061a0839b14SLouis Dionne    > >
106206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1063a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np>&& __array)
1064a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1065a0839b14SLouis Dionne    {
1066a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1067a0839b14SLouis Dionne            __tuple_types<_If<true, _Up, _Tp>...>(),
1068a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1069a0839b14SLouis Dionne        return *this;
1070a0839b14SLouis Dionne    }
1071a0839b14SLouis Dionne
1072a0839b14SLouis Dionne    // [tuple.swap]
107306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
107427d0a2a7SHoward Hinnant    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1075def3c375SEric Fiselier        {__base_.swap(__t.__base_);}
10763e519524SHoward Hinnant};
10773e519524SHoward Hinnant
10783e519524SHoward Hinnanttemplate <>
1079e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple<>
10803e519524SHoward Hinnant{
10813e519524SHoward Hinnantpublic:
108206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr
108306e2b737SArthur O'Dwyer        tuple() _NOEXCEPT = default;
10843e519524SHoward Hinnant    template <class _Alloc>
108506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10868a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
10873e519524SHoward Hinnant    template <class _Alloc>
108806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10898a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1090c003db1fSHoward Hinnant    template <class _Up>
109106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10928a9ee148SHoward Hinnant        tuple(array<_Up, 0>) _NOEXCEPT {}
1093c003db1fSHoward Hinnant    template <class _Alloc, class _Up>
109406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10958a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
109606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
109727d0a2a7SHoward Hinnant    void swap(tuple&) _NOEXCEPT {}
10983e519524SHoward Hinnant};
10993e519524SHoward Hinnant
110001666904SLouis Dionne#if _LIBCPP_STD_VER >= 17
11011308011eSLouis Dionnetemplate <class ..._Tp>
11021308011eSLouis Dionnetuple(_Tp...) -> tuple<_Tp...>;
11031308011eSLouis Dionnetemplate <class _Tp1, class _Tp2>
11041308011eSLouis Dionnetuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11051308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11061308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
11071308011eSLouis Dionnetemplate <class _Alloc, class _Tp1, class _Tp2>
11081308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11091308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11101308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1111baaee206SEric Fiselier#endif
1112baaee206SEric Fiselier
11133e519524SHoward Hinnanttemplate <class ..._Tp>
111406e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1115bc95cf0dSHoward Hinnanttypename enable_if
1116bc95cf0dSHoward Hinnant<
1117bc95cf0dSHoward Hinnant    __all<__is_swappable<_Tp>::value...>::value,
11183e519524SHoward Hinnant    void
1119bc95cf0dSHoward Hinnant>::type
112027d0a2a7SHoward Hinnantswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
112127d0a2a7SHoward Hinnant                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
112227d0a2a7SHoward Hinnant    {__t.swap(__u);}
11233e519524SHoward Hinnant
11243e519524SHoward Hinnant// get
11253e519524SHoward Hinnant
11263e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11278bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11283e519524SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&
1129c206366fSHoward Hinnantget(tuple<_Tp...>& __t) _NOEXCEPT
11303e519524SHoward Hinnant{
11313557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1132def3c375SEric Fiselier    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
11333e519524SHoward Hinnant}
11343e519524SHoward Hinnant
11353e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11368bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11373e519524SHoward Hinnantconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
1138c206366fSHoward Hinnantget(const tuple<_Tp...>& __t) _NOEXCEPT
11393e519524SHoward Hinnant{
11403557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1141def3c375SEric Fiselier    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
11423e519524SHoward Hinnant}
11433e519524SHoward Hinnant
1144601afb30SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11458bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1146601afb30SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&&
1147c206366fSHoward Hinnantget(tuple<_Tp...>&& __t) _NOEXCEPT
1148601afb30SHoward Hinnant{
11493557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11502a3f1bc1SHoward Hinnant    return static_cast<type&&>(
1151def3c375SEric Fiselier             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1152601afb30SHoward Hinnant}
1153601afb30SHoward Hinnant
1154545b8861SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
1155545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1156545b8861SEric Fiselierconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1157545b8861SEric Fiselierget(const tuple<_Tp...>&& __t) _NOEXCEPT
1158545b8861SEric Fiselier{
11593557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1160545b8861SEric Fiselier    return static_cast<const type&&>(
1161def3c375SEric Fiselier             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1162545b8861SEric Fiselier}
1163545b8861SEric Fiselier
1164e99520c7SMarshall Clow#if _LIBCPP_STD_VER > 11
1165e99520c7SMarshall Clow
1166f447e62eSEric Fiseliernamespace __find_detail {
1167f447e62eSEric Fiselier
1168f86570cdSLouis Dionnestatic constexpr size_t __not_found = static_cast<size_t>(-1);
1169f447e62eSEric Fiselierstatic constexpr size_t __ambiguous = __not_found - 1;
1170f447e62eSEric Fiselier
1171f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1172f447e62eSEric Fiselierconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1173f447e62eSEric Fiselier    return !__matches ? __res :
1174f447e62eSEric Fiselier        (__res == __not_found ? __curr_i : __ambiguous);
1175f447e62eSEric Fiselier}
1176f447e62eSEric Fiselier
1177f447e62eSEric Fiseliertemplate <size_t _Nx>
1178f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1179f447e62eSEric Fiselierconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1180f447e62eSEric Fiselier  return __i == _Nx ? __not_found :
1181f447e62eSEric Fiselier      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1182f447e62eSEric Fiselier}
1183f447e62eSEric Fiselier
1184f447e62eSEric Fiseliertemplate <class _T1, class ..._Args>
1185f447e62eSEric Fiselierstruct __find_exactly_one_checked {
118600c872f3SCasey Carter    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1187f447e62eSEric Fiselier    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1188f447e62eSEric Fiselier    static_assert(value != __not_found, "type not found in type list" );
1189f447e62eSEric Fiselier    static_assert(value != __ambiguous, "type occurs more than once in type list");
1190e99520c7SMarshall Clow};
1191e99520c7SMarshall Clow
11924f905b8dSEric Fiseliertemplate <class _T1>
11934f905b8dSEric Fiselierstruct __find_exactly_one_checked<_T1> {
11944f905b8dSEric Fiselier    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
11954f905b8dSEric Fiselier};
11964f905b8dSEric Fiselier
1197f447e62eSEric Fiselier} // namespace __find_detail;
1198e99520c7SMarshall Clow
1199e99520c7SMarshall Clowtemplate <typename _T1, typename... _Args>
1200f447e62eSEric Fiselierstruct __find_exactly_one_t
1201f447e62eSEric Fiselier    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1202e99520c7SMarshall Clow};
1203e99520c7SMarshall Clow
1204e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1205e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1206e99520c7SMarshall Clowconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
1207e99520c7SMarshall Clow{
1208e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1209e99520c7SMarshall Clow}
1210e99520c7SMarshall Clow
1211e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1212e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1213e99520c7SMarshall Clowconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1214e99520c7SMarshall Clow{
1215e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1216e99520c7SMarshall Clow}
1217e99520c7SMarshall Clow
1218e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1219e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1220e99520c7SMarshall Clowconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1221e99520c7SMarshall Clow{
12221c682f0fSMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1223e99520c7SMarshall Clow}
1224e99520c7SMarshall Clow
1225545b8861SEric Fiseliertemplate <class _T1, class... _Args>
1226545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1227545b8861SEric Fiselierconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1228545b8861SEric Fiselier{
1229545b8861SEric Fiselier    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1230545b8861SEric Fiselier}
1231545b8861SEric Fiselier
1232e99520c7SMarshall Clow#endif
1233e99520c7SMarshall Clow
12343e519524SHoward Hinnant// tie
12353e519524SHoward Hinnant
12363e519524SHoward Hinnanttemplate <class ..._Tp>
12370d1560e1SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12383e519524SHoward Hinnanttuple<_Tp&...>
12398a9ee148SHoward Hinnanttie(_Tp&... __t) _NOEXCEPT
12403e519524SHoward Hinnant{
12413e519524SHoward Hinnant    return tuple<_Tp&...>(__t...);
12423e519524SHoward Hinnant}
12433e519524SHoward Hinnant
12443e519524SHoward Hinnanttemplate <class _Up>
12453e519524SHoward Hinnantstruct __ignore_t
12463e519524SHoward Hinnant{
12473e519524SHoward Hinnant    template <class _Tp>
12489af60c4aSEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12493e519524SHoward Hinnant    const __ignore_t& operator=(_Tp&&) const {return *this;}
12503e519524SHoward Hinnant};
12513e519524SHoward Hinnant
12529af60c4aSEric Fiseliernamespace {
125340a01d53SMarshall Clow  _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
12549af60c4aSEric Fiselier}
12553e519524SHoward Hinnant
12563e519524SHoward Hinnanttemplate <class... _Tp>
125775eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1258bb9ca6d0SLouis Dionnetuple<typename __unwrap_ref_decay<_Tp>::type...>
12593e519524SHoward Hinnantmake_tuple(_Tp&&... __t)
12603e519524SHoward Hinnant{
1261bb9ca6d0SLouis Dionne    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
12623e519524SHoward Hinnant}
12633e519524SHoward Hinnant
12641102fbbdSHoward Hinnanttemplate <class... _Tp>
126575eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
126675eff748SMarshall Clowtuple<_Tp&&...>
12678a9ee148SHoward Hinnantforward_as_tuple(_Tp&&... __t) _NOEXCEPT
12681102fbbdSHoward Hinnant{
1269ce48a113SHoward Hinnant    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
12701102fbbdSHoward Hinnant}
12711102fbbdSHoward Hinnant
1272c003db1fSHoward Hinnanttemplate <size_t _Ip>
12733e519524SHoward Hinnantstruct __tuple_equal
12743e519524SHoward Hinnant{
12753e519524SHoward Hinnant    template <class _Tp, class _Up>
127675eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12773e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
12783e519524SHoward Hinnant    {
1279f9af6140SMarshall Clow        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
12803e519524SHoward Hinnant    }
12813e519524SHoward Hinnant};
12823e519524SHoward Hinnant
12833e519524SHoward Hinnanttemplate <>
12843e519524SHoward Hinnantstruct __tuple_equal<0>
12853e519524SHoward Hinnant{
12863e519524SHoward Hinnant    template <class _Tp, class _Up>
128775eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12883e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
12893e519524SHoward Hinnant    {
12903e519524SHoward Hinnant        return true;
12913e519524SHoward Hinnant    }
12923e519524SHoward Hinnant};
12933e519524SHoward Hinnant
12943e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
129575eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12963e519524SHoward Hinnantbool
12973e519524SHoward Hinnantoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
12983e519524SHoward Hinnant{
1299aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13003e519524SHoward Hinnant    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
13013e519524SHoward Hinnant}
13023e519524SHoward Hinnant
13033e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
130475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13053e519524SHoward Hinnantbool
13063e519524SHoward Hinnantoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13073e519524SHoward Hinnant{
13083e519524SHoward Hinnant    return !(__x == __y);
13093e519524SHoward Hinnant}
13103e519524SHoward Hinnant
1311c003db1fSHoward Hinnanttemplate <size_t _Ip>
13123e519524SHoward Hinnantstruct __tuple_less
13133e519524SHoward Hinnant{
13143e519524SHoward Hinnant    template <class _Tp, class _Up>
131575eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13163e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
13173e519524SHoward Hinnant    {
131853afae49SDuncan P. N. Exon Smith        const size_t __idx = tuple_size<_Tp>::value - _Ip;
131953afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
132053afae49SDuncan P. N. Exon Smith            return true;
132153afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
132253afae49SDuncan P. N. Exon Smith            return false;
132353afae49SDuncan P. N. Exon Smith        return __tuple_less<_Ip-1>()(__x, __y);
13243e519524SHoward Hinnant    }
13253e519524SHoward Hinnant};
13263e519524SHoward Hinnant
13273e519524SHoward Hinnanttemplate <>
13283e519524SHoward Hinnantstruct __tuple_less<0>
13293e519524SHoward Hinnant{
13303e519524SHoward Hinnant    template <class _Tp, class _Up>
133175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13323e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
13333e519524SHoward Hinnant    {
13343e519524SHoward Hinnant        return false;
13353e519524SHoward Hinnant    }
13363e519524SHoward Hinnant};
13373e519524SHoward Hinnant
13383e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
133975eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13403e519524SHoward Hinnantbool
13413e519524SHoward Hinnantoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13423e519524SHoward Hinnant{
1343aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13443e519524SHoward Hinnant    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
13453e519524SHoward Hinnant}
13463e519524SHoward Hinnant
13473e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
134875eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13493e519524SHoward Hinnantbool
13503e519524SHoward Hinnantoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13513e519524SHoward Hinnant{
13523e519524SHoward Hinnant    return __y < __x;
13533e519524SHoward Hinnant}
13543e519524SHoward Hinnant
13553e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
135675eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13573e519524SHoward Hinnantbool
13583e519524SHoward Hinnantoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13593e519524SHoward Hinnant{
13603e519524SHoward Hinnant    return !(__x < __y);
13613e519524SHoward Hinnant}
13623e519524SHoward Hinnant
13633e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
136475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13653e519524SHoward Hinnantbool
13663e519524SHoward Hinnantoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13673e519524SHoward Hinnant{
13683e519524SHoward Hinnant    return !(__y < __x);
13693e519524SHoward Hinnant}
13703e519524SHoward Hinnant
13713e519524SHoward Hinnant// tuple_cat
13723e519524SHoward Hinnant
13737f64810bSHoward Hinnanttemplate <class _Tp, class _Up> struct __tuple_cat_type;
13747f64810bSHoward Hinnant
13757f64810bSHoward Hinnanttemplate <class ..._Ttypes, class ..._Utypes>
13767f64810bSHoward Hinnantstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
13773e519524SHoward Hinnant{
13783557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
13797f64810bSHoward Hinnant};
13807f64810bSHoward Hinnant
13817f64810bSHoward Hinnanttemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
13827f64810bSHoward Hinnantstruct __tuple_cat_return_1
13837f64810bSHoward Hinnant{
13847f64810bSHoward Hinnant};
13857f64810bSHoward Hinnant
13867f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0>
13877f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
13887f64810bSHoward Hinnant{
13893557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename __tuple_cat_type<tuple<_Types...>,
13907e528bc4SEric Fiselier            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
13917f64810bSHoward Hinnant                                                                           type;
13927f64810bSHoward Hinnant};
13937f64810bSHoward Hinnant
13947f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
13957f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
13967f64810bSHoward Hinnant    : public __tuple_cat_return_1<
13977f64810bSHoward Hinnant                 typename __tuple_cat_type<
13987f64810bSHoward Hinnant                     tuple<_Types...>,
13997e528bc4SEric Fiselier                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
14007f64810bSHoward Hinnant                 >::type,
14017f64810bSHoward Hinnant                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
14027f64810bSHoward Hinnant                 _Tuple1, _Tuples...>
14037f64810bSHoward Hinnant{
14047f64810bSHoward Hinnant};
14057f64810bSHoward Hinnant
14067f64810bSHoward Hinnanttemplate <class ..._Tuples> struct __tuple_cat_return;
14077f64810bSHoward Hinnant
14087f64810bSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
14097f64810bSHoward Hinnantstruct __tuple_cat_return<_Tuple0, _Tuples...>
14107f64810bSHoward Hinnant    : public __tuple_cat_return_1<tuple<>,
14117f64810bSHoward Hinnant         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
14127f64810bSHoward Hinnant                                                                     _Tuples...>
14137f64810bSHoward Hinnant{
14147f64810bSHoward Hinnant};
14157f64810bSHoward Hinnant
14167f64810bSHoward Hinnanttemplate <>
14177f64810bSHoward Hinnantstruct __tuple_cat_return<>
14187f64810bSHoward Hinnant{
14193557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<> type;
14207f64810bSHoward Hinnant};
14217f64810bSHoward Hinnant
142275eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14237f64810bSHoward Hinnanttuple<>
14247f64810bSHoward Hinnanttuple_cat()
14257f64810bSHoward Hinnant{
14267f64810bSHoward Hinnant    return tuple<>();
14273e519524SHoward Hinnant}
14283e519524SHoward Hinnant
1429c003db1fSHoward Hinnanttemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1430ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp;
14313e519524SHoward Hinnant
1432ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1433ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
14343e519524SHoward Hinnant{
14353557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1436ba31cbdbSHoward Hinnant    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1437ba31cbdbSHoward Hinnant                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1438ba31cbdbSHoward Hinnant};
1439ba31cbdbSHoward Hinnant
1440ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1441ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1442ba31cbdbSHoward Hinnant                                  _Tuple0, _Tuple1, _Tuples...>
1443ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<
1444ba31cbdbSHoward Hinnant         tuple<_Types..., typename __apply_cv<_Tuple0,
1445ba31cbdbSHoward Hinnant               typename tuple_element<_I0,
1446ba31cbdbSHoward Hinnant                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1447ba31cbdbSHoward Hinnant         typename __make_tuple_indices<tuple_size<typename
1448ba31cbdbSHoward Hinnant                                 remove_reference<_Tuple1>::type>::value>::type,
1449ba31cbdbSHoward Hinnant         _Tuple1, _Tuples...>
1450ba31cbdbSHoward Hinnant{
1451ba31cbdbSHoward Hinnant};
1452ba31cbdbSHoward Hinnant
1453ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
1454ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref
1455ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<tuple<>,
1456ba31cbdbSHoward Hinnant               typename __make_tuple_indices<
1457ba31cbdbSHoward Hinnant                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1458ba31cbdbSHoward Hinnant               >::type, _Tuple0, _Tuples...>
1459ba31cbdbSHoward Hinnant{
1460ba31cbdbSHoward Hinnant};
1461ba31cbdbSHoward Hinnant
1462ba31cbdbSHoward Hinnanttemplate <class _Types, class _I0, class _J0>
1463ba31cbdbSHoward Hinnantstruct __tuple_cat;
1464ba31cbdbSHoward Hinnant
1465ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1466ba31cbdbSHoward Hinnantstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1467ba31cbdbSHoward Hinnant{
1468ba31cbdbSHoward Hinnant    template <class _Tuple0>
146975eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1470ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1471ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1472ba31cbdbSHoward Hinnant    {
1473e658b3ebSDavid Blaikie        return _VSTD::forward_as_tuple(
1474e658b3ebSDavid Blaikie            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1475f9af6140SMarshall Clow            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
14763e519524SHoward Hinnant    }
14773e519524SHoward Hinnant
14787f64810bSHoward Hinnant    template <class _Tuple0, class _Tuple1, class ..._Tuples>
147975eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1480ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1481ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
14823e519524SHoward Hinnant    {
14833557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
14843557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
1485ba31cbdbSHoward Hinnant        return __tuple_cat<
1486e658b3ebSDavid Blaikie            tuple<_Types...,
1487e658b3ebSDavid Blaikie                  typename __apply_cv<_Tuple0, typename tuple_element<
1488e658b3ebSDavid Blaikie                                                   _J0, _T0>::type>::type&&...>,
1489e658b3ebSDavid Blaikie            typename __make_tuple_indices<sizeof...(_Types) +
1490e658b3ebSDavid Blaikie                                          tuple_size<_T0>::value>::type,
1491e658b3ebSDavid Blaikie            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1492e658b3ebSDavid Blaikie            _VSTD::forward_as_tuple(
1493f9af6140SMarshall Clow                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1494e658b3ebSDavid Blaikie                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1495e658b3ebSDavid Blaikie            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1496ba31cbdbSHoward Hinnant    }
1497ba31cbdbSHoward Hinnant};
1498ba31cbdbSHoward Hinnant
1499ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class... _Tuples>
150075eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1501ba31cbdbSHoward Hinnanttypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1502ba31cbdbSHoward Hinnanttuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1503ba31cbdbSHoward Hinnant{
15043557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1505ba31cbdbSHoward Hinnant    return __tuple_cat<tuple<>, __tuple_indices<>,
1506ba31cbdbSHoward Hinnant                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1507ce48a113SHoward Hinnant                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1508ce48a113SHoward Hinnant                                            _VSTD::forward<_Tuples>(__tpls)...);
15093e519524SHoward Hinnant}
15103e519524SHoward Hinnant
15113e519524SHoward Hinnanttemplate <class ..._Tp, class _Alloc>
1512e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
15133e519524SHoward Hinnant    : true_type {};
15143e519524SHoward Hinnant
15153e519524SHoward Hinnanttemplate <class _T1, class _T2>
15163e519524SHoward Hinnanttemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1517737a4501SMichael Schellenberger Costainline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15183e519524SHoward Hinnantpair<_T1, _T2>::pair(piecewise_construct_t,
15193e519524SHoward Hinnant                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
15203e519524SHoward Hinnant                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1521f9af6140SMarshall Clow    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1522f9af6140SMarshall Clow      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
15233e519524SHoward Hinnant{
15243e519524SHoward Hinnant}
15253e519524SHoward Hinnant
152603e29a29SEric Fiselier#if _LIBCPP_STD_VER > 14
152703e29a29SEric Fiseliertemplate <class _Tp>
152840a01d53SMarshall Clow_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
152903e29a29SEric Fiselier
153003e29a29SEric Fiselier#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
153103e29a29SEric Fiselier
153203e29a29SEric Fiseliertemplate <class _Fn, class _Tuple, size_t ..._Id>
153303e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
153403e29a29SEric Fiselierconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
153503e29a29SEric Fiselier                                            __tuple_indices<_Id...>)
153603e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
153703e29a29SEric Fiselier    _VSTD::__invoke_constexpr(
153803e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f),
153903e29a29SEric Fiselier        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
154003e29a29SEric Fiselier)
154103e29a29SEric Fiselier
154203e29a29SEric Fiseliertemplate <class _Fn, class _Tuple>
154303e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
154403e29a29SEric Fiselierconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
154503e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
154603e29a29SEric Fiselier    _VSTD::__apply_tuple_impl(
154703e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1548655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
154903e29a29SEric Fiselier)
155003e29a29SEric Fiselier
155103e29a29SEric Fiseliertemplate <class _Tp, class _Tuple, size_t... _Idx>
155203e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
155303e29a29SEric Fiselierconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
155403e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
155503e29a29SEric Fiselier    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
155603e29a29SEric Fiselier)
155703e29a29SEric Fiselier
155803e29a29SEric Fiseliertemplate <class _Tp, class _Tuple>
155903e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
156003e29a29SEric Fiselierconstexpr _Tp make_from_tuple(_Tuple&& __t)
156103e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
156203e29a29SEric Fiselier    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1563655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
156403e29a29SEric Fiselier)
156503e29a29SEric Fiselier
156603e29a29SEric Fiselier#undef _LIBCPP_NOEXCEPT_RETURN
156703e29a29SEric Fiselier
156803e29a29SEric Fiselier#endif // _LIBCPP_STD_VER > 14
156903e29a29SEric Fiselier
157029870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
157129870871SEric Fiselier
15723e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
15733e519524SHoward Hinnant
15743e519524SHoward Hinnant#endif // _LIBCPP_TUPLE
1575