xref: /llvm-project-15.0.7/libcxx/include/tuple (revision b80f2dfd)
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
135*b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
136*b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
137*b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
138*b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
139*b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
140*b80f2dfdSKent Rosstemplate<class... T, class... U>
141*b80f2dfdSKent Ross  constexpr common_comparison_category_t<synth-three-way-result<T, U>...>
142*b80f2dfdSKent Ross    operator<=>(const tuple<T...>&, const tuple<U...>&);                                  // since C++20
1433e519524SHoward Hinnant
1443e519524SHoward Hinnanttemplate <class... Types, class Alloc>
1453e519524SHoward Hinnant  struct uses_allocator<tuple<Types...>, Alloc>;
1463e519524SHoward Hinnant
1473e519524SHoward Hinnanttemplate <class... Types>
14827d0a2a7SHoward Hinnant  void
14927d0a2a7SHoward Hinnant  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1503e519524SHoward Hinnant
1513e519524SHoward Hinnant}  // std
1523e519524SHoward Hinnant
1533e519524SHoward Hinnant*/
1543e519524SHoward Hinnant
155*b80f2dfdSKent Ross#include <__compare/common_comparison_category.h>
156*b80f2dfdSKent Ross#include <__compare/synth_three_way.h>
1573e519524SHoward Hinnant#include <__config>
15869d5a666SChristopher Di Bella#include <__functional/unwrap_ref.h>
159050b064fSChristopher Di Bella#include <__functional_base>
160050b064fSChristopher Di Bella#include <__memory/allocator_arg_t.h>
161050b064fSChristopher Di Bella#include <__memory/uses_allocator.h>
162050b064fSChristopher Di Bella#include <__tuple>
1636adbc83eSChristopher Di Bella#include <__utility/forward.h>
164*b80f2dfdSKent Ross#include <__utility/integer_sequence.h>
1656adbc83eSChristopher Di Bella#include <__utility/move.h>
1662d0f1fa4SArthur O'Dwyer#include <compare>
1673e519524SHoward Hinnant#include <cstddef>
1683e519524SHoward Hinnant#include <type_traits>
169a87b5e34SHoward Hinnant#include <utility>
170f56972e2SMarshall Clow#include <version>
1713e519524SHoward Hinnant
172073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1733e519524SHoward Hinnant#pragma GCC system_header
174073458b1SHoward Hinnant#endif
1753e519524SHoward Hinnant
1763e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1773e519524SHoward Hinnant
17829870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1793e519524SHoward Hinnant
18005c8dad2SMarshall Clow
1813e519524SHoward Hinnant// __tuple_leaf
1823e519524SHoward Hinnant
183ee187e24SEric Fiseliertemplate <size_t _Ip, class _Hp,
184ee187e24SEric Fiselier          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
18542b8bb50SHoward Hinnant         >
1863e519524SHoward Hinnantclass __tuple_leaf;
1873e519524SHoward Hinnant
1883e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool _Ep>
18906e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1903e519524SHoward Hinnantvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
19127d0a2a7SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
1923e519524SHoward Hinnant{
1933e519524SHoward Hinnant    swap(__x.get(), __y.get());
1943e519524SHoward Hinnant}
1953e519524SHoward Hinnant
1963e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool>
1973e519524SHoward Hinnantclass __tuple_leaf
1983e519524SHoward Hinnant{
199def3c375SEric Fiselier    _Hp __value_;
2003e519524SHoward Hinnant
201074f8d77SEric Fiselier    template <class _Tp>
202074f8d77SEric Fiselier    static constexpr bool __can_bind_reference() {
203292617e7SEric Fiselier#if __has_keyword(__reference_binds_to_temporary)
204292617e7SEric Fiselier      return !__reference_binds_to_temporary(_Hp, _Tp);
205b1539e0aSEric Fiselier#else
206b1539e0aSEric Fiselier      return true;
207292617e7SEric Fiselier#endif
208074f8d77SEric Fiselier    }
209074f8d77SEric Fiselier
21006e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2113e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2123e519524SHoward Hinnantpublic:
21306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
214def3c375SEric Fiselier             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2153e519524SHoward Hinnant       {static_assert(!is_reference<_Hp>::value,
2163e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2173e519524SHoward Hinnant
2183e519524SHoward Hinnant    template <class _Alloc>
21906e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2203e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
221def3c375SEric Fiselier            : __value_()
2223e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2233e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2243e519524SHoward Hinnant
2253e519524SHoward Hinnant    template <class _Alloc>
22606e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2273e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
228def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a)
2293e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2303e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2313e519524SHoward Hinnant
2323e519524SHoward Hinnant    template <class _Alloc>
23306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2343e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
235def3c375SEric Fiselier            : __value_(__a)
2363e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2373e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2383e519524SHoward Hinnant
23930ad985bSHoward Hinnant    template <class _Tp,
240b4e88d4dSLouis Dionne              class = __enable_if_t<
2413359a17bSEric Fiselier                  _And<
2423359a17bSEric Fiselier                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
2433359a17bSEric Fiselier                      is_constructible<_Hp, _Tp>
244567bb79bSEric Fiselier                    >::value
2453359a17bSEric Fiselier                >
246567bb79bSEric Fiselier            >
24775eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2488a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
249def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
250292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
251292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2523e519524SHoward Hinnant
2533e519524SHoward Hinnant    template <class _Tp, class _Alloc>
25406e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2553e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
256def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
257292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
258292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2593e519524SHoward Hinnant
2603e519524SHoward Hinnant    template <class _Tp, class _Alloc>
26106e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2623e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
263def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
264074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
265074f8d77SEric Fiselier            "Attempted to uses-allocator construct a reference element in a tuple");}
2663e519524SHoward Hinnant
2673e519524SHoward Hinnant    template <class _Tp, class _Alloc>
26806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2693e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
270def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t), __a)
271074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
272074f8d77SEric Fiselier           "Attempted to uses-allocator construct a reference element in a tuple");}
2733e519524SHoward Hinnant
2747546a111SMarshall Clow    __tuple_leaf(const __tuple_leaf& __t) = default;
2757546a111SMarshall Clow    __tuple_leaf(__tuple_leaf&& __t) = default;
2763e519524SHoward Hinnant
27706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
27827d0a2a7SHoward Hinnant    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
2793e519524SHoward Hinnant    {
280ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
2813e519524SHoward Hinnant        return 0;
2823e519524SHoward Hinnant    }
2833e519524SHoward Hinnant
284def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
285def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
2863e519524SHoward Hinnant};
2873e519524SHoward Hinnant
2883e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp>
2893e519524SHoward Hinnantclass __tuple_leaf<_Ip, _Hp, true>
2903e519524SHoward Hinnant    : private _Hp
2913e519524SHoward Hinnant{
29206e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2933e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2943e519524SHoward Hinnantpublic:
29506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
296a0f4c45cSHoward Hinnant             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
2973e519524SHoward Hinnant
2983e519524SHoward Hinnant    template <class _Alloc>
29906e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3003e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
3013e519524SHoward Hinnant
3023e519524SHoward Hinnant    template <class _Alloc>
30306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3043e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3053e519524SHoward Hinnant            : _Hp(allocator_arg_t(), __a) {}
3063e519524SHoward Hinnant
3073e519524SHoward Hinnant    template <class _Alloc>
30806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3093e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3103e519524SHoward Hinnant            : _Hp(__a) {}
3113e519524SHoward Hinnant
31230ad985bSHoward Hinnant    template <class _Tp,
313b4e88d4dSLouis Dionne              class = __enable_if_t<
3143359a17bSEric Fiselier                  _And<
3153359a17bSEric Fiselier                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3163359a17bSEric Fiselier                    is_constructible<_Hp, _Tp>
317567bb79bSEric Fiselier                  >::value
3183359a17bSEric Fiselier                >
319567bb79bSEric Fiselier            >
32075eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3218a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
322ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3233e519524SHoward Hinnant
3243e519524SHoward Hinnant    template <class _Tp, class _Alloc>
32506e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3263e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
327ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3283e519524SHoward Hinnant
3293e519524SHoward Hinnant    template <class _Tp, class _Alloc>
33006e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3313e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
332ce48a113SHoward Hinnant            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3333e519524SHoward Hinnant
3343e519524SHoward Hinnant    template <class _Tp, class _Alloc>
33506e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3363e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
337ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3383e519524SHoward Hinnant
339567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf const &) = default;
340567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf &&) = default;
341567bb79bSEric Fiselier
34206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
34327d0a2a7SHoward Hinnant    int
34427d0a2a7SHoward Hinnant    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3453e519524SHoward Hinnant    {
346ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
3473e519524SHoward Hinnant        return 0;
3483e519524SHoward Hinnant    }
3493e519524SHoward Hinnant
35075eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
35175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3523e519524SHoward Hinnant};
3533e519524SHoward Hinnant
354789847ddSHoward Hinnanttemplate <class ..._Tp>
35506e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3568a9ee148SHoward Hinnantvoid __swallow(_Tp&&...) _NOEXCEPT {}
3573e519524SHoward Hinnant
35814c5ec51SMarshall Clowtemplate <class _Tp>
35914c5ec51SMarshall Clowstruct __all_default_constructible;
36027d0a2a7SHoward Hinnant
36114c5ec51SMarshall Clowtemplate <class ..._Tp>
36214c5ec51SMarshall Clowstruct __all_default_constructible<__tuple_types<_Tp...>>
36314c5ec51SMarshall Clow    : __all<is_default_constructible<_Tp>::value...>
36414c5ec51SMarshall Clow{ };
36527d0a2a7SHoward Hinnant
3663e519524SHoward Hinnant// __tuple_impl
3673e519524SHoward Hinnant
3683e519524SHoward Hinnanttemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3693e519524SHoward Hinnant
3703e519524SHoward Hinnanttemplate<size_t ..._Indx, class ..._Tp>
371b43f17c8SEric Fiselierstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3723e519524SHoward Hinnant    : public __tuple_leaf<_Indx, _Tp>...
3733e519524SHoward Hinnant{
374a62ebe04SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
37506e2b737SArthur O'Dwyer    constexpr __tuple_impl()
376a0f4c45cSHoward Hinnant        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
377a62ebe04SHoward Hinnant
3783e519524SHoward Hinnant    template <size_t ..._Uf, class ..._Tf,
3793e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
38075eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3813e519524SHoward Hinnant        explicit
3823e519524SHoward Hinnant        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3833e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3848a9ee148SHoward Hinnant                     _Up&&... __u)
3858a9ee148SHoward Hinnant                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
3868a9ee148SHoward Hinnant                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
387ce48a113SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
3883e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>()...
3893e519524SHoward Hinnant            {}
3903e519524SHoward Hinnant
3913e519524SHoward Hinnant    template <class _Alloc, size_t ..._Uf, class ..._Tf,
3923e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
39306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3943e519524SHoward Hinnant        explicit
3953e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a,
3963e519524SHoward Hinnant                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3973e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3983e519524SHoward Hinnant                     _Up&&... __u) :
3993e519524SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
400ce48a113SHoward Hinnant            _VSTD::forward<_Up>(__u))...,
4013e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
4023e519524SHoward Hinnant            {}
4033e519524SHoward Hinnant
4043e519524SHoward Hinnant    template <class _Tuple,
4053e519524SHoward Hinnant              class = typename enable_if
4063e519524SHoward Hinnant                      <
407f3b02b17SHoward Hinnant                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4083e519524SHoward Hinnant                      >::type
4093e519524SHoward Hinnant             >
41075eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4118a9ee148SHoward Hinnant        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4128a9ee148SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
413ce48a113SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
414ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4153e519524SHoward Hinnant            {}
4163e519524SHoward Hinnant
4173e519524SHoward Hinnant    template <class _Alloc, class _Tuple,
4183e519524SHoward Hinnant              class = typename enable_if
4193e519524SHoward Hinnant                      <
4209795699aSEric Fiselier                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4213e519524SHoward Hinnant                      >::type
4223e519524SHoward Hinnant             >
42306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4243e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4253e519524SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4263e519524SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
427ce48a113SHoward Hinnant                                       _VSTD::forward<typename tuple_element<_Indx,
428ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4293e519524SHoward Hinnant            {}
4303e519524SHoward Hinnant
4314478b25aSHoward Hinnant    __tuple_impl(const __tuple_impl&) = default;
4324478b25aSHoward Hinnant    __tuple_impl(__tuple_impl&&) = default;
4334478b25aSHoward Hinnant
43406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4353e519524SHoward Hinnant    void swap(__tuple_impl& __t)
43627d0a2a7SHoward Hinnant        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4373e519524SHoward Hinnant    {
438a0839b14SLouis Dionne        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4393e519524SHoward Hinnant    }
4403e519524SHoward Hinnant};
4413e519524SHoward Hinnant
442a0839b14SLouis Dionnetemplate<class _Dest, class _Source, size_t ..._Np>
44306e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444a0839b14SLouis Dionnevoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
445a0839b14SLouis Dionne    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
446a0839b14SLouis Dionne}
44774cba642SEric Fiselier
448a0839b14SLouis Dionnetemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
44906e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
450a0839b14SLouis Dionnevoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
451a0839b14SLouis Dionne    _VSTD::__swallow(((
452618862e8SLouis Dionne        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
453a0839b14SLouis Dionne    ), void(), 0)...);
454a0839b14SLouis Dionne}
45574cba642SEric Fiselier
4563e519524SHoward Hinnanttemplate <class ..._Tp>
457e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple
4583e519524SHoward Hinnant{
459def3c375SEric Fiselier    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4603e519524SHoward Hinnant
461def3c375SEric Fiselier    _BaseT __base_;
4623e519524SHoward Hinnant
4638bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
464c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
4658bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
466c206366fSHoward Hinnant        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
4678bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
468c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
469545b8861SEric Fiselier    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
470545b8861SEric Fiselier        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
4713e519524SHoward Hinnantpublic:
472a3ab5120SLouis Dionne    // [tuple.cnstr]
4733e519524SHoward Hinnant
474a3ab5120SLouis Dionne    // tuple() constructors (including allocator_arg_t variants)
475b4e88d4dSLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
476a3ab5120SLouis Dionne        _And<
477a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
478a3ab5120SLouis Dionne        >::value
479a3ab5120SLouis Dionne    , int> = 0>
480ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
481e16f2cb6SLouis Dionne    tuple()
482a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
483a3ab5120SLouis Dionne    { }
484e16f2cb6SLouis Dionne
485a3ab5120SLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
486b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
487a3ab5120SLouis Dionne        _And<
488a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
489a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
490a3ab5120SLouis Dionne        >::value
491a3ab5120SLouis Dionne    , int> = 0>
492a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
493a3ab5120SLouis Dionne    explicit tuple()
494a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
495a3ab5120SLouis Dionne    { }
496a62ebe04SHoward Hinnant
497b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
498a3ab5120SLouis Dionne        _And<
499a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
500a3ab5120SLouis Dionne        >::value
501a3ab5120SLouis Dionne    , int> = 0>
502a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
503a3ab5120SLouis Dionne    tuple(allocator_arg_t, _Alloc const& __a)
504a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
505a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
506a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
507a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
508a3ab5120SLouis Dionne
509a3ab5120SLouis Dionne    template <class _Alloc,
510a3ab5120SLouis Dionne              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
511b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
512a3ab5120SLouis Dionne        _And<
513a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
514a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
515a3ab5120SLouis Dionne        >::value
516a3ab5120SLouis Dionne    , int> = 0>
517a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
518a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, _Alloc const& __a)
519a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
520a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
521a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
522a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
523a3ab5120SLouis Dionne
524a3ab5120SLouis Dionne    // tuple(const T&...) constructors (including allocator_arg_t variants)
525b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
526a3ab5120SLouis Dionne        _And<
527a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
528a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
529a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
530a3ab5120SLouis Dionne        >::value
531a3ab5120SLouis Dionne    , int> = 0>
532a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
533a3ab5120SLouis Dionne    tuple(const _Tp& ... __t)
534a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
535a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
536a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
537a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
538a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
539a3ab5120SLouis Dionne                __t...
540a3ab5120SLouis Dionne               ) {}
541a3ab5120SLouis Dionne
542b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
543a3ab5120SLouis Dionne        _And<
544a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
545a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
546a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
547a3ab5120SLouis Dionne        >::value
548a3ab5120SLouis Dionne    , int> = 0>
549a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
550a3ab5120SLouis Dionne    explicit tuple(const _Tp& ... __t)
551a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
552a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
553a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
554a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
555a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
556a3ab5120SLouis Dionne                __t...
557a3ab5120SLouis Dionne               ) {}
558a3ab5120SLouis Dionne
559b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
560a3ab5120SLouis Dionne        _And<
561a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
562a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
563a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
564a3ab5120SLouis Dionne        >::value
565a3ab5120SLouis Dionne    , int> = 0>
566a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
567a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
568a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
569a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
570a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
571a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
572a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
573a3ab5120SLouis Dionne                __t...
574a3ab5120SLouis Dionne               ) {}
575a3ab5120SLouis Dionne
576b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
577a3ab5120SLouis Dionne        _And<
578a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
579a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
580a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
581a3ab5120SLouis Dionne        >::value
582a3ab5120SLouis Dionne    , int> = 0>
583a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
584a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
585a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
586a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
587a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
588a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
589a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
590a3ab5120SLouis Dionne                __t...
591a3ab5120SLouis Dionne               ) {}
592a3ab5120SLouis Dionne
593a3ab5120SLouis Dionne    // tuple(U&& ...) constructors (including allocator_arg_t variants)
594a3ab5120SLouis Dionne    template <class ..._Up> struct _IsThisTuple : false_type { };
595a3ab5120SLouis Dionne    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
596a3ab5120SLouis Dionne
597a3ab5120SLouis Dionne    template <class ..._Up>
598a3ab5120SLouis Dionne    struct _EnableUTypesCtor : _And<
599a3ab5120SLouis Dionne        _BoolConstant<sizeof...(_Tp) >= 1>,
600a3ab5120SLouis Dionne        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
601a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
602a3ab5120SLouis Dionne    > { };
603a3ab5120SLouis Dionne
604b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
605a3ab5120SLouis Dionne        _And<
606a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
607a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
608a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
609a3ab5120SLouis Dionne        >::value
610a3ab5120SLouis Dionne    , int> = 0>
611a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
612a3ab5120SLouis Dionne    tuple(_Up&&... __u)
613a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
614a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
615a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
616a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
617a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
618a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
619a3ab5120SLouis Dionne
620b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
621a3ab5120SLouis Dionne        _And<
622a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
623a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
624a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
625a3ab5120SLouis Dionne        >::value
626a3ab5120SLouis Dionne    , int> = 0>
627a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
628a3ab5120SLouis Dionne    explicit tuple(_Up&&... __u)
629a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
630a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
631a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
632a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
633a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
634a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
635a3ab5120SLouis Dionne
636b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
637a3ab5120SLouis Dionne        _And<
638a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
639a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
640a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
641a3ab5120SLouis Dionne        >::value
642a3ab5120SLouis Dionne    , int> = 0>
643a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
644a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
645a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
646a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
647a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
648a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
649a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
650a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
651a3ab5120SLouis Dionne
652b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
653a3ab5120SLouis Dionne        _And<
654a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
655a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
656a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
657a3ab5120SLouis Dionne        >::value
658a3ab5120SLouis Dionne    , int> = 0>
659a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
660a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
661a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
662a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
663a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
664a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
665a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
666a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
667a3ab5120SLouis Dionne
668a3ab5120SLouis Dionne    // Copy and move constructors (including the allocator_arg_t variants)
669a3ab5120SLouis Dionne    tuple(const tuple&) = default;
670aedcbf89SEric Fiselier    tuple(tuple&&) = default;
671aedcbf89SEric Fiselier
672b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
673a3ab5120SLouis Dionne        _And<is_copy_constructible<_Tp>...>::value
674a3ab5120SLouis Dionne    , int> = 0>
675a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
676a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, __t)
677a3ab5120SLouis Dionne    { }
67890fb2bafSEric Fiselier
679b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
680a3ab5120SLouis Dionne        _And<is_move_constructible<_Tp>...>::value
681a3ab5120SLouis Dionne    , int> = 0>
682a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
683a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
684a3ab5120SLouis Dionne    { }
68559e26308SLouis Dionne
686a3ab5120SLouis Dionne    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
687a3ab5120SLouis Dionne    template <class ..._Up>
688a3ab5120SLouis Dionne    struct _EnableCopyFromOtherTuple : _And<
68917f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
69017f2d1cbSLouis Dionne        _Lazy<_Or,
691a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
692a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
693a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
694a3ab5120SLouis Dionne            _Lazy<_And,
695a3ab5120SLouis Dionne                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
696a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
6979795699aSEric Fiselier            >
698a3ab5120SLouis Dionne        >,
699a3ab5120SLouis Dionne        is_constructible<_Tp, const _Up&>...
700a3ab5120SLouis Dionne    > { };
7019795699aSEric Fiselier
702b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
703a3ab5120SLouis Dionne        _And<
704a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
705a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
706a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
7078a9ee148SHoward Hinnant        >::value
708a3ab5120SLouis Dionne    , int> = 0>
70975eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
710a3ab5120SLouis Dionne    tuple(const tuple<_Up...>& __t)
711a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
712a3ab5120SLouis Dionne        : __base_(__t)
713a3ab5120SLouis Dionne    { }
714a3ab5120SLouis Dionne
715b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
716a3ab5120SLouis Dionne        _And<
717a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
718a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
719a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
7208a9ee148SHoward Hinnant        >::value
721a3ab5120SLouis Dionne    , int> = 0>
72275eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
723a3ab5120SLouis Dionne    explicit tuple(const tuple<_Up...>& __t)
724a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
725a3ab5120SLouis Dionne        : __base_(__t)
726a3ab5120SLouis Dionne    { }
7273e519524SHoward Hinnant
728b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
729a3ab5120SLouis Dionne        _And<
730a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
731a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
732a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
733a3ab5120SLouis Dionne        >::value
734a3ab5120SLouis Dionne    , int> = 0>
73506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
736a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
737a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
738a3ab5120SLouis Dionne    { }
7393e519524SHoward Hinnant
740b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
741a3ab5120SLouis Dionne        _And<
742a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
743a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
744a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
745a3ab5120SLouis Dionne        >::value
746a3ab5120SLouis Dionne    , int> = 0>
74706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
748a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
749a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
750a3ab5120SLouis Dionne    { }
751a3ab5120SLouis Dionne
752a3ab5120SLouis Dionne    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
753a3ab5120SLouis Dionne    template <class ..._Up>
754a3ab5120SLouis Dionne    struct _EnableMoveFromOtherTuple : _And<
75517f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
75617f2d1cbSLouis Dionne        _Lazy<_Or,
757a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
758a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
759a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
760a3ab5120SLouis Dionne            _Lazy<_And,
761a3ab5120SLouis Dionne                _Not<is_convertible<tuple<_Up>, _Tp> >...,
762a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, tuple<_Up> > >...
763a3ab5120SLouis Dionne            >
764a3ab5120SLouis Dionne        >,
765a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
766a3ab5120SLouis Dionne    > { };
767a3ab5120SLouis Dionne
768b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
769a3ab5120SLouis Dionne        _And<
770a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
771a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
772a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
773a3ab5120SLouis Dionne        >::value
774a3ab5120SLouis Dionne    , int> = 0>
775a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
776a3ab5120SLouis Dionne    tuple(tuple<_Up...>&& __t)
777a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
778a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
779a3ab5120SLouis Dionne    { }
780a3ab5120SLouis Dionne
781b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
782a3ab5120SLouis Dionne        _And<
783a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
784a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
785a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
786a3ab5120SLouis Dionne        >::value
787a3ab5120SLouis Dionne    , int> = 0>
788a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
789a3ab5120SLouis Dionne    explicit tuple(tuple<_Up...>&& __t)
790a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
791a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
792a3ab5120SLouis Dionne    { }
793a3ab5120SLouis Dionne
794b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
795a3ab5120SLouis Dionne        _And<
796a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
797a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
798a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
799a3ab5120SLouis Dionne        >::value
800a3ab5120SLouis Dionne    , int> = 0>
801a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
802a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
803a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
804a3ab5120SLouis Dionne    { }
805a3ab5120SLouis Dionne
806b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
807a3ab5120SLouis Dionne        _And<
808a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
809a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
810a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
811a3ab5120SLouis Dionne        >::value
812a3ab5120SLouis Dionne    , int> = 0>
813a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
814a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
815a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
816a3ab5120SLouis Dionne    { }
817a3ab5120SLouis Dionne
818a3ab5120SLouis Dionne    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
819a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
820a3ab5120SLouis Dionne    struct _EnableImplicitCopyFromPair : _And<
821a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
822a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
823a3ab5120SLouis Dionne        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
824a3ab5120SLouis Dionne        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
825a3ab5120SLouis Dionne    > { };
826a3ab5120SLouis Dionne
827a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
828a3ab5120SLouis Dionne    struct _EnableExplicitCopyFromPair : _And<
829a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
830a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
831a3ab5120SLouis Dionne        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
832a3ab5120SLouis Dionne        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
833a3ab5120SLouis Dionne    > { };
834a3ab5120SLouis Dionne
835b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
836a3ab5120SLouis Dionne        _And<
837a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
838a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
839a3ab5120SLouis Dionne        >::value
840a3ab5120SLouis Dionne    , int> = 0>
841a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
842a3ab5120SLouis Dionne    tuple(const pair<_Up1, _Up2>& __p)
843a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
844a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
845a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
846a3ab5120SLouis Dionne        >::value))
847a3ab5120SLouis Dionne        : __base_(__p)
848a3ab5120SLouis Dionne    { }
849a3ab5120SLouis Dionne
850b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
851a3ab5120SLouis Dionne        _And<
852a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
853a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
854a3ab5120SLouis Dionne        >::value
855a3ab5120SLouis Dionne    , int> = 0>
856a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
857a3ab5120SLouis Dionne    explicit tuple(const pair<_Up1, _Up2>& __p)
858a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
859a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
860a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
861a3ab5120SLouis Dionne        >::value))
862a3ab5120SLouis Dionne        : __base_(__p)
863a3ab5120SLouis Dionne    { }
864a3ab5120SLouis Dionne
865b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
866a3ab5120SLouis Dionne        _And<
867a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
868a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
869a3ab5120SLouis Dionne        >::value
870a3ab5120SLouis Dionne    , int> = 0>
871a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
872a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
873a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
874a3ab5120SLouis Dionne    { }
875a3ab5120SLouis Dionne
876b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
877a3ab5120SLouis Dionne        _And<
878a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
879a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
880a3ab5120SLouis Dionne        >::value
881a3ab5120SLouis Dionne    , int> = 0>
882a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
883a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
884a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
885a3ab5120SLouis Dionne    { }
886a3ab5120SLouis Dionne
887a3ab5120SLouis Dionne    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
888a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
889a3ab5120SLouis Dionne    struct _EnableImplicitMoveFromPair : _And<
890a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
891a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
892a3ab5120SLouis Dionne        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
893a3ab5120SLouis Dionne        is_convertible<_Up2, _SecondType<_DependentTp...> >
894a3ab5120SLouis Dionne    > { };
895a3ab5120SLouis Dionne
896a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
897a3ab5120SLouis Dionne    struct _EnableExplicitMoveFromPair : _And<
898a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
899a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
900a3ab5120SLouis Dionne        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
901a3ab5120SLouis Dionne        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
902a3ab5120SLouis Dionne    > { };
903a3ab5120SLouis Dionne
904b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
905a3ab5120SLouis Dionne        _And<
906a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
907a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
908a3ab5120SLouis Dionne        >::value
909a3ab5120SLouis Dionne    , int> = 0>
910ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
911a3ab5120SLouis Dionne    tuple(pair<_Up1, _Up2>&& __p)
912a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
913a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
914a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
915a3ab5120SLouis Dionne        >::value))
916a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
917a3ab5120SLouis Dionne    { }
918a3ab5120SLouis Dionne
919b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
920a3ab5120SLouis Dionne        _And<
921a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
922a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
923a3ab5120SLouis Dionne        >::value
924a3ab5120SLouis Dionne    , int> = 0>
925ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
926a3ab5120SLouis Dionne    explicit tuple(pair<_Up1, _Up2>&& __p)
927a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
928a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
929a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
930a3ab5120SLouis Dionne        >::value))
931a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
932a3ab5120SLouis Dionne    { }
933a3ab5120SLouis Dionne
934b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
935a3ab5120SLouis Dionne        _And<
936a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
937a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
938a3ab5120SLouis Dionne        >::value
939a3ab5120SLouis Dionne    , int> = 0>
940a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
941a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
942a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
943a3ab5120SLouis Dionne    { }
944a3ab5120SLouis Dionne
945b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
946a3ab5120SLouis Dionne        _And<
947a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
948a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
949a3ab5120SLouis Dionne        >::value
950a3ab5120SLouis Dionne    , int> = 0>
951a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
952a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
953a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
954a3ab5120SLouis Dionne    { }
9559795699aSEric Fiselier
956a0839b14SLouis Dionne    // [tuple.assign]
95706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
958a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
959a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
960aedcbf89SEric Fiselier    {
961a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
962a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
963aedcbf89SEric Fiselier        return *this;
964aedcbf89SEric Fiselier    }
965aedcbf89SEric Fiselier
96606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
967a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
968a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
969aedcbf89SEric Fiselier    {
970a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
971a0839b14SLouis Dionne            __tuple_types<_Tp...>(),
972a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
973aedcbf89SEric Fiselier        return *this;
974aedcbf89SEric Fiselier    }
975aedcbf89SEric Fiselier
976b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
977a0839b14SLouis Dionne        _And<
978a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
979a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
980a0839b14SLouis Dionne        >::value
981a0839b14SLouis Dionne    ,int> = 0>
98206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
983a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...> const& __tuple)
984a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
9853e519524SHoward Hinnant    {
986a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
987a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9883e519524SHoward Hinnant        return *this;
9893e519524SHoward Hinnant    }
9903e519524SHoward Hinnant
991b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
992a0839b14SLouis Dionne        _And<
993a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
994a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
995a0839b14SLouis Dionne        >::value
996a0839b14SLouis Dionne    ,int> = 0>
99706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
998a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...>&& __tuple)
999a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1000a0839b14SLouis Dionne    {
1001a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1002a0839b14SLouis Dionne            __tuple_types<_Up...>(),
1003a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1004a0839b14SLouis Dionne        return *this;
1005a0839b14SLouis Dionne    }
1006a0839b14SLouis Dionne
1007b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1008a0839b14SLouis Dionne        _And<_Dep,
1009a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1010a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1011a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1012a0839b14SLouis Dionne        >::value
1013a0839b14SLouis Dionne    ,int> = 0>
101406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1015a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1016a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1017a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1018a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1019a0839b14SLouis Dionne        >::value))
1020a0839b14SLouis Dionne    {
1021a0839b14SLouis Dionne        _VSTD::get<0>(*this) = __pair.first;
1022a0839b14SLouis Dionne        _VSTD::get<1>(*this) = __pair.second;
1023a0839b14SLouis Dionne        return *this;
1024a0839b14SLouis Dionne    }
1025a0839b14SLouis Dionne
1026b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1027a0839b14SLouis Dionne        _And<_Dep,
1028a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1029a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1030a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1031a0839b14SLouis Dionne        >::value
1032a0839b14SLouis Dionne    ,int> = 0>
103306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1034a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1035a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1036a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1037a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1038a0839b14SLouis Dionne        >::value))
1039a0839b14SLouis Dionne    {
1040618862e8SLouis Dionne        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1041618862e8SLouis Dionne        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1042a0839b14SLouis Dionne        return *this;
1043a0839b14SLouis Dionne    }
1044a0839b14SLouis Dionne
1045a0839b14SLouis Dionne    // EXTENSION
1046b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = __enable_if_t<
1047a0839b14SLouis Dionne        _And<
1048a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1049a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
1050a0839b14SLouis Dionne        >::value
1051a0839b14SLouis Dionne    > >
105206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1053a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np> const& __array)
1054a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1055a0839b14SLouis Dionne    {
1056a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __array,
1057a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1058a0839b14SLouis Dionne        return *this;
1059a0839b14SLouis Dionne    }
1060a0839b14SLouis Dionne
1061a0839b14SLouis Dionne    // EXTENSION
1062b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1063a0839b14SLouis Dionne        _And<
1064a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1065a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
1066a0839b14SLouis Dionne        >::value
1067a0839b14SLouis Dionne    > >
106806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1069a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np>&& __array)
1070a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1071a0839b14SLouis Dionne    {
1072a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1073a0839b14SLouis Dionne            __tuple_types<_If<true, _Up, _Tp>...>(),
1074a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1075a0839b14SLouis Dionne        return *this;
1076a0839b14SLouis Dionne    }
1077a0839b14SLouis Dionne
1078a0839b14SLouis Dionne    // [tuple.swap]
107906e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
108027d0a2a7SHoward Hinnant    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1081def3c375SEric Fiselier        {__base_.swap(__t.__base_);}
10823e519524SHoward Hinnant};
10833e519524SHoward Hinnant
10843e519524SHoward Hinnanttemplate <>
1085e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple<>
10863e519524SHoward Hinnant{
10873e519524SHoward Hinnantpublic:
108806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr
108906e2b737SArthur O'Dwyer        tuple() _NOEXCEPT = default;
10903e519524SHoward Hinnant    template <class _Alloc>
109106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10928a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
10933e519524SHoward Hinnant    template <class _Alloc>
109406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10958a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1096c003db1fSHoward Hinnant    template <class _Up>
109706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10988a9ee148SHoward Hinnant        tuple(array<_Up, 0>) _NOEXCEPT {}
1099c003db1fSHoward Hinnant    template <class _Alloc, class _Up>
110006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11018a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
110206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
110327d0a2a7SHoward Hinnant    void swap(tuple&) _NOEXCEPT {}
11043e519524SHoward Hinnant};
11053e519524SHoward Hinnant
110601666904SLouis Dionne#if _LIBCPP_STD_VER >= 17
11071308011eSLouis Dionnetemplate <class ..._Tp>
11081308011eSLouis Dionnetuple(_Tp...) -> tuple<_Tp...>;
11091308011eSLouis Dionnetemplate <class _Tp1, class _Tp2>
11101308011eSLouis Dionnetuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11111308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11121308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
11131308011eSLouis Dionnetemplate <class _Alloc, class _Tp1, class _Tp2>
11141308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11151308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11161308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1117baaee206SEric Fiselier#endif
1118baaee206SEric Fiselier
11193e519524SHoward Hinnanttemplate <class ..._Tp>
112006e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1121bc95cf0dSHoward Hinnanttypename enable_if
1122bc95cf0dSHoward Hinnant<
1123bc95cf0dSHoward Hinnant    __all<__is_swappable<_Tp>::value...>::value,
11243e519524SHoward Hinnant    void
1125bc95cf0dSHoward Hinnant>::type
112627d0a2a7SHoward Hinnantswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
112727d0a2a7SHoward Hinnant                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
112827d0a2a7SHoward Hinnant    {__t.swap(__u);}
11293e519524SHoward Hinnant
11303e519524SHoward Hinnant// get
11313e519524SHoward Hinnant
11323e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11338bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11343e519524SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&
1135c206366fSHoward Hinnantget(tuple<_Tp...>& __t) _NOEXCEPT
11363e519524SHoward Hinnant{
11373557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1138def3c375SEric Fiselier    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
11393e519524SHoward Hinnant}
11403e519524SHoward Hinnant
11413e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11428bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11433e519524SHoward Hinnantconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
1144c206366fSHoward Hinnantget(const tuple<_Tp...>& __t) _NOEXCEPT
11453e519524SHoward Hinnant{
11463557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1147def3c375SEric Fiselier    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
11483e519524SHoward Hinnant}
11493e519524SHoward Hinnant
1150601afb30SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11518bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1152601afb30SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&&
1153c206366fSHoward Hinnantget(tuple<_Tp...>&& __t) _NOEXCEPT
1154601afb30SHoward Hinnant{
11553557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11562a3f1bc1SHoward Hinnant    return static_cast<type&&>(
1157def3c375SEric Fiselier             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1158601afb30SHoward Hinnant}
1159601afb30SHoward Hinnant
1160545b8861SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
1161545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1162545b8861SEric Fiselierconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1163545b8861SEric Fiselierget(const tuple<_Tp...>&& __t) _NOEXCEPT
1164545b8861SEric Fiselier{
11653557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1166545b8861SEric Fiselier    return static_cast<const type&&>(
1167def3c375SEric Fiselier             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1168545b8861SEric Fiselier}
1169545b8861SEric Fiselier
1170e99520c7SMarshall Clow#if _LIBCPP_STD_VER > 11
1171e99520c7SMarshall Clow
1172f447e62eSEric Fiseliernamespace __find_detail {
1173f447e62eSEric Fiselier
1174f86570cdSLouis Dionnestatic constexpr size_t __not_found = static_cast<size_t>(-1);
1175f447e62eSEric Fiselierstatic constexpr size_t __ambiguous = __not_found - 1;
1176f447e62eSEric Fiselier
1177f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1178f447e62eSEric Fiselierconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1179f447e62eSEric Fiselier    return !__matches ? __res :
1180f447e62eSEric Fiselier        (__res == __not_found ? __curr_i : __ambiguous);
1181f447e62eSEric Fiselier}
1182f447e62eSEric Fiselier
1183f447e62eSEric Fiseliertemplate <size_t _Nx>
1184f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1185f447e62eSEric Fiselierconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1186f447e62eSEric Fiselier  return __i == _Nx ? __not_found :
1187f447e62eSEric Fiselier      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1188f447e62eSEric Fiselier}
1189f447e62eSEric Fiselier
1190f447e62eSEric Fiseliertemplate <class _T1, class ..._Args>
1191f447e62eSEric Fiselierstruct __find_exactly_one_checked {
119200c872f3SCasey Carter    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1193f447e62eSEric Fiselier    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1194f447e62eSEric Fiselier    static_assert(value != __not_found, "type not found in type list" );
1195f447e62eSEric Fiselier    static_assert(value != __ambiguous, "type occurs more than once in type list");
1196e99520c7SMarshall Clow};
1197e99520c7SMarshall Clow
11984f905b8dSEric Fiseliertemplate <class _T1>
11994f905b8dSEric Fiselierstruct __find_exactly_one_checked<_T1> {
12004f905b8dSEric Fiselier    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
12014f905b8dSEric Fiselier};
12024f905b8dSEric Fiselier
1203f447e62eSEric Fiselier} // namespace __find_detail;
1204e99520c7SMarshall Clow
1205e99520c7SMarshall Clowtemplate <typename _T1, typename... _Args>
1206f447e62eSEric Fiselierstruct __find_exactly_one_t
1207f447e62eSEric Fiselier    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1208e99520c7SMarshall Clow};
1209e99520c7SMarshall Clow
1210e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1211e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1212e99520c7SMarshall Clowconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
1213e99520c7SMarshall Clow{
1214e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1215e99520c7SMarshall Clow}
1216e99520c7SMarshall Clow
1217e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1218e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1219e99520c7SMarshall Clowconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1220e99520c7SMarshall Clow{
1221e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1222e99520c7SMarshall Clow}
1223e99520c7SMarshall Clow
1224e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1225e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1226e99520c7SMarshall Clowconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1227e99520c7SMarshall Clow{
12281c682f0fSMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1229e99520c7SMarshall Clow}
1230e99520c7SMarshall Clow
1231545b8861SEric Fiseliertemplate <class _T1, class... _Args>
1232545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1233545b8861SEric Fiselierconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1234545b8861SEric Fiselier{
1235545b8861SEric Fiselier    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1236545b8861SEric Fiselier}
1237545b8861SEric Fiselier
1238e99520c7SMarshall Clow#endif
1239e99520c7SMarshall Clow
12403e519524SHoward Hinnant// tie
12413e519524SHoward Hinnant
12423e519524SHoward Hinnanttemplate <class ..._Tp>
12430d1560e1SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12443e519524SHoward Hinnanttuple<_Tp&...>
12458a9ee148SHoward Hinnanttie(_Tp&... __t) _NOEXCEPT
12463e519524SHoward Hinnant{
12473e519524SHoward Hinnant    return tuple<_Tp&...>(__t...);
12483e519524SHoward Hinnant}
12493e519524SHoward Hinnant
12503e519524SHoward Hinnanttemplate <class _Up>
12513e519524SHoward Hinnantstruct __ignore_t
12523e519524SHoward Hinnant{
12533e519524SHoward Hinnant    template <class _Tp>
12549af60c4aSEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12553e519524SHoward Hinnant    const __ignore_t& operator=(_Tp&&) const {return *this;}
12563e519524SHoward Hinnant};
12573e519524SHoward Hinnant
12589af60c4aSEric Fiseliernamespace {
1259cb793e1aSLouis Dionne  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
12609af60c4aSEric Fiselier}
12613e519524SHoward Hinnant
12623e519524SHoward Hinnanttemplate <class... _Tp>
126375eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1264bb9ca6d0SLouis Dionnetuple<typename __unwrap_ref_decay<_Tp>::type...>
12653e519524SHoward Hinnantmake_tuple(_Tp&&... __t)
12663e519524SHoward Hinnant{
1267bb9ca6d0SLouis Dionne    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
12683e519524SHoward Hinnant}
12693e519524SHoward Hinnant
12701102fbbdSHoward Hinnanttemplate <class... _Tp>
127175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
127275eff748SMarshall Clowtuple<_Tp&&...>
12738a9ee148SHoward Hinnantforward_as_tuple(_Tp&&... __t) _NOEXCEPT
12741102fbbdSHoward Hinnant{
1275ce48a113SHoward Hinnant    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
12761102fbbdSHoward Hinnant}
12771102fbbdSHoward Hinnant
1278c003db1fSHoward Hinnanttemplate <size_t _Ip>
12793e519524SHoward Hinnantstruct __tuple_equal
12803e519524SHoward Hinnant{
12813e519524SHoward Hinnant    template <class _Tp, class _Up>
128275eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12833e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
12843e519524SHoward Hinnant    {
1285f9af6140SMarshall Clow        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
12863e519524SHoward Hinnant    }
12873e519524SHoward Hinnant};
12883e519524SHoward Hinnant
12893e519524SHoward Hinnanttemplate <>
12903e519524SHoward Hinnantstruct __tuple_equal<0>
12913e519524SHoward Hinnant{
12923e519524SHoward Hinnant    template <class _Tp, class _Up>
129375eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12943e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
12953e519524SHoward Hinnant    {
12963e519524SHoward Hinnant        return true;
12973e519524SHoward Hinnant    }
12983e519524SHoward Hinnant};
12993e519524SHoward Hinnant
13003e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
130175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13023e519524SHoward Hinnantbool
13033e519524SHoward Hinnantoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13043e519524SHoward Hinnant{
1305aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13063e519524SHoward Hinnant    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
13073e519524SHoward Hinnant}
13083e519524SHoward Hinnant
1309*b80f2dfdSKent Ross#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1310*b80f2dfdSKent Ross
1311*b80f2dfdSKent Ross// operator<=>
1312*b80f2dfdSKent Ross
1313*b80f2dfdSKent Rosstemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1314*b80f2dfdSKent Ross_LIBCPP_HIDE_FROM_ABI constexpr
1315*b80f2dfdSKent Rossauto
1316*b80f2dfdSKent Ross__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1317*b80f2dfdSKent Ross    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1318*b80f2dfdSKent Ross    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1319*b80f2dfdSKent Ross    return __result;
1320*b80f2dfdSKent Ross}
1321*b80f2dfdSKent Ross
1322*b80f2dfdSKent Rosstemplate <class ..._Tp, class ..._Up>
1323*b80f2dfdSKent Rossrequires (sizeof...(_Tp) == sizeof...(_Up))
1324*b80f2dfdSKent Ross_LIBCPP_HIDE_FROM_ABI constexpr
1325*b80f2dfdSKent Rosscommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1326*b80f2dfdSKent Rossoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1327*b80f2dfdSKent Ross{
1328*b80f2dfdSKent Ross    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1329*b80f2dfdSKent Ross}
1330*b80f2dfdSKent Ross
1331*b80f2dfdSKent Ross#else // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1332*b80f2dfdSKent Ross
13333e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
133475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13353e519524SHoward Hinnantbool
13363e519524SHoward Hinnantoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13373e519524SHoward Hinnant{
13383e519524SHoward Hinnant    return !(__x == __y);
13393e519524SHoward Hinnant}
13403e519524SHoward Hinnant
1341c003db1fSHoward Hinnanttemplate <size_t _Ip>
13423e519524SHoward Hinnantstruct __tuple_less
13433e519524SHoward Hinnant{
13443e519524SHoward Hinnant    template <class _Tp, class _Up>
134575eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13463e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
13473e519524SHoward Hinnant    {
134853afae49SDuncan P. N. Exon Smith        const size_t __idx = tuple_size<_Tp>::value - _Ip;
134953afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
135053afae49SDuncan P. N. Exon Smith            return true;
135153afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
135253afae49SDuncan P. N. Exon Smith            return false;
135353afae49SDuncan P. N. Exon Smith        return __tuple_less<_Ip-1>()(__x, __y);
13543e519524SHoward Hinnant    }
13553e519524SHoward Hinnant};
13563e519524SHoward Hinnant
13573e519524SHoward Hinnanttemplate <>
13583e519524SHoward Hinnantstruct __tuple_less<0>
13593e519524SHoward Hinnant{
13603e519524SHoward Hinnant    template <class _Tp, class _Up>
136175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13623e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
13633e519524SHoward Hinnant    {
13643e519524SHoward Hinnant        return false;
13653e519524SHoward Hinnant    }
13663e519524SHoward Hinnant};
13673e519524SHoward Hinnant
13683e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
136975eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13703e519524SHoward Hinnantbool
13713e519524SHoward Hinnantoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13723e519524SHoward Hinnant{
1373aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13743e519524SHoward Hinnant    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
13753e519524SHoward Hinnant}
13763e519524SHoward Hinnant
13773e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
137875eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13793e519524SHoward Hinnantbool
13803e519524SHoward Hinnantoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13813e519524SHoward Hinnant{
13823e519524SHoward Hinnant    return __y < __x;
13833e519524SHoward Hinnant}
13843e519524SHoward Hinnant
13853e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
138675eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13873e519524SHoward Hinnantbool
13883e519524SHoward Hinnantoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13893e519524SHoward Hinnant{
13903e519524SHoward Hinnant    return !(__x < __y);
13913e519524SHoward Hinnant}
13923e519524SHoward Hinnant
13933e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
139475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13953e519524SHoward Hinnantbool
13963e519524SHoward Hinnantoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13973e519524SHoward Hinnant{
13983e519524SHoward Hinnant    return !(__y < __x);
13993e519524SHoward Hinnant}
14003e519524SHoward Hinnant
1401*b80f2dfdSKent Ross#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1402*b80f2dfdSKent Ross
14033e519524SHoward Hinnant// tuple_cat
14043e519524SHoward Hinnant
14057f64810bSHoward Hinnanttemplate <class _Tp, class _Up> struct __tuple_cat_type;
14067f64810bSHoward Hinnant
14077f64810bSHoward Hinnanttemplate <class ..._Ttypes, class ..._Utypes>
14087f64810bSHoward Hinnantstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
14093e519524SHoward Hinnant{
14103557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
14117f64810bSHoward Hinnant};
14127f64810bSHoward Hinnant
14137f64810bSHoward Hinnanttemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
14147f64810bSHoward Hinnantstruct __tuple_cat_return_1
14157f64810bSHoward Hinnant{
14167f64810bSHoward Hinnant};
14177f64810bSHoward Hinnant
14187f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0>
14197f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
14207f64810bSHoward Hinnant{
14213557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename __tuple_cat_type<tuple<_Types...>,
14227e528bc4SEric Fiselier            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
14237f64810bSHoward Hinnant                                                                           type;
14247f64810bSHoward Hinnant};
14257f64810bSHoward Hinnant
14267f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
14277f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
14287f64810bSHoward Hinnant    : public __tuple_cat_return_1<
14297f64810bSHoward Hinnant                 typename __tuple_cat_type<
14307f64810bSHoward Hinnant                     tuple<_Types...>,
14317e528bc4SEric Fiselier                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
14327f64810bSHoward Hinnant                 >::type,
14337f64810bSHoward Hinnant                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
14347f64810bSHoward Hinnant                 _Tuple1, _Tuples...>
14357f64810bSHoward Hinnant{
14367f64810bSHoward Hinnant};
14377f64810bSHoward Hinnant
14387f64810bSHoward Hinnanttemplate <class ..._Tuples> struct __tuple_cat_return;
14397f64810bSHoward Hinnant
14407f64810bSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
14417f64810bSHoward Hinnantstruct __tuple_cat_return<_Tuple0, _Tuples...>
14427f64810bSHoward Hinnant    : public __tuple_cat_return_1<tuple<>,
14437f64810bSHoward Hinnant         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
14447f64810bSHoward Hinnant                                                                     _Tuples...>
14457f64810bSHoward Hinnant{
14467f64810bSHoward Hinnant};
14477f64810bSHoward Hinnant
14487f64810bSHoward Hinnanttemplate <>
14497f64810bSHoward Hinnantstruct __tuple_cat_return<>
14507f64810bSHoward Hinnant{
14513557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<> type;
14527f64810bSHoward Hinnant};
14537f64810bSHoward Hinnant
145475eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14557f64810bSHoward Hinnanttuple<>
14567f64810bSHoward Hinnanttuple_cat()
14577f64810bSHoward Hinnant{
14587f64810bSHoward Hinnant    return tuple<>();
14593e519524SHoward Hinnant}
14603e519524SHoward Hinnant
1461c003db1fSHoward Hinnanttemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1462ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp;
14633e519524SHoward Hinnant
1464ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1465ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
14663e519524SHoward Hinnant{
14673557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1468ba31cbdbSHoward Hinnant    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1469ba31cbdbSHoward Hinnant                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1470ba31cbdbSHoward Hinnant};
1471ba31cbdbSHoward Hinnant
1472ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1473ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1474ba31cbdbSHoward Hinnant                                  _Tuple0, _Tuple1, _Tuples...>
1475ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<
1476ba31cbdbSHoward Hinnant         tuple<_Types..., typename __apply_cv<_Tuple0,
1477ba31cbdbSHoward Hinnant               typename tuple_element<_I0,
1478ba31cbdbSHoward Hinnant                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1479ba31cbdbSHoward Hinnant         typename __make_tuple_indices<tuple_size<typename
1480ba31cbdbSHoward Hinnant                                 remove_reference<_Tuple1>::type>::value>::type,
1481ba31cbdbSHoward Hinnant         _Tuple1, _Tuples...>
1482ba31cbdbSHoward Hinnant{
1483ba31cbdbSHoward Hinnant};
1484ba31cbdbSHoward Hinnant
1485ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
1486ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref
1487ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<tuple<>,
1488ba31cbdbSHoward Hinnant               typename __make_tuple_indices<
1489ba31cbdbSHoward Hinnant                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1490ba31cbdbSHoward Hinnant               >::type, _Tuple0, _Tuples...>
1491ba31cbdbSHoward Hinnant{
1492ba31cbdbSHoward Hinnant};
1493ba31cbdbSHoward Hinnant
1494ba31cbdbSHoward Hinnanttemplate <class _Types, class _I0, class _J0>
1495ba31cbdbSHoward Hinnantstruct __tuple_cat;
1496ba31cbdbSHoward Hinnant
1497ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1498ba31cbdbSHoward Hinnantstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1499ba31cbdbSHoward Hinnant{
1500ba31cbdbSHoward Hinnant    template <class _Tuple0>
150175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1502ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1503ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1504ba31cbdbSHoward Hinnant    {
1505e658b3ebSDavid Blaikie        return _VSTD::forward_as_tuple(
1506e658b3ebSDavid Blaikie            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1507f9af6140SMarshall Clow            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
15083e519524SHoward Hinnant    }
15093e519524SHoward Hinnant
15107f64810bSHoward Hinnant    template <class _Tuple0, class _Tuple1, class ..._Tuples>
151175eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1512ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1513ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
15143e519524SHoward Hinnant    {
15153557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
15163557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
1517ba31cbdbSHoward Hinnant        return __tuple_cat<
1518e658b3ebSDavid Blaikie            tuple<_Types...,
1519e658b3ebSDavid Blaikie                  typename __apply_cv<_Tuple0, typename tuple_element<
1520e658b3ebSDavid Blaikie                                                   _J0, _T0>::type>::type&&...>,
1521e658b3ebSDavid Blaikie            typename __make_tuple_indices<sizeof...(_Types) +
1522e658b3ebSDavid Blaikie                                          tuple_size<_T0>::value>::type,
1523e658b3ebSDavid Blaikie            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1524e658b3ebSDavid Blaikie            _VSTD::forward_as_tuple(
1525f9af6140SMarshall Clow                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1526e658b3ebSDavid Blaikie                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1527e658b3ebSDavid Blaikie            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1528ba31cbdbSHoward Hinnant    }
1529ba31cbdbSHoward Hinnant};
1530ba31cbdbSHoward Hinnant
1531ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class... _Tuples>
153275eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1533ba31cbdbSHoward Hinnanttypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1534ba31cbdbSHoward Hinnanttuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1535ba31cbdbSHoward Hinnant{
15363557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1537ba31cbdbSHoward Hinnant    return __tuple_cat<tuple<>, __tuple_indices<>,
1538ba31cbdbSHoward Hinnant                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1539ce48a113SHoward Hinnant                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1540ce48a113SHoward Hinnant                                            _VSTD::forward<_Tuples>(__tpls)...);
15413e519524SHoward Hinnant}
15423e519524SHoward Hinnant
15433e519524SHoward Hinnanttemplate <class ..._Tp, class _Alloc>
1544e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
15453e519524SHoward Hinnant    : true_type {};
15463e519524SHoward Hinnant
15473e519524SHoward Hinnanttemplate <class _T1, class _T2>
15483e519524SHoward Hinnanttemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1549737a4501SMichael Schellenberger Costainline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15503e519524SHoward Hinnantpair<_T1, _T2>::pair(piecewise_construct_t,
15513e519524SHoward Hinnant                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
15523e519524SHoward Hinnant                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1553f9af6140SMarshall Clow    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1554f9af6140SMarshall Clow      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
15553e519524SHoward Hinnant{
15563e519524SHoward Hinnant}
15573e519524SHoward Hinnant
155803e29a29SEric Fiselier#if _LIBCPP_STD_VER > 14
155903e29a29SEric Fiseliertemplate <class _Tp>
1560cb793e1aSLouis Dionneinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
156103e29a29SEric Fiselier
156203e29a29SEric Fiselier#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
156303e29a29SEric Fiselier
156403e29a29SEric Fiseliertemplate <class _Fn, class _Tuple, size_t ..._Id>
156503e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
156603e29a29SEric Fiselierconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
156703e29a29SEric Fiselier                                            __tuple_indices<_Id...>)
156803e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
156903e29a29SEric Fiselier    _VSTD::__invoke_constexpr(
157003e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f),
157103e29a29SEric Fiselier        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
157203e29a29SEric Fiselier)
157303e29a29SEric Fiselier
157403e29a29SEric Fiseliertemplate <class _Fn, class _Tuple>
157503e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
157603e29a29SEric Fiselierconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
157703e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
157803e29a29SEric Fiselier    _VSTD::__apply_tuple_impl(
157903e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1580655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
158103e29a29SEric Fiselier)
158203e29a29SEric Fiselier
158303e29a29SEric Fiseliertemplate <class _Tp, class _Tuple, size_t... _Idx>
158403e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
158503e29a29SEric Fiselierconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
158603e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
158703e29a29SEric Fiselier    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
158803e29a29SEric Fiselier)
158903e29a29SEric Fiselier
159003e29a29SEric Fiseliertemplate <class _Tp, class _Tuple>
159103e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
159203e29a29SEric Fiselierconstexpr _Tp make_from_tuple(_Tuple&& __t)
159303e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
159403e29a29SEric Fiselier    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1595655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
159603e29a29SEric Fiselier)
159703e29a29SEric Fiselier
159803e29a29SEric Fiselier#undef _LIBCPP_NOEXCEPT_RETURN
159903e29a29SEric Fiselier
160003e29a29SEric Fiselier#endif // _LIBCPP_STD_VER > 14
160103e29a29SEric Fiselier
160229870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
160329870871SEric Fiselier
16043e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
16053e519524SHoward Hinnant
16063e519524SHoward Hinnant#endif // _LIBCPP_TUPLE
1607