xref: /llvm-project-15.0.7/libcxx/include/tuple (revision 169a66ea)
13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
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
76311207bbSNikolas Klauser
77311207bbSNikolas Klausertemplate<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23
78311207bbSNikolas Klauser  requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; }
79311207bbSNikolas Klauserstruct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> {
80311207bbSNikolas Klauser  using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>;
81311207bbSNikolas Klauser};
82311207bbSNikolas Klauser
83311207bbSNikolas Klausertemplate<class... TTypes, class... UTypes>                                // since C++23
84311207bbSNikolas Klauser  requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; }
85311207bbSNikolas Klauserstruct common_type<tuple<TTypes...>, tuple<UTypes...>> {
86311207bbSNikolas Klauser  using type = tuple<common_type_t<TTypes, UTypes>...>;
87311207bbSNikolas Klauser};
88311207bbSNikolas Klauser
891308011eSLouis Dionnetemplate <class ...T>
901308011eSLouis Dionnetuple(T...) -> tuple<T...>;                                         // since C++17
911308011eSLouis Dionnetemplate <class T1, class T2>
921308011eSLouis Dionnetuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
931308011eSLouis Dionnetemplate <class Alloc, class ...T>
941308011eSLouis Dionnetuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
951308011eSLouis Dionnetemplate <class Alloc, class T1, class T2>
961308011eSLouis Dionnetuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
971308011eSLouis Dionnetemplate <class Alloc, class ...T>
981308011eSLouis Dionnetuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
991308011eSLouis Dionne
10040a01d53SMarshall Clowinline constexpr unspecified ignore;
1013e519524SHoward Hinnant
10275eff748SMarshall Clowtemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
103de9320aaSMarshall Clowtemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
1040d1560e1SMarshall Clowtemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
10575eff748SMarshall Clowtemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
1063e519524SHoward Hinnant
10703e29a29SEric Fiselier// [tuple.apply], calling a function with a tuple of arguments:
10803e29a29SEric Fiseliertemplate <class F, class Tuple>
10903e29a29SEric Fiselier  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
11003e29a29SEric Fiseliertemplate <class T, class Tuple>
11103e29a29SEric Fiselier  constexpr T make_from_tuple(Tuple&& t); // C++17
11203e29a29SEric Fiselier
1133e519524SHoward Hinnant// 20.4.1.4, tuple helper classes:
114e4957601SMarshall Clowtemplate <class T> struct tuple_size; // undefined
115e4957601SMarshall Clowtemplate <class... T> struct tuple_size<tuple<T...>>;
11603e29a29SEric Fiseliertemplate <class T>
11740a01d53SMarshall Clow inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
1182b0c7abbSLouis Dionnetemplate <size_t I, class T> struct tuple_element; // undefined
1192b0c7abbSLouis Dionnetemplate <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
120bfb3f2bfSMarshall Clowtemplate <size_t I, class T>
121bfb3f2bfSMarshall Clow  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
1223e519524SHoward Hinnant
1233e519524SHoward Hinnant// 20.4.1.5, element access:
124bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
12527d0a2a7SHoward Hinnant    typename tuple_element<I, tuple<T...>>::type&
1268bf1f08aSMarshall Clow    get(tuple<T...>&) noexcept; // constexpr in C++14
127bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
128bfb3f2bfSMarshall Clow    const typename tuple_element<I, tuple<T...>>::type&
1298bf1f08aSMarshall Clow    get(const tuple<T...>&) noexcept; // constexpr in C++14
130bfb3f2bfSMarshall Clowtemplate <size_t I, class... T>
13127d0a2a7SHoward Hinnant    typename tuple_element<I, tuple<T...>>::type&&
1328bf1f08aSMarshall Clow    get(tuple<T...>&&) noexcept; // constexpr in C++14
133545b8861SEric Fiseliertemplate <size_t I, class... T>
134545b8861SEric Fiselier    const typename tuple_element<I, tuple<T...>>::type&&
135545b8861SEric Fiselier    get(const tuple<T...>&&) noexcept; // constexpr in C++14
1363e519524SHoward Hinnant
137e99520c7SMarshall Clowtemplate <class T1, class... T>
138e99520c7SMarshall Clow    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
139e99520c7SMarshall Clowtemplate <class T1, class... T>
140bfb3f2bfSMarshall Clow    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
141e99520c7SMarshall Clowtemplate <class T1, class... T>
142e99520c7SMarshall Clow    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
143545b8861SEric Fiseliertemplate <class T1, class... T>
144545b8861SEric Fiselier    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
145e99520c7SMarshall Clow
1463e519524SHoward Hinnant// 20.4.1.6, relational operators:
14775eff748SMarshall Clowtemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
148b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
149b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
150b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
151b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
152b80f2dfdSKent Rosstemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
153b80f2dfdSKent Rosstemplate<class... T, class... U>
154b80f2dfdSKent Ross  constexpr common_comparison_category_t<synth-three-way-result<T, U>...>
155b80f2dfdSKent Ross    operator<=>(const tuple<T...>&, const tuple<U...>&);                                  // since C++20
1563e519524SHoward Hinnant
1573e519524SHoward Hinnanttemplate <class... Types, class Alloc>
1583e519524SHoward Hinnant  struct uses_allocator<tuple<Types...>, Alloc>;
1593e519524SHoward Hinnant
1603e519524SHoward Hinnanttemplate <class... Types>
16127d0a2a7SHoward Hinnant  void
16227d0a2a7SHoward Hinnant  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1633e519524SHoward Hinnant
1643e519524SHoward Hinnant}  // std
1653e519524SHoward Hinnant
1663e519524SHoward Hinnant*/
1673e519524SHoward Hinnant
168b80f2dfdSKent Ross#include <__compare/common_comparison_category.h>
169b80f2dfdSKent Ross#include <__compare/synth_three_way.h>
1703e519524SHoward Hinnant#include <__config>
17169d5a666SChristopher Di Bella#include <__functional/unwrap_ref.h>
172050b064fSChristopher Di Bella#include <__memory/allocator_arg_t.h>
173050b064fSChristopher Di Bella#include <__memory/uses_allocator.h>
174050b064fSChristopher Di Bella#include <__tuple>
1756adbc83eSChristopher Di Bella#include <__utility/forward.h>
176b80f2dfdSKent Ross#include <__utility/integer_sequence.h>
1776adbc83eSChristopher Di Bella#include <__utility/move.h>
1782d0f1fa4SArthur O'Dwyer#include <compare>
1793e519524SHoward Hinnant#include <cstddef>
1803e519524SHoward Hinnant#include <type_traits>
181a87b5e34SHoward Hinnant#include <utility>
182f56972e2SMarshall Clow#include <version>
1833e519524SHoward Hinnant
184*169a66eaSNikolas Klauser// TODO: remove these headers
185*169a66eaSNikolas Klauser#include <__functional/binary_function.h>
186*169a66eaSNikolas Klauser#include <__functional/invoke.h>
187*169a66eaSNikolas Klauser#include <__functional/operations.h>
188*169a66eaSNikolas Klauser#include <__functional/reference_wrapper.h>
189*169a66eaSNikolas Klauser#include <__functional/unary_function.h>
190*169a66eaSNikolas Klauser#include <__functional/weak_result_type.h>
191*169a66eaSNikolas Klauser#include <exception>
192*169a66eaSNikolas Klauser#include <new>
193*169a66eaSNikolas Klauser#include <typeinfo>
194*169a66eaSNikolas Klauser
195073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1963e519524SHoward Hinnant#  pragma GCC system_header
197073458b1SHoward Hinnant#endif
1983e519524SHoward Hinnant
1993e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
2003e519524SHoward Hinnant
20129870871SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2023e519524SHoward Hinnant
20305c8dad2SMarshall Clow
2043e519524SHoward Hinnant// __tuple_leaf
2053e519524SHoward Hinnant
206ee187e24SEric Fiseliertemplate <size_t _Ip, class _Hp,
207ee187e24SEric Fiselier          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
20842b8bb50SHoward Hinnant         >
2093e519524SHoward Hinnantclass __tuple_leaf;
2103e519524SHoward Hinnant
2113e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool _Ep>
21206e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2133e519524SHoward Hinnantvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
21427d0a2a7SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
2153e519524SHoward Hinnant{
2163e519524SHoward Hinnant    swap(__x.get(), __y.get());
2173e519524SHoward Hinnant}
2183e519524SHoward Hinnant
2193e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp, bool>
2203e519524SHoward Hinnantclass __tuple_leaf
2213e519524SHoward Hinnant{
222def3c375SEric Fiselier    _Hp __value_;
2233e519524SHoward Hinnant
224074f8d77SEric Fiselier    template <class _Tp>
225074f8d77SEric Fiselier    static constexpr bool __can_bind_reference() {
226292617e7SEric Fiselier#if __has_keyword(__reference_binds_to_temporary)
227292617e7SEric Fiselier      return !__reference_binds_to_temporary(_Hp, _Tp);
228b1539e0aSEric Fiselier#else
229b1539e0aSEric Fiselier      return true;
230292617e7SEric Fiselier#endif
231074f8d77SEric Fiselier    }
232074f8d77SEric Fiselier
23306e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
2343e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
2353e519524SHoward Hinnantpublic:
23606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
237def3c375SEric Fiselier             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2383e519524SHoward Hinnant       {static_assert(!is_reference<_Hp>::value,
2393e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2403e519524SHoward Hinnant
2413e519524SHoward Hinnant    template <class _Alloc>
24206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2433e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
244def3c375SEric Fiselier            : __value_()
2453e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2463e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2473e519524SHoward Hinnant
2483e519524SHoward Hinnant    template <class _Alloc>
24906e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2503e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
251def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a)
2523e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2533e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2543e519524SHoward Hinnant
2553e519524SHoward Hinnant    template <class _Alloc>
25606e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
2573e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
258def3c375SEric Fiselier            : __value_(__a)
2593e519524SHoward Hinnant        {static_assert(!is_reference<_Hp>::value,
2603e519524SHoward Hinnant              "Attempted to default construct a reference element in a tuple");}
2613e519524SHoward Hinnant
26230ad985bSHoward Hinnant    template <class _Tp,
263b4e88d4dSLouis Dionne              class = __enable_if_t<
2643359a17bSEric Fiselier                  _And<
2653359a17bSEric Fiselier                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
2663359a17bSEric Fiselier                      is_constructible<_Hp, _Tp>
267567bb79bSEric Fiselier                    >::value
2683359a17bSEric Fiselier                >
269567bb79bSEric Fiselier            >
27075eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2718a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
272def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
273292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
274292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2753e519524SHoward Hinnant
2763e519524SHoward Hinnant    template <class _Tp, class _Alloc>
27706e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2783e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
279def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t))
280292617e7SEric Fiselier        {static_assert(__can_bind_reference<_Tp&&>(),
281292617e7SEric Fiselier       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2823e519524SHoward Hinnant
2833e519524SHoward Hinnant    template <class _Tp, class _Alloc>
28406e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2853e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
286def3c375SEric Fiselier            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
287074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
288074f8d77SEric Fiselier            "Attempted to uses-allocator construct a reference element in a tuple");}
2893e519524SHoward Hinnant
2903e519524SHoward Hinnant    template <class _Tp, class _Alloc>
29106e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2923e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
293def3c375SEric Fiselier            : __value_(_VSTD::forward<_Tp>(__t), __a)
294074f8d77SEric Fiselier        {static_assert(!is_reference<_Hp>::value,
295074f8d77SEric Fiselier           "Attempted to uses-allocator construct a reference element in a tuple");}
2963e519524SHoward Hinnant
2977546a111SMarshall Clow    __tuple_leaf(const __tuple_leaf& __t) = default;
2987546a111SMarshall Clow    __tuple_leaf(__tuple_leaf&& __t) = default;
2993e519524SHoward Hinnant
30006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
30127d0a2a7SHoward Hinnant    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3023e519524SHoward Hinnant    {
303ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
3043e519524SHoward Hinnant        return 0;
3053e519524SHoward Hinnant    }
3063e519524SHoward Hinnant
307def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
308def3c375SEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
3093e519524SHoward Hinnant};
3103e519524SHoward Hinnant
3113e519524SHoward Hinnanttemplate <size_t _Ip, class _Hp>
3123e519524SHoward Hinnantclass __tuple_leaf<_Ip, _Hp, true>
3133e519524SHoward Hinnant    : private _Hp
3143e519524SHoward Hinnant{
31506e2b737SArthur O'Dwyer    _LIBCPP_CONSTEXPR_AFTER_CXX11
3163e519524SHoward Hinnant    __tuple_leaf& operator=(const __tuple_leaf&);
3173e519524SHoward Hinnantpublic:
31806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
319a0f4c45cSHoward Hinnant             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
3203e519524SHoward Hinnant
3213e519524SHoward Hinnant    template <class _Alloc>
32206e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3233e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
3243e519524SHoward Hinnant
3253e519524SHoward Hinnant    template <class _Alloc>
32606e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3273e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3283e519524SHoward Hinnant            : _Hp(allocator_arg_t(), __a) {}
3293e519524SHoward Hinnant
3303e519524SHoward Hinnant    template <class _Alloc>
33106e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3323e519524SHoward Hinnant        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3333e519524SHoward Hinnant            : _Hp(__a) {}
3343e519524SHoward Hinnant
33530ad985bSHoward Hinnant    template <class _Tp,
336b4e88d4dSLouis Dionne              class = __enable_if_t<
3373359a17bSEric Fiselier                  _And<
3383359a17bSEric Fiselier                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3393359a17bSEric Fiselier                    is_constructible<_Hp, _Tp>
340567bb79bSEric Fiselier                  >::value
3413359a17bSEric Fiselier                >
342567bb79bSEric Fiselier            >
34375eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3448a9ee148SHoward Hinnant        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
345ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3463e519524SHoward Hinnant
3473e519524SHoward Hinnant    template <class _Tp, class _Alloc>
34806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3493e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
350ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3513e519524SHoward Hinnant
3523e519524SHoward Hinnant    template <class _Tp, class _Alloc>
35306e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3543e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
355ce48a113SHoward Hinnant            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3563e519524SHoward Hinnant
3573e519524SHoward Hinnant    template <class _Tp, class _Alloc>
35806e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY constexpr
3593e519524SHoward Hinnant        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
360ce48a113SHoward Hinnant            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3613e519524SHoward Hinnant
362567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf const &) = default;
363567bb79bSEric Fiselier    __tuple_leaf(__tuple_leaf &&) = default;
364567bb79bSEric Fiselier
36506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
36627d0a2a7SHoward Hinnant    int
36727d0a2a7SHoward Hinnant    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3683e519524SHoward Hinnant    {
369ce48a113SHoward Hinnant        _VSTD::swap(*this, __t);
3703e519524SHoward Hinnant        return 0;
3713e519524SHoward Hinnant    }
3723e519524SHoward Hinnant
37375eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
37475eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3753e519524SHoward Hinnant};
3763e519524SHoward Hinnant
377789847ddSHoward Hinnanttemplate <class ..._Tp>
37806e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3798a9ee148SHoward Hinnantvoid __swallow(_Tp&&...) _NOEXCEPT {}
3803e519524SHoward Hinnant
38114c5ec51SMarshall Clowtemplate <class _Tp>
38214c5ec51SMarshall Clowstruct __all_default_constructible;
38327d0a2a7SHoward Hinnant
38414c5ec51SMarshall Clowtemplate <class ..._Tp>
38514c5ec51SMarshall Clowstruct __all_default_constructible<__tuple_types<_Tp...>>
38614c5ec51SMarshall Clow    : __all<is_default_constructible<_Tp>::value...>
38714c5ec51SMarshall Clow{ };
38827d0a2a7SHoward Hinnant
3893e519524SHoward Hinnant// __tuple_impl
3903e519524SHoward Hinnant
3913e519524SHoward Hinnanttemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3923e519524SHoward Hinnant
3933e519524SHoward Hinnanttemplate<size_t ..._Indx, class ..._Tp>
394b43f17c8SEric Fiselierstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3953e519524SHoward Hinnant    : public __tuple_leaf<_Indx, _Tp>...
3963e519524SHoward Hinnant{
397a62ebe04SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
39806e2b737SArthur O'Dwyer    constexpr __tuple_impl()
399a0f4c45cSHoward Hinnant        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
400a62ebe04SHoward Hinnant
4013e519524SHoward Hinnant    template <size_t ..._Uf, class ..._Tf,
4023e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
40375eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4043e519524SHoward Hinnant        explicit
4053e519524SHoward Hinnant        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
4063e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
4078a9ee148SHoward Hinnant                     _Up&&... __u)
4088a9ee148SHoward Hinnant                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
4098a9ee148SHoward Hinnant                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
410ce48a113SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
4113e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>()...
4123e519524SHoward Hinnant            {}
4133e519524SHoward Hinnant
4143e519524SHoward Hinnant    template <class _Alloc, size_t ..._Uf, class ..._Tf,
4153e519524SHoward Hinnant              size_t ..._Ul, class ..._Tl, class ..._Up>
41606e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4173e519524SHoward Hinnant        explicit
4183e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a,
4193e519524SHoward Hinnant                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
4203e519524SHoward Hinnant                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
4213e519524SHoward Hinnant                     _Up&&... __u) :
4223e519524SHoward Hinnant            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
423ce48a113SHoward Hinnant            _VSTD::forward<_Up>(__u))...,
4243e519524SHoward Hinnant            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
4253e519524SHoward Hinnant            {}
4263e519524SHoward Hinnant
4273e519524SHoward Hinnant    template <class _Tuple,
4283e519524SHoward Hinnant              class = typename enable_if
4293e519524SHoward Hinnant                      <
430f3b02b17SHoward Hinnant                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4313e519524SHoward Hinnant                      >::type
4323e519524SHoward Hinnant             >
43375eff748SMarshall Clow        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4348a9ee148SHoward Hinnant        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4358a9ee148SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
436ce48a113SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
437ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4383e519524SHoward Hinnant            {}
4393e519524SHoward Hinnant
4403e519524SHoward Hinnant    template <class _Alloc, class _Tuple,
4413e519524SHoward Hinnant              class = typename enable_if
4423e519524SHoward Hinnant                      <
4439795699aSEric Fiselier                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4443e519524SHoward Hinnant                      >::type
4453e519524SHoward Hinnant             >
44606e2b737SArthur O'Dwyer        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4473e519524SHoward Hinnant        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4483e519524SHoward Hinnant            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4493e519524SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
450ce48a113SHoward Hinnant                                       _VSTD::forward<typename tuple_element<_Indx,
451ce48a113SHoward Hinnant                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4523e519524SHoward Hinnant            {}
4533e519524SHoward Hinnant
4544478b25aSHoward Hinnant    __tuple_impl(const __tuple_impl&) = default;
4554478b25aSHoward Hinnant    __tuple_impl(__tuple_impl&&) = default;
4564478b25aSHoward Hinnant
45706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4583e519524SHoward Hinnant    void swap(__tuple_impl& __t)
45927d0a2a7SHoward Hinnant        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4603e519524SHoward Hinnant    {
461a0839b14SLouis Dionne        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4623e519524SHoward Hinnant    }
4633e519524SHoward Hinnant};
4643e519524SHoward Hinnant
465a0839b14SLouis Dionnetemplate<class _Dest, class _Source, size_t ..._Np>
46606e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
467a0839b14SLouis Dionnevoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
468a0839b14SLouis Dionne    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
469a0839b14SLouis Dionne}
47074cba642SEric Fiselier
471a0839b14SLouis Dionnetemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
47206e2b737SArthur O'Dwyer_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
473a0839b14SLouis Dionnevoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
474a0839b14SLouis Dionne    _VSTD::__swallow(((
475618862e8SLouis Dionne        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
476a0839b14SLouis Dionne    ), void(), 0)...);
477a0839b14SLouis Dionne}
47874cba642SEric Fiselier
4793e519524SHoward Hinnanttemplate <class ..._Tp>
480e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple
4813e519524SHoward Hinnant{
482def3c375SEric Fiselier    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4833e519524SHoward Hinnant
484def3c375SEric Fiselier    _BaseT __base_;
4853e519524SHoward Hinnant
4868bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
487c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
4888bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
489c206366fSHoward Hinnant        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
4908bf1f08aSMarshall Clow    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
491c206366fSHoward Hinnant        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
492545b8861SEric Fiselier    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
493545b8861SEric Fiselier        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
4943e519524SHoward Hinnantpublic:
495a3ab5120SLouis Dionne    // [tuple.cnstr]
4963e519524SHoward Hinnant
497a3ab5120SLouis Dionne    // tuple() constructors (including allocator_arg_t variants)
498b4e88d4dSLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
499a3ab5120SLouis Dionne        _And<
500a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
501a3ab5120SLouis Dionne        >::value
502a3ab5120SLouis Dionne    , int> = 0>
503ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
504e16f2cb6SLouis Dionne    tuple()
505a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
506a3ab5120SLouis Dionne    { }
507e16f2cb6SLouis Dionne
508a3ab5120SLouis Dionne    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
509b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
510a3ab5120SLouis Dionne        _And<
511a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
512a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
513a3ab5120SLouis Dionne        >::value
514a3ab5120SLouis Dionne    , int> = 0>
515a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
516a3ab5120SLouis Dionne    explicit tuple()
517a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
518a3ab5120SLouis Dionne    { }
519a62ebe04SHoward Hinnant
520b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
521a3ab5120SLouis Dionne        _And<
522a3ab5120SLouis Dionne            _IsImpDefault<_Tp>... // explicit check
523a3ab5120SLouis Dionne        >::value
524a3ab5120SLouis Dionne    , int> = 0>
525a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
526a3ab5120SLouis Dionne    tuple(allocator_arg_t, _Alloc const& __a)
527a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
528a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
529a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
530a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
531a3ab5120SLouis Dionne
532a3ab5120SLouis Dionne    template <class _Alloc,
533a3ab5120SLouis Dionne              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
534b4e88d4dSLouis Dionne              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
535a3ab5120SLouis Dionne        _And<
536a3ab5120SLouis Dionne            _IsDefault<_Tp>...,
537a3ab5120SLouis Dionne            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
538a3ab5120SLouis Dionne        >::value
539a3ab5120SLouis Dionne    , int> = 0>
540a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
541a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, _Alloc const& __a)
542a3ab5120SLouis Dionne      : __base_(allocator_arg_t(), __a,
543a3ab5120SLouis Dionne                    __tuple_indices<>(), __tuple_types<>(),
544a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
545a3ab5120SLouis Dionne                    __tuple_types<_Tp...>()) {}
546a3ab5120SLouis Dionne
547a3ab5120SLouis Dionne    // tuple(const T&...) constructors (including allocator_arg_t variants)
548b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
549a3ab5120SLouis Dionne        _And<
550a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
551a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
552a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
553a3ab5120SLouis Dionne        >::value
554a3ab5120SLouis Dionne    , int> = 0>
555a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
556a3ab5120SLouis Dionne    tuple(const _Tp& ... __t)
557a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
558a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
559a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
560a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
561a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
562a3ab5120SLouis Dionne                __t...
563a3ab5120SLouis Dionne               ) {}
564a3ab5120SLouis Dionne
565b4e88d4dSLouis Dionne    template <template<class...> class _And = _And, __enable_if_t<
566a3ab5120SLouis Dionne        _And<
567a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
568a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
569a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
570a3ab5120SLouis Dionne        >::value
571a3ab5120SLouis Dionne    , int> = 0>
572a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
573a3ab5120SLouis Dionne    explicit tuple(const _Tp& ... __t)
574a3ab5120SLouis Dionne        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
575a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
576a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
577a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
578a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
579a3ab5120SLouis Dionne                __t...
580a3ab5120SLouis Dionne               ) {}
581a3ab5120SLouis Dionne
582b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
583a3ab5120SLouis Dionne        _And<
584a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
585a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
586a3ab5120SLouis Dionne            is_convertible<const _Tp&, _Tp>... // explicit check
587a3ab5120SLouis Dionne        >::value
588a3ab5120SLouis Dionne    , int> = 0>
589a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
590a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
591a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
592a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
593a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
594a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
595a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
596a3ab5120SLouis Dionne                __t...
597a3ab5120SLouis Dionne               ) {}
598a3ab5120SLouis Dionne
599b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
600a3ab5120SLouis Dionne        _And<
601a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) >= 1>,
602a3ab5120SLouis Dionne            is_copy_constructible<_Tp>...,
603a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
604a3ab5120SLouis Dionne        >::value
605a3ab5120SLouis Dionne    , int> = 0>
606a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
607a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
608a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
609a3ab5120SLouis Dionne                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
610a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
611a3ab5120SLouis Dionne                typename __make_tuple_indices<0>::type(),
612a3ab5120SLouis Dionne                typename __make_tuple_types<tuple, 0>::type(),
613a3ab5120SLouis Dionne                __t...
614a3ab5120SLouis Dionne               ) {}
615a3ab5120SLouis Dionne
616a3ab5120SLouis Dionne    // tuple(U&& ...) constructors (including allocator_arg_t variants)
617a3ab5120SLouis Dionne    template <class ..._Up> struct _IsThisTuple : false_type { };
618a3ab5120SLouis Dionne    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
619a3ab5120SLouis Dionne
620a3ab5120SLouis Dionne    template <class ..._Up>
621a3ab5120SLouis Dionne    struct _EnableUTypesCtor : _And<
622a3ab5120SLouis Dionne        _BoolConstant<sizeof...(_Tp) >= 1>,
623a3ab5120SLouis Dionne        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
624a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
625a3ab5120SLouis Dionne    > { };
626a3ab5120SLouis Dionne
627b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
628a3ab5120SLouis Dionne        _And<
629a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
630a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
631a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
632a3ab5120SLouis Dionne        >::value
633a3ab5120SLouis Dionne    , int> = 0>
634a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
635a3ab5120SLouis Dionne    tuple(_Up&&... __u)
636a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
637a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
638a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
639a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
640a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
641a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
642a3ab5120SLouis Dionne
643b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
644a3ab5120SLouis Dionne        _And<
645a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
646a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
647a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
648a3ab5120SLouis Dionne        >::value
649a3ab5120SLouis Dionne    , int> = 0>
650a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
651a3ab5120SLouis Dionne    explicit tuple(_Up&&... __u)
652a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
653a3ab5120SLouis Dionne        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
654a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
655a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
656a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
657a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
658a3ab5120SLouis Dionne
659b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
660a3ab5120SLouis Dionne        _And<
661a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
662a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
663a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
664a3ab5120SLouis Dionne        >::value
665a3ab5120SLouis Dionne    , int> = 0>
666a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
667a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
668a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
669a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
670a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
671a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
672a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
673a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
674a3ab5120SLouis Dionne
675b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
676a3ab5120SLouis Dionne        _And<
677a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
678a3ab5120SLouis Dionne            _EnableUTypesCtor<_Up...>,
679a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
680a3ab5120SLouis Dionne        >::value
681a3ab5120SLouis Dionne    , int> = 0>
682a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
683a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
684a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a,
685a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
686a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
687a3ab5120SLouis Dionne                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
688a3ab5120SLouis Dionne                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
689a3ab5120SLouis Dionne                    _VSTD::forward<_Up>(__u)...) {}
690a3ab5120SLouis Dionne
691a3ab5120SLouis Dionne    // Copy and move constructors (including the allocator_arg_t variants)
692a3ab5120SLouis Dionne    tuple(const tuple&) = default;
693aedcbf89SEric Fiselier    tuple(tuple&&) = default;
694aedcbf89SEric Fiselier
695b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
696a3ab5120SLouis Dionne        _And<is_copy_constructible<_Tp>...>::value
697a3ab5120SLouis Dionne    , int> = 0>
698a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
699a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, __t)
700a3ab5120SLouis Dionne    { }
70190fb2bafSEric Fiselier
702b4e88d4dSLouis Dionne    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
703a3ab5120SLouis Dionne        _And<is_move_constructible<_Tp>...>::value
704a3ab5120SLouis Dionne    , int> = 0>
705a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
706a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
707a3ab5120SLouis Dionne    { }
70859e26308SLouis Dionne
709a3ab5120SLouis Dionne    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
710a3ab5120SLouis Dionne    template <class ..._Up>
711a3ab5120SLouis Dionne    struct _EnableCopyFromOtherTuple : _And<
71217f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
71317f2d1cbSLouis Dionne        _Lazy<_Or,
714a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
715a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
716a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
717a3ab5120SLouis Dionne            _Lazy<_And,
718a3ab5120SLouis Dionne                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
719a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
7209795699aSEric Fiselier            >
721a3ab5120SLouis Dionne        >,
722a3ab5120SLouis Dionne        is_constructible<_Tp, const _Up&>...
723a3ab5120SLouis Dionne    > { };
7249795699aSEric Fiselier
725b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
726a3ab5120SLouis Dionne        _And<
727a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
728a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
729a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
7308a9ee148SHoward Hinnant        >::value
731a3ab5120SLouis Dionne    , int> = 0>
73275eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
733a3ab5120SLouis Dionne    tuple(const tuple<_Up...>& __t)
734a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
735a3ab5120SLouis Dionne        : __base_(__t)
736a3ab5120SLouis Dionne    { }
737a3ab5120SLouis Dionne
738b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
739a3ab5120SLouis Dionne        _And<
740a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
741a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
742a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
7438a9ee148SHoward Hinnant        >::value
744a3ab5120SLouis Dionne    , int> = 0>
74575eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
746a3ab5120SLouis Dionne    explicit tuple(const tuple<_Up...>& __t)
747a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
748a3ab5120SLouis Dionne        : __base_(__t)
749a3ab5120SLouis Dionne    { }
7503e519524SHoward Hinnant
751b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
752a3ab5120SLouis Dionne        _And<
753a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
754a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
755a3ab5120SLouis Dionne            is_convertible<const _Up&, _Tp>... // explicit check
756a3ab5120SLouis Dionne        >::value
757a3ab5120SLouis Dionne    , int> = 0>
75806e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
759a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
760a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
761a3ab5120SLouis Dionne    { }
7623e519524SHoward Hinnant
763b4e88d4dSLouis Dionne    template <class ..._Up, class _Alloc, __enable_if_t<
764a3ab5120SLouis Dionne        _And<
765a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
766a3ab5120SLouis Dionne            _EnableCopyFromOtherTuple<_Up...>,
767a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
768a3ab5120SLouis Dionne        >::value
769a3ab5120SLouis Dionne    , int> = 0>
77006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
771a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
772a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __t)
773a3ab5120SLouis Dionne    { }
774a3ab5120SLouis Dionne
775a3ab5120SLouis Dionne    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
776a3ab5120SLouis Dionne    template <class ..._Up>
777a3ab5120SLouis Dionne    struct _EnableMoveFromOtherTuple : _And<
77817f2d1cbSLouis Dionne        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
77917f2d1cbSLouis Dionne        _Lazy<_Or,
780a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) != 1>,
781a3ab5120SLouis Dionne            // _Tp and _Up are 1-element packs - the pack expansions look
782a3ab5120SLouis Dionne            // weird to avoid tripping up the type traits in degenerate cases
783a3ab5120SLouis Dionne            _Lazy<_And,
784a3ab5120SLouis Dionne                _Not<is_convertible<tuple<_Up>, _Tp> >...,
785a3ab5120SLouis Dionne                _Not<is_constructible<_Tp, tuple<_Up> > >...
786a3ab5120SLouis Dionne            >
787a3ab5120SLouis Dionne        >,
788a3ab5120SLouis Dionne        is_constructible<_Tp, _Up>...
789a3ab5120SLouis Dionne    > { };
790a3ab5120SLouis Dionne
791b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
792a3ab5120SLouis Dionne        _And<
793a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
794a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
795a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
796a3ab5120SLouis Dionne        >::value
797a3ab5120SLouis Dionne    , int> = 0>
798a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
799a3ab5120SLouis Dionne    tuple(tuple<_Up...>&& __t)
800a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
801a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
802a3ab5120SLouis Dionne    { }
803a3ab5120SLouis Dionne
804b4e88d4dSLouis Dionne    template <class ..._Up, __enable_if_t<
805a3ab5120SLouis Dionne        _And<
806a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
807a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
808a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
809a3ab5120SLouis Dionne        >::value
810a3ab5120SLouis Dionne    , int> = 0>
811a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
812a3ab5120SLouis Dionne    explicit tuple(tuple<_Up...>&& __t)
813a3ab5120SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
814a3ab5120SLouis Dionne        : __base_(_VSTD::move(__t))
815a3ab5120SLouis Dionne    { }
816a3ab5120SLouis Dionne
817b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
818a3ab5120SLouis Dionne        _And<
819a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
820a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
821a3ab5120SLouis Dionne            is_convertible<_Up, _Tp>... // explicit check
822a3ab5120SLouis Dionne        >::value
823a3ab5120SLouis Dionne    , int> = 0>
824a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
825a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
826a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
827a3ab5120SLouis Dionne    { }
828a3ab5120SLouis Dionne
829b4e88d4dSLouis Dionne    template <class _Alloc, class ..._Up, __enable_if_t<
830a3ab5120SLouis Dionne        _And<
831a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
832a3ab5120SLouis Dionne            _EnableMoveFromOtherTuple<_Up...>,
833a3ab5120SLouis Dionne            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
834a3ab5120SLouis Dionne        >::value
835a3ab5120SLouis Dionne    , int> = 0>
836a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
837a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
838a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
839a3ab5120SLouis Dionne    { }
840a3ab5120SLouis Dionne
841a3ab5120SLouis Dionne    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
842a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
843a3ab5120SLouis Dionne    struct _EnableImplicitCopyFromPair : _And<
844a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
845a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
846a3ab5120SLouis Dionne        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
847a3ab5120SLouis Dionne        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
848a3ab5120SLouis Dionne    > { };
849a3ab5120SLouis Dionne
850a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
851a3ab5120SLouis Dionne    struct _EnableExplicitCopyFromPair : _And<
852a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
853a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
854a3ab5120SLouis Dionne        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
855a3ab5120SLouis Dionne        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
856a3ab5120SLouis Dionne    > { };
857a3ab5120SLouis Dionne
858b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
859a3ab5120SLouis Dionne        _And<
860a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
861a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
862a3ab5120SLouis Dionne        >::value
863a3ab5120SLouis Dionne    , int> = 0>
864a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
865a3ab5120SLouis Dionne    tuple(const pair<_Up1, _Up2>& __p)
866a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
867a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
868a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
869a3ab5120SLouis Dionne        >::value))
870a3ab5120SLouis Dionne        : __base_(__p)
871a3ab5120SLouis Dionne    { }
872a3ab5120SLouis Dionne
873b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
874a3ab5120SLouis Dionne        _And<
875a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
876a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
877a3ab5120SLouis Dionne        >::value
878a3ab5120SLouis Dionne    , int> = 0>
879a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
880a3ab5120SLouis Dionne    explicit tuple(const pair<_Up1, _Up2>& __p)
881a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
882a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
883a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
884a3ab5120SLouis Dionne        >::value))
885a3ab5120SLouis Dionne        : __base_(__p)
886a3ab5120SLouis Dionne    { }
887a3ab5120SLouis Dionne
888b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
889a3ab5120SLouis Dionne        _And<
890a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
891a3ab5120SLouis Dionne            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
892a3ab5120SLouis Dionne        >::value
893a3ab5120SLouis Dionne    , int> = 0>
894a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
895a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
896a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
897a3ab5120SLouis Dionne    { }
898a3ab5120SLouis Dionne
899b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
900a3ab5120SLouis Dionne        _And<
901a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
902a3ab5120SLouis Dionne            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
903a3ab5120SLouis Dionne        >::value
904a3ab5120SLouis Dionne    , int> = 0>
905a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
906a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
907a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, __p)
908a3ab5120SLouis Dionne    { }
909a3ab5120SLouis Dionne
910a3ab5120SLouis Dionne    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
911a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
912a3ab5120SLouis Dionne    struct _EnableImplicitMoveFromPair : _And<
913a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
914a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
915a3ab5120SLouis Dionne        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
916a3ab5120SLouis Dionne        is_convertible<_Up2, _SecondType<_DependentTp...> >
917a3ab5120SLouis Dionne    > { };
918a3ab5120SLouis Dionne
919a3ab5120SLouis Dionne    template <class _Up1, class _Up2, class ..._DependentTp>
920a3ab5120SLouis Dionne    struct _EnableExplicitMoveFromPair : _And<
921a3ab5120SLouis Dionne        is_constructible<_FirstType<_DependentTp...>, _Up1>,
922a3ab5120SLouis Dionne        is_constructible<_SecondType<_DependentTp...>, _Up2>,
923a3ab5120SLouis Dionne        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
924a3ab5120SLouis Dionne        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
925a3ab5120SLouis Dionne    > { };
926a3ab5120SLouis Dionne
927b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
928a3ab5120SLouis Dionne        _And<
929a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
930a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
931a3ab5120SLouis Dionne        >::value
932a3ab5120SLouis Dionne    , int> = 0>
933ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
934a3ab5120SLouis Dionne    tuple(pair<_Up1, _Up2>&& __p)
935a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
936a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
937a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
938a3ab5120SLouis Dionne        >::value))
939a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
940a3ab5120SLouis Dionne    { }
941a3ab5120SLouis Dionne
942b4e88d4dSLouis Dionne    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
943a3ab5120SLouis Dionne        _And<
944a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
945a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
946a3ab5120SLouis Dionne        >::value
947a3ab5120SLouis Dionne    , int> = 0>
948ef89e8caSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
949a3ab5120SLouis Dionne    explicit tuple(pair<_Up1, _Up2>&& __p)
950a3ab5120SLouis Dionne        _NOEXCEPT_((_And<
951a3ab5120SLouis Dionne            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
952a3ab5120SLouis Dionne            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
953a3ab5120SLouis Dionne        >::value))
954a3ab5120SLouis Dionne        : __base_(_VSTD::move(__p))
955a3ab5120SLouis Dionne    { }
956a3ab5120SLouis Dionne
957b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
958a3ab5120SLouis Dionne        _And<
959a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
960a3ab5120SLouis Dionne            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
961a3ab5120SLouis Dionne        >::value
962a3ab5120SLouis Dionne    , int> = 0>
963a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
964a3ab5120SLouis Dionne    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
965a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
966a3ab5120SLouis Dionne    { }
967a3ab5120SLouis Dionne
968b4e88d4dSLouis Dionne    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
969a3ab5120SLouis Dionne        _And<
970a3ab5120SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
971a3ab5120SLouis Dionne            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
972a3ab5120SLouis Dionne        >::value
973a3ab5120SLouis Dionne    , int> = 0>
974a3ab5120SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
975a3ab5120SLouis Dionne    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
976a3ab5120SLouis Dionne        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
977a3ab5120SLouis Dionne    { }
9789795699aSEric Fiselier
979a0839b14SLouis Dionne    // [tuple.assign]
98006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
981a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
982a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
983aedcbf89SEric Fiselier    {
984a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
985a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
986aedcbf89SEric Fiselier        return *this;
987aedcbf89SEric Fiselier    }
988aedcbf89SEric Fiselier
98906e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
990a0839b14SLouis Dionne    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
991a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
992aedcbf89SEric Fiselier    {
993a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
994a0839b14SLouis Dionne            __tuple_types<_Tp...>(),
995a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
996aedcbf89SEric Fiselier        return *this;
997aedcbf89SEric Fiselier    }
998aedcbf89SEric Fiselier
999b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
1000a0839b14SLouis Dionne        _And<
1001a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1002a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
1003a0839b14SLouis Dionne        >::value
1004a0839b14SLouis Dionne    ,int> = 0>
100506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1006a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...> const& __tuple)
1007a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
10083e519524SHoward Hinnant    {
1009a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __tuple,
1010a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
10113e519524SHoward Hinnant        return *this;
10123e519524SHoward Hinnant    }
10133e519524SHoward Hinnant
1014b4e88d4dSLouis Dionne    template<class... _Up, __enable_if_t<
1015a0839b14SLouis Dionne        _And<
1016a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1017a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
1018a0839b14SLouis Dionne        >::value
1019a0839b14SLouis Dionne    ,int> = 0>
102006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1021a0839b14SLouis Dionne    tuple& operator=(tuple<_Up...>&& __tuple)
1022a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1023a0839b14SLouis Dionne    {
1024a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1025a0839b14SLouis Dionne            __tuple_types<_Up...>(),
1026a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1027a0839b14SLouis Dionne        return *this;
1028a0839b14SLouis Dionne    }
1029a0839b14SLouis Dionne
1030b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1031a0839b14SLouis Dionne        _And<_Dep,
1032a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1033a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1034a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1035a0839b14SLouis Dionne        >::value
1036a0839b14SLouis Dionne    ,int> = 0>
103706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1038a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1039a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1040a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1041a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1042a0839b14SLouis Dionne        >::value))
1043a0839b14SLouis Dionne    {
1044a0839b14SLouis Dionne        _VSTD::get<0>(*this) = __pair.first;
1045a0839b14SLouis Dionne        _VSTD::get<1>(*this) = __pair.second;
1046a0839b14SLouis Dionne        return *this;
1047a0839b14SLouis Dionne    }
1048a0839b14SLouis Dionne
1049b4e88d4dSLouis Dionne    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1050a0839b14SLouis Dionne        _And<_Dep,
1051a0839b14SLouis Dionne            _BoolConstant<sizeof...(_Tp) == 2>,
1052a0839b14SLouis Dionne            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1053a0839b14SLouis Dionne            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1054a0839b14SLouis Dionne        >::value
1055a0839b14SLouis Dionne    ,int> = 0>
105606e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1057a0839b14SLouis Dionne    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1058a0839b14SLouis Dionne        _NOEXCEPT_((_And<
1059a0839b14SLouis Dionne            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1060a0839b14SLouis Dionne            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1061a0839b14SLouis Dionne        >::value))
1062a0839b14SLouis Dionne    {
1063618862e8SLouis Dionne        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1064618862e8SLouis Dionne        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1065a0839b14SLouis Dionne        return *this;
1066a0839b14SLouis Dionne    }
1067a0839b14SLouis Dionne
1068a0839b14SLouis Dionne    // EXTENSION
1069b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = __enable_if_t<
1070a0839b14SLouis Dionne        _And<
1071a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1072a0839b14SLouis Dionne            is_assignable<_Tp&, _Up const&>...
1073a0839b14SLouis Dionne        >::value
1074a0839b14SLouis Dionne    > >
107506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1076a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np> const& __array)
1077a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1078a0839b14SLouis Dionne    {
1079a0839b14SLouis Dionne        _VSTD::__memberwise_copy_assign(*this, __array,
1080a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1081a0839b14SLouis Dionne        return *this;
1082a0839b14SLouis Dionne    }
1083a0839b14SLouis Dionne
1084a0839b14SLouis Dionne    // EXTENSION
1085b4e88d4dSLouis Dionne    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1086a0839b14SLouis Dionne        _And<
1087a0839b14SLouis Dionne            _BoolConstant<_Np == sizeof...(_Tp)>,
1088a0839b14SLouis Dionne            is_assignable<_Tp&, _Up>...
1089a0839b14SLouis Dionne        >::value
1090a0839b14SLouis Dionne    > >
109106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1092a0839b14SLouis Dionne    tuple& operator=(array<_Up, _Np>&& __array)
1093a0839b14SLouis Dionne        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1094a0839b14SLouis Dionne    {
1095a0839b14SLouis Dionne        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1096a0839b14SLouis Dionne            __tuple_types<_If<true, _Up, _Tp>...>(),
1097a0839b14SLouis Dionne            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1098a0839b14SLouis Dionne        return *this;
1099a0839b14SLouis Dionne    }
1100a0839b14SLouis Dionne
1101a0839b14SLouis Dionne    // [tuple.swap]
110206e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
110327d0a2a7SHoward Hinnant    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1104def3c375SEric Fiselier        {__base_.swap(__t.__base_);}
11053e519524SHoward Hinnant};
11063e519524SHoward Hinnant
11073e519524SHoward Hinnanttemplate <>
1108e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS tuple<>
11093e519524SHoward Hinnant{
11103e519524SHoward Hinnantpublic:
111106e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr
111206e2b737SArthur O'Dwyer        tuple() _NOEXCEPT = default;
11133e519524SHoward Hinnant    template <class _Alloc>
111406e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11158a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
11163e519524SHoward Hinnant    template <class _Alloc>
111706e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11188a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1119c003db1fSHoward Hinnant    template <class _Up>
112006e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11218a9ee148SHoward Hinnant        tuple(array<_Up, 0>) _NOEXCEPT {}
1122c003db1fSHoward Hinnant    template <class _Alloc, class _Up>
112306e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11248a9ee148SHoward Hinnant        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
112506e2b737SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
112627d0a2a7SHoward Hinnant    void swap(tuple&) _NOEXCEPT {}
11273e519524SHoward Hinnant};
11283e519524SHoward Hinnant
1129b2a0cc1cSArthur O'Dwyer#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1130311207bbSNikolas Klausertemplate <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
1131311207bbSNikolas Klauser    requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
1132311207bbSNikolas Klauserstruct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
1133311207bbSNikolas Klauser    using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
1134311207bbSNikolas Klauser};
1135311207bbSNikolas Klauser
1136311207bbSNikolas Klausertemplate <class... _TTypes, class... _UTypes>
1137311207bbSNikolas Klauser    requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
1138311207bbSNikolas Klauserstruct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
1139311207bbSNikolas Klauser    using type = tuple<common_type_t<_TTypes, _UTypes>...>;
1140311207bbSNikolas Klauser};
1141b2a0cc1cSArthur O'Dwyer#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1142311207bbSNikolas Klauser
1143311207bbSNikolas Klauser#if _LIBCPP_STD_VER > 14
11441308011eSLouis Dionnetemplate <class ..._Tp>
11451308011eSLouis Dionnetuple(_Tp...) -> tuple<_Tp...>;
11461308011eSLouis Dionnetemplate <class _Tp1, class _Tp2>
11471308011eSLouis Dionnetuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11481308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11491308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
11501308011eSLouis Dionnetemplate <class _Alloc, class _Tp1, class _Tp2>
11511308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
11521308011eSLouis Dionnetemplate <class _Alloc, class ..._Tp>
11531308011eSLouis Dionnetuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1154baaee206SEric Fiselier#endif
1155baaee206SEric Fiselier
11563e519524SHoward Hinnanttemplate <class ..._Tp>
115706e2b737SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1158bc95cf0dSHoward Hinnanttypename enable_if
1159bc95cf0dSHoward Hinnant<
1160bc95cf0dSHoward Hinnant    __all<__is_swappable<_Tp>::value...>::value,
11613e519524SHoward Hinnant    void
1162bc95cf0dSHoward Hinnant>::type
116327d0a2a7SHoward Hinnantswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
116427d0a2a7SHoward Hinnant                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
116527d0a2a7SHoward Hinnant    {__t.swap(__u);}
11663e519524SHoward Hinnant
11673e519524SHoward Hinnant// get
11683e519524SHoward Hinnant
11693e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11708bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11713e519524SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&
1172c206366fSHoward Hinnantget(tuple<_Tp...>& __t) _NOEXCEPT
11733e519524SHoward Hinnant{
11743557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1175def3c375SEric Fiselier    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
11763e519524SHoward Hinnant}
11773e519524SHoward Hinnant
11783e519524SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11798bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11803e519524SHoward Hinnantconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
1181c206366fSHoward Hinnantget(const tuple<_Tp...>& __t) _NOEXCEPT
11823e519524SHoward Hinnant{
11833557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1184def3c375SEric Fiselier    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
11853e519524SHoward Hinnant}
11863e519524SHoward Hinnant
1187601afb30SHoward Hinnanttemplate <size_t _Ip, class ..._Tp>
11888bf1f08aSMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1189601afb30SHoward Hinnanttypename tuple_element<_Ip, tuple<_Tp...> >::type&&
1190c206366fSHoward Hinnantget(tuple<_Tp...>&& __t) _NOEXCEPT
1191601afb30SHoward Hinnant{
11923557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11932a3f1bc1SHoward Hinnant    return static_cast<type&&>(
1194def3c375SEric Fiselier             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1195601afb30SHoward Hinnant}
1196601afb30SHoward Hinnant
1197545b8861SEric Fiseliertemplate <size_t _Ip, class ..._Tp>
1198545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1199545b8861SEric Fiselierconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1200545b8861SEric Fiselierget(const tuple<_Tp...>&& __t) _NOEXCEPT
1201545b8861SEric Fiselier{
12023557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1203545b8861SEric Fiselier    return static_cast<const type&&>(
1204def3c375SEric Fiselier             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1205545b8861SEric Fiselier}
1206545b8861SEric Fiselier
1207e99520c7SMarshall Clow#if _LIBCPP_STD_VER > 11
1208e99520c7SMarshall Clow
1209f447e62eSEric Fiseliernamespace __find_detail {
1210f447e62eSEric Fiselier
1211f86570cdSLouis Dionnestatic constexpr size_t __not_found = static_cast<size_t>(-1);
1212f447e62eSEric Fiselierstatic constexpr size_t __ambiguous = __not_found - 1;
1213f447e62eSEric Fiselier
1214f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1215f447e62eSEric Fiselierconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1216f447e62eSEric Fiselier    return !__matches ? __res :
1217f447e62eSEric Fiselier        (__res == __not_found ? __curr_i : __ambiguous);
1218f447e62eSEric Fiselier}
1219f447e62eSEric Fiselier
1220f447e62eSEric Fiseliertemplate <size_t _Nx>
1221f447e62eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1222f447e62eSEric Fiselierconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1223f447e62eSEric Fiselier  return __i == _Nx ? __not_found :
1224f447e62eSEric Fiselier      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1225f447e62eSEric Fiselier}
1226f447e62eSEric Fiselier
1227f447e62eSEric Fiseliertemplate <class _T1, class ..._Args>
1228f447e62eSEric Fiselierstruct __find_exactly_one_checked {
122900c872f3SCasey Carter    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1230f447e62eSEric Fiselier    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1231f447e62eSEric Fiselier    static_assert(value != __not_found, "type not found in type list" );
1232f447e62eSEric Fiselier    static_assert(value != __ambiguous, "type occurs more than once in type list");
1233e99520c7SMarshall Clow};
1234e99520c7SMarshall Clow
12354f905b8dSEric Fiseliertemplate <class _T1>
12364f905b8dSEric Fiselierstruct __find_exactly_one_checked<_T1> {
12374f905b8dSEric Fiselier    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
12384f905b8dSEric Fiselier};
12394f905b8dSEric Fiselier
1240d2b0df35SNikolas Klauser} // namespace __find_detail
1241e99520c7SMarshall Clow
1242e99520c7SMarshall Clowtemplate <typename _T1, typename... _Args>
1243f447e62eSEric Fiselierstruct __find_exactly_one_t
1244f447e62eSEric Fiselier    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1245e99520c7SMarshall Clow};
1246e99520c7SMarshall Clow
1247e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1248e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1249e99520c7SMarshall Clowconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
1250e99520c7SMarshall Clow{
1251e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1252e99520c7SMarshall Clow}
1253e99520c7SMarshall Clow
1254e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1255e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1256e99520c7SMarshall Clowconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1257e99520c7SMarshall Clow{
1258e99520c7SMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1259e99520c7SMarshall Clow}
1260e99520c7SMarshall Clow
1261e99520c7SMarshall Clowtemplate <class _T1, class... _Args>
1262e99520c7SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
1263e99520c7SMarshall Clowconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1264e99520c7SMarshall Clow{
12651c682f0fSMarshall Clow    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1266e99520c7SMarshall Clow}
1267e99520c7SMarshall Clow
1268545b8861SEric Fiseliertemplate <class _T1, class... _Args>
1269545b8861SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
1270545b8861SEric Fiselierconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1271545b8861SEric Fiselier{
1272545b8861SEric Fiselier    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1273545b8861SEric Fiselier}
1274545b8861SEric Fiselier
1275e99520c7SMarshall Clow#endif
1276e99520c7SMarshall Clow
12773e519524SHoward Hinnant// tie
12783e519524SHoward Hinnant
12793e519524SHoward Hinnanttemplate <class ..._Tp>
12800d1560e1SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12813e519524SHoward Hinnanttuple<_Tp&...>
12828a9ee148SHoward Hinnanttie(_Tp&... __t) _NOEXCEPT
12833e519524SHoward Hinnant{
12843e519524SHoward Hinnant    return tuple<_Tp&...>(__t...);
12853e519524SHoward Hinnant}
12863e519524SHoward Hinnant
12873e519524SHoward Hinnanttemplate <class _Up>
12883e519524SHoward Hinnantstruct __ignore_t
12893e519524SHoward Hinnant{
12903e519524SHoward Hinnant    template <class _Tp>
12919af60c4aSEric Fiselier    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12923e519524SHoward Hinnant    const __ignore_t& operator=(_Tp&&) const {return *this;}
12933e519524SHoward Hinnant};
12943e519524SHoward Hinnant
12959af60c4aSEric Fiseliernamespace {
1296cb793e1aSLouis Dionne  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1297d2b0df35SNikolas Klauser} // namespace
12983e519524SHoward Hinnant
12993e519524SHoward Hinnanttemplate <class... _Tp>
130075eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1301bb9ca6d0SLouis Dionnetuple<typename __unwrap_ref_decay<_Tp>::type...>
13023e519524SHoward Hinnantmake_tuple(_Tp&&... __t)
13033e519524SHoward Hinnant{
1304bb9ca6d0SLouis Dionne    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
13053e519524SHoward Hinnant}
13063e519524SHoward Hinnant
13071102fbbdSHoward Hinnanttemplate <class... _Tp>
130875eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
130975eff748SMarshall Clowtuple<_Tp&&...>
13108a9ee148SHoward Hinnantforward_as_tuple(_Tp&&... __t) _NOEXCEPT
13111102fbbdSHoward Hinnant{
1312ce48a113SHoward Hinnant    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
13131102fbbdSHoward Hinnant}
13141102fbbdSHoward Hinnant
1315c003db1fSHoward Hinnanttemplate <size_t _Ip>
13163e519524SHoward Hinnantstruct __tuple_equal
13173e519524SHoward Hinnant{
13183e519524SHoward Hinnant    template <class _Tp, class _Up>
131975eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13203e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
13213e519524SHoward Hinnant    {
1322f9af6140SMarshall Clow        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
13233e519524SHoward Hinnant    }
13243e519524SHoward Hinnant};
13253e519524SHoward Hinnant
13263e519524SHoward Hinnanttemplate <>
13273e519524SHoward Hinnantstruct __tuple_equal<0>
13283e519524SHoward Hinnant{
13293e519524SHoward Hinnant    template <class _Tp, class _Up>
133075eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13313e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
13323e519524SHoward Hinnant    {
13333e519524SHoward Hinnant        return true;
13343e519524SHoward Hinnant    }
13353e519524SHoward Hinnant};
13363e519524SHoward Hinnant
13373e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
133875eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13393e519524SHoward Hinnantbool
13403e519524SHoward Hinnantoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13413e519524SHoward Hinnant{
1342aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13433e519524SHoward Hinnant    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
13443e519524SHoward Hinnant}
13453e519524SHoward Hinnant
134638db42d0SArthur O'Dwyer#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
1347b80f2dfdSKent Ross
1348b80f2dfdSKent Ross// operator<=>
1349b80f2dfdSKent Ross
1350b80f2dfdSKent Rosstemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1351b80f2dfdSKent Ross_LIBCPP_HIDE_FROM_ABI constexpr
1352b80f2dfdSKent Rossauto
1353b80f2dfdSKent Ross__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1354b80f2dfdSKent Ross    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1355b80f2dfdSKent Ross    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1356b80f2dfdSKent Ross    return __result;
1357b80f2dfdSKent Ross}
1358b80f2dfdSKent Ross
1359b80f2dfdSKent Rosstemplate <class ..._Tp, class ..._Up>
1360b80f2dfdSKent Rossrequires (sizeof...(_Tp) == sizeof...(_Up))
1361b80f2dfdSKent Ross_LIBCPP_HIDE_FROM_ABI constexpr
1362b80f2dfdSKent Rosscommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1363b80f2dfdSKent Rossoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1364b80f2dfdSKent Ross{
1365b80f2dfdSKent Ross    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1366b80f2dfdSKent Ross}
1367b80f2dfdSKent Ross
136838db42d0SArthur O'Dwyer#else // !defined(_LIBCPP_HAS_NO_CONCEPTS)
1369b80f2dfdSKent Ross
13703e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
137175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13723e519524SHoward Hinnantbool
13733e519524SHoward Hinnantoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13743e519524SHoward Hinnant{
13753e519524SHoward Hinnant    return !(__x == __y);
13763e519524SHoward Hinnant}
13773e519524SHoward Hinnant
1378c003db1fSHoward Hinnanttemplate <size_t _Ip>
13793e519524SHoward Hinnantstruct __tuple_less
13803e519524SHoward Hinnant{
13813e519524SHoward Hinnant    template <class _Tp, class _Up>
138275eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13833e519524SHoward Hinnant    bool operator()(const _Tp& __x, const _Up& __y)
13843e519524SHoward Hinnant    {
138553afae49SDuncan P. N. Exon Smith        const size_t __idx = tuple_size<_Tp>::value - _Ip;
138653afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
138753afae49SDuncan P. N. Exon Smith            return true;
138853afae49SDuncan P. N. Exon Smith        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
138953afae49SDuncan P. N. Exon Smith            return false;
139053afae49SDuncan P. N. Exon Smith        return __tuple_less<_Ip-1>()(__x, __y);
13913e519524SHoward Hinnant    }
13923e519524SHoward Hinnant};
13933e519524SHoward Hinnant
13943e519524SHoward Hinnanttemplate <>
13953e519524SHoward Hinnantstruct __tuple_less<0>
13963e519524SHoward Hinnant{
13973e519524SHoward Hinnant    template <class _Tp, class _Up>
139875eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13993e519524SHoward Hinnant    bool operator()(const _Tp&, const _Up&)
14003e519524SHoward Hinnant    {
14013e519524SHoward Hinnant        return false;
14023e519524SHoward Hinnant    }
14033e519524SHoward Hinnant};
14043e519524SHoward Hinnant
14053e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
140675eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14073e519524SHoward Hinnantbool
14083e519524SHoward Hinnantoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
14093e519524SHoward Hinnant{
1410aa09911aSMarshall Clow    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
14113e519524SHoward Hinnant    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
14123e519524SHoward Hinnant}
14133e519524SHoward Hinnant
14143e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
141575eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14163e519524SHoward Hinnantbool
14173e519524SHoward Hinnantoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
14183e519524SHoward Hinnant{
14193e519524SHoward Hinnant    return __y < __x;
14203e519524SHoward Hinnant}
14213e519524SHoward Hinnant
14223e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
142375eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14243e519524SHoward Hinnantbool
14253e519524SHoward Hinnantoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
14263e519524SHoward Hinnant{
14273e519524SHoward Hinnant    return !(__x < __y);
14283e519524SHoward Hinnant}
14293e519524SHoward Hinnant
14303e519524SHoward Hinnanttemplate <class ..._Tp, class ..._Up>
143175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14323e519524SHoward Hinnantbool
14333e519524SHoward Hinnantoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
14343e519524SHoward Hinnant{
14353e519524SHoward Hinnant    return !(__y < __x);
14363e519524SHoward Hinnant}
14373e519524SHoward Hinnant
143838db42d0SArthur O'Dwyer#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
1439b80f2dfdSKent Ross
14403e519524SHoward Hinnant// tuple_cat
14413e519524SHoward Hinnant
14427f64810bSHoward Hinnanttemplate <class _Tp, class _Up> struct __tuple_cat_type;
14437f64810bSHoward Hinnant
14447f64810bSHoward Hinnanttemplate <class ..._Ttypes, class ..._Utypes>
14457f64810bSHoward Hinnantstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
14463e519524SHoward Hinnant{
14473557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
14487f64810bSHoward Hinnant};
14497f64810bSHoward Hinnant
14507f64810bSHoward Hinnanttemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
14517f64810bSHoward Hinnantstruct __tuple_cat_return_1
14527f64810bSHoward Hinnant{
14537f64810bSHoward Hinnant};
14547f64810bSHoward Hinnant
14557f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0>
14567f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
14577f64810bSHoward Hinnant{
14583557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename __tuple_cat_type<tuple<_Types...>,
14597e528bc4SEric Fiselier            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
14607f64810bSHoward Hinnant                                                                           type;
14617f64810bSHoward Hinnant};
14627f64810bSHoward Hinnant
14637f64810bSHoward Hinnanttemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
14647f64810bSHoward Hinnantstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
14657f64810bSHoward Hinnant    : public __tuple_cat_return_1<
14667f64810bSHoward Hinnant                 typename __tuple_cat_type<
14677f64810bSHoward Hinnant                     tuple<_Types...>,
14687e528bc4SEric Fiselier                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
14697f64810bSHoward Hinnant                 >::type,
14707f64810bSHoward Hinnant                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
14717f64810bSHoward Hinnant                 _Tuple1, _Tuples...>
14727f64810bSHoward Hinnant{
14737f64810bSHoward Hinnant};
14747f64810bSHoward Hinnant
14757f64810bSHoward Hinnanttemplate <class ..._Tuples> struct __tuple_cat_return;
14767f64810bSHoward Hinnant
14777f64810bSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
14787f64810bSHoward Hinnantstruct __tuple_cat_return<_Tuple0, _Tuples...>
14797f64810bSHoward Hinnant    : public __tuple_cat_return_1<tuple<>,
14807f64810bSHoward Hinnant         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
14817f64810bSHoward Hinnant                                                                     _Tuples...>
14827f64810bSHoward Hinnant{
14837f64810bSHoward Hinnant};
14847f64810bSHoward Hinnant
14857f64810bSHoward Hinnanttemplate <>
14867f64810bSHoward Hinnantstruct __tuple_cat_return<>
14877f64810bSHoward Hinnant{
14883557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG tuple<> type;
14897f64810bSHoward Hinnant};
14907f64810bSHoward Hinnant
149175eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14927f64810bSHoward Hinnanttuple<>
14937f64810bSHoward Hinnanttuple_cat()
14947f64810bSHoward Hinnant{
14957f64810bSHoward Hinnant    return tuple<>();
14963e519524SHoward Hinnant}
14973e519524SHoward Hinnant
1498c003db1fSHoward Hinnanttemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1499ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp;
15003e519524SHoward Hinnant
1501ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1502ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
15033e519524SHoward Hinnant{
15043557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1505ba31cbdbSHoward Hinnant    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1506ba31cbdbSHoward Hinnant                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1507ba31cbdbSHoward Hinnant};
1508ba31cbdbSHoward Hinnant
1509ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1510ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1511ba31cbdbSHoward Hinnant                                  _Tuple0, _Tuple1, _Tuples...>
1512ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<
1513ba31cbdbSHoward Hinnant         tuple<_Types..., typename __apply_cv<_Tuple0,
1514ba31cbdbSHoward Hinnant               typename tuple_element<_I0,
1515ba31cbdbSHoward Hinnant                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1516ba31cbdbSHoward Hinnant         typename __make_tuple_indices<tuple_size<typename
1517ba31cbdbSHoward Hinnant                                 remove_reference<_Tuple1>::type>::value>::type,
1518ba31cbdbSHoward Hinnant         _Tuple1, _Tuples...>
1519ba31cbdbSHoward Hinnant{
1520ba31cbdbSHoward Hinnant};
1521ba31cbdbSHoward Hinnant
1522ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class ..._Tuples>
1523ba31cbdbSHoward Hinnantstruct __tuple_cat_return_ref
1524ba31cbdbSHoward Hinnant    : public __tuple_cat_return_ref_imp<tuple<>,
1525ba31cbdbSHoward Hinnant               typename __make_tuple_indices<
1526ba31cbdbSHoward Hinnant                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1527ba31cbdbSHoward Hinnant               >::type, _Tuple0, _Tuples...>
1528ba31cbdbSHoward Hinnant{
1529ba31cbdbSHoward Hinnant};
1530ba31cbdbSHoward Hinnant
1531ba31cbdbSHoward Hinnanttemplate <class _Types, class _I0, class _J0>
1532ba31cbdbSHoward Hinnantstruct __tuple_cat;
1533ba31cbdbSHoward Hinnant
1534ba31cbdbSHoward Hinnanttemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1535ba31cbdbSHoward Hinnantstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1536ba31cbdbSHoward Hinnant{
1537ba31cbdbSHoward Hinnant    template <class _Tuple0>
153875eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1539ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1540ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1541ba31cbdbSHoward Hinnant    {
1542e658b3ebSDavid Blaikie        return _VSTD::forward_as_tuple(
1543e658b3ebSDavid Blaikie            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1544f9af6140SMarshall Clow            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
15453e519524SHoward Hinnant    }
15463e519524SHoward Hinnant
15477f64810bSHoward Hinnant    template <class _Tuple0, class _Tuple1, class ..._Tuples>
154875eff748SMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1549ba31cbdbSHoward Hinnant    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1550ba31cbdbSHoward Hinnant    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
15513e519524SHoward Hinnant    {
15523557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
15533557c7c1SLouis Dionne        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
1554ba31cbdbSHoward Hinnant        return __tuple_cat<
1555e658b3ebSDavid Blaikie            tuple<_Types...,
1556e658b3ebSDavid Blaikie                  typename __apply_cv<_Tuple0, typename tuple_element<
1557e658b3ebSDavid Blaikie                                                   _J0, _T0>::type>::type&&...>,
1558e658b3ebSDavid Blaikie            typename __make_tuple_indices<sizeof...(_Types) +
1559e658b3ebSDavid Blaikie                                          tuple_size<_T0>::value>::type,
1560e658b3ebSDavid Blaikie            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1561e658b3ebSDavid Blaikie            _VSTD::forward_as_tuple(
1562f9af6140SMarshall Clow                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1563e658b3ebSDavid Blaikie                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1564e658b3ebSDavid Blaikie            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1565ba31cbdbSHoward Hinnant    }
1566ba31cbdbSHoward Hinnant};
1567ba31cbdbSHoward Hinnant
1568ba31cbdbSHoward Hinnanttemplate <class _Tuple0, class... _Tuples>
156975eff748SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1570ba31cbdbSHoward Hinnanttypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1571ba31cbdbSHoward Hinnanttuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1572ba31cbdbSHoward Hinnant{
15733557c7c1SLouis Dionne    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1574ba31cbdbSHoward Hinnant    return __tuple_cat<tuple<>, __tuple_indices<>,
1575ba31cbdbSHoward Hinnant                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1576ce48a113SHoward Hinnant                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1577ce48a113SHoward Hinnant                                            _VSTD::forward<_Tuples>(__tpls)...);
15783e519524SHoward Hinnant}
15793e519524SHoward Hinnant
15803e519524SHoward Hinnanttemplate <class ..._Tp, class _Alloc>
1581e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
15823e519524SHoward Hinnant    : true_type {};
15833e519524SHoward Hinnant
15843e519524SHoward Hinnanttemplate <class _T1, class _T2>
15853e519524SHoward Hinnanttemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1586737a4501SMichael Schellenberger Costainline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15873e519524SHoward Hinnantpair<_T1, _T2>::pair(piecewise_construct_t,
15883e519524SHoward Hinnant                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
15893e519524SHoward Hinnant                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1590f9af6140SMarshall Clow    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1591f9af6140SMarshall Clow      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
15923e519524SHoward Hinnant{
15933e519524SHoward Hinnant}
15943e519524SHoward Hinnant
159503e29a29SEric Fiselier#if _LIBCPP_STD_VER > 14
159603e29a29SEric Fiseliertemplate <class _Tp>
1597cb793e1aSLouis Dionneinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
159803e29a29SEric Fiselier
159903e29a29SEric Fiselier#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
160003e29a29SEric Fiselier
160103e29a29SEric Fiseliertemplate <class _Fn, class _Tuple, size_t ..._Id>
160203e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
160303e29a29SEric Fiselierconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
160403e29a29SEric Fiselier                                            __tuple_indices<_Id...>)
160503e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
160603e29a29SEric Fiselier    _VSTD::__invoke_constexpr(
160703e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f),
160803e29a29SEric Fiselier        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
160903e29a29SEric Fiselier)
161003e29a29SEric Fiselier
161103e29a29SEric Fiseliertemplate <class _Fn, class _Tuple>
161203e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
161303e29a29SEric Fiselierconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
161403e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
161503e29a29SEric Fiselier    _VSTD::__apply_tuple_impl(
161603e29a29SEric Fiselier        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1617655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
161803e29a29SEric Fiselier)
161903e29a29SEric Fiselier
162003e29a29SEric Fiseliertemplate <class _Tp, class _Tuple, size_t... _Idx>
162103e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
162203e29a29SEric Fiselierconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
162303e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
162403e29a29SEric Fiselier    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
162503e29a29SEric Fiselier)
162603e29a29SEric Fiselier
162703e29a29SEric Fiseliertemplate <class _Tp, class _Tuple>
162803e29a29SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
162903e29a29SEric Fiselierconstexpr _Tp make_from_tuple(_Tuple&& __t)
163003e29a29SEric Fiselier_LIBCPP_NOEXCEPT_RETURN(
163103e29a29SEric Fiselier    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1632655c4695SMarshall Clow        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
163303e29a29SEric Fiselier)
163403e29a29SEric Fiselier
163503e29a29SEric Fiselier#undef _LIBCPP_NOEXCEPT_RETURN
163603e29a29SEric Fiselier
163703e29a29SEric Fiselier#endif // _LIBCPP_STD_VER > 14
163803e29a29SEric Fiselier
163929870871SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
164029870871SEric Fiselier
16413e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
16423e519524SHoward Hinnant
16433e519524SHoward Hinnant#endif // _LIBCPP_TUPLE
1644