xref: /freebsd/contrib/llvm-project/libcxx/include/tuple (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric// -*- C++ -*-
2*349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_TUPLE
110b57cec5SDimitry Andric#define _LIBCPP_TUPLE
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    tuple synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate <class... T>
200b57cec5SDimitry Andricclass tuple {
210b57cec5SDimitry Andricpublic:
22e40139ffSDimitry Andric    explicit(see-below) constexpr tuple();
23e40139ffSDimitry Andric    explicit(see-below) tuple(const T&...);  // constexpr in C++14
240b57cec5SDimitry Andric    template <class... U>
25e40139ffSDimitry Andric        explicit(see-below) tuple(U&&...);  // constexpr in C++14
260b57cec5SDimitry Andric    tuple(const tuple&) = default;
270b57cec5SDimitry Andric    tuple(tuple&&) = default;
280b57cec5SDimitry Andric    template <class... U>
29e40139ffSDimitry Andric        explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
300b57cec5SDimitry Andric    template <class... U>
31e40139ffSDimitry Andric        explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
320b57cec5SDimitry Andric    template <class U1, class U2>
33e40139ffSDimitry Andric        explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
340b57cec5SDimitry Andric    template <class U1, class U2>
35e40139ffSDimitry Andric        explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric    // allocator-extended constructors
380b57cec5SDimitry Andric    template <class Alloc>
390b57cec5SDimitry Andric        tuple(allocator_arg_t, const Alloc& a);
400b57cec5SDimitry Andric    template <class Alloc>
41fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
420b57cec5SDimitry Andric    template <class Alloc, class... U>
43fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
440b57cec5SDimitry Andric    template <class Alloc>
45fe6060f1SDimitry Andric        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
460b57cec5SDimitry Andric    template <class Alloc>
47fe6060f1SDimitry Andric        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
480b57cec5SDimitry Andric    template <class Alloc, class... U>
49fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
500b57cec5SDimitry Andric    template <class Alloc, class... U>
51fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
520b57cec5SDimitry Andric    template <class Alloc, class U1, class U2>
53fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
540b57cec5SDimitry Andric    template <class Alloc, class U1, class U2>
55fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
560b57cec5SDimitry Andric
57fe6060f1SDimitry Andric    tuple& operator=(const tuple&);                                                       // constexpr in C++20
58fe6060f1SDimitry Andric    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
590b57cec5SDimitry Andric    template <class... U>
60fe6060f1SDimitry Andric        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
610b57cec5SDimitry Andric    template <class... U>
62fe6060f1SDimitry Andric        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
630b57cec5SDimitry Andric    template <class U1, class U2>
64fe6060f1SDimitry Andric        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
650b57cec5SDimitry Andric    template <class U1, class U2>
66fe6060f1SDimitry Andric        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
670b57cec5SDimitry Andric
68fe6060f1SDimitry Andric    template<class U, size_t N>
69fe6060f1SDimitry Andric        tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70fe6060f1SDimitry Andric    template<class U, size_t N>
71fe6060f1SDimitry Andric        tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72fe6060f1SDimitry Andric
73fe6060f1SDimitry Andric    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
740b57cec5SDimitry Andric};
750b57cec5SDimitry Andric
76e40139ffSDimitry Andrictemplate <class ...T>
77e40139ffSDimitry Andrictuple(T...) -> tuple<T...>;                                         // since C++17
78e40139ffSDimitry Andrictemplate <class T1, class T2>
79e40139ffSDimitry Andrictuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
80e40139ffSDimitry Andrictemplate <class Alloc, class ...T>
81e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
82e40139ffSDimitry Andrictemplate <class Alloc, class T1, class T2>
83e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
84e40139ffSDimitry Andrictemplate <class Alloc, class ...T>
85e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
86e40139ffSDimitry Andric
870b57cec5SDimitry Andricinline constexpr unspecified ignore;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andrictemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
900b57cec5SDimitry Andrictemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
910b57cec5SDimitry Andrictemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
920b57cec5SDimitry Andrictemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric// [tuple.apply], calling a function with a tuple of arguments:
950b57cec5SDimitry Andrictemplate <class F, class Tuple>
960b57cec5SDimitry Andric  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
970b57cec5SDimitry Andrictemplate <class T, class Tuple>
980b57cec5SDimitry Andric  constexpr T make_from_tuple(Tuple&& t); // C++17
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric// 20.4.1.4, tuple helper classes:
1010b57cec5SDimitry Andrictemplate <class T> struct tuple_size; // undefined
1020b57cec5SDimitry Andrictemplate <class... T> struct tuple_size<tuple<T...>>;
1030b57cec5SDimitry Andrictemplate <class T>
1040b57cec5SDimitry Andric inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
1050b57cec5SDimitry Andrictemplate <size_t I, class T> struct tuple_element; // undefined
1060b57cec5SDimitry Andrictemplate <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
1070b57cec5SDimitry Andrictemplate <size_t I, class T>
1080b57cec5SDimitry Andric  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric// 20.4.1.5, element access:
1110b57cec5SDimitry Andrictemplate <size_t I, class... T>
1120b57cec5SDimitry Andric    typename tuple_element<I, tuple<T...>>::type&
1130b57cec5SDimitry Andric    get(tuple<T...>&) noexcept; // constexpr in C++14
1140b57cec5SDimitry Andrictemplate <size_t I, class... T>
1150b57cec5SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&
1160b57cec5SDimitry Andric    get(const tuple<T...>&) noexcept; // constexpr in C++14
1170b57cec5SDimitry Andrictemplate <size_t I, class... T>
1180b57cec5SDimitry Andric    typename tuple_element<I, tuple<T...>>::type&&
1190b57cec5SDimitry Andric    get(tuple<T...>&&) noexcept; // constexpr in C++14
1200b57cec5SDimitry Andrictemplate <size_t I, class... T>
1210b57cec5SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&&
1220b57cec5SDimitry Andric    get(const tuple<T...>&&) noexcept; // constexpr in C++14
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andrictemplate <class T1, class... T>
1250b57cec5SDimitry Andric    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
1260b57cec5SDimitry Andrictemplate <class T1, class... T>
1270b57cec5SDimitry Andric    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
1280b57cec5SDimitry Andrictemplate <class T1, class... T>
1290b57cec5SDimitry Andric    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
1300b57cec5SDimitry Andrictemplate <class T1, class... T>
1310b57cec5SDimitry Andric    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric// 20.4.1.6, relational operators:
1340b57cec5SDimitry Andrictemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
135*349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
136*349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
137*349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
138*349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
139*349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
140*349cc55cSDimitry Andrictemplate<class... T, class... U>
141*349cc55cSDimitry Andric  constexpr common_comparison_category_t<synth-three-way-result<T, U>...>
142*349cc55cSDimitry Andric    operator<=>(const tuple<T...>&, const tuple<U...>&);                                  // since C++20
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andrictemplate <class... Types, class Alloc>
1450b57cec5SDimitry Andric  struct uses_allocator<tuple<Types...>, Alloc>;
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andrictemplate <class... Types>
1480b57cec5SDimitry Andric  void
1490b57cec5SDimitry Andric  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1500b57cec5SDimitry Andric
1510b57cec5SDimitry Andric}  // std
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric*/
1540b57cec5SDimitry Andric
155*349cc55cSDimitry Andric#include <__compare/common_comparison_category.h>
156*349cc55cSDimitry Andric#include <__compare/synth_three_way.h>
1570b57cec5SDimitry Andric#include <__config>
158fe6060f1SDimitry Andric#include <__functional/unwrap_ref.h>
159fe6060f1SDimitry Andric#include <__functional_base>
160fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
161fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
1620b57cec5SDimitry Andric#include <__tuple>
163fe6060f1SDimitry Andric#include <__utility/forward.h>
164*349cc55cSDimitry Andric#include <__utility/integer_sequence.h>
165fe6060f1SDimitry Andric#include <__utility/move.h>
166fe6060f1SDimitry Andric#include <compare>
1670b57cec5SDimitry Andric#include <cstddef>
1680b57cec5SDimitry Andric#include <type_traits>
1690b57cec5SDimitry Andric#include <utility>
1700b57cec5SDimitry Andric#include <version>
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1730b57cec5SDimitry Andric#pragma GCC system_header
1740b57cec5SDimitry Andric#endif
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric// __tuple_leaf
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp,
1840b57cec5SDimitry Andric          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
1850b57cec5SDimitry Andric         >
1860b57cec5SDimitry Andricclass __tuple_leaf;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
189fe6060f1SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1900b57cec5SDimitry Andricvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
1910b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
1920b57cec5SDimitry Andric{
1930b57cec5SDimitry Andric    swap(__x.get(), __y.get());
1940b57cec5SDimitry Andric}
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool>
1970b57cec5SDimitry Andricclass __tuple_leaf
1980b57cec5SDimitry Andric{
1990b57cec5SDimitry Andric    _Hp __value_;
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric    template <class _Tp>
2020b57cec5SDimitry Andric    static constexpr bool __can_bind_reference() {
2030b57cec5SDimitry Andric#if __has_keyword(__reference_binds_to_temporary)
2040b57cec5SDimitry Andric      return !__reference_binds_to_temporary(_Hp, _Tp);
2050b57cec5SDimitry Andric#else
2060b57cec5SDimitry Andric      return true;
2070b57cec5SDimitry Andric#endif
2080b57cec5SDimitry Andric    }
2090b57cec5SDimitry Andric
210fe6060f1SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11
2110b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
2120b57cec5SDimitry Andricpublic:
213fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
2140b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2150b57cec5SDimitry Andric       {static_assert(!is_reference<_Hp>::value,
2160b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric    template <class _Alloc>
219fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
2200b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
2210b57cec5SDimitry Andric            : __value_()
2220b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2230b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andric    template <class _Alloc>
226fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
2270b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
2280b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a)
2290b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2300b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric    template <class _Alloc>
233fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
2340b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
2350b57cec5SDimitry Andric            : __value_(__a)
2360b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2370b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric    template <class _Tp,
240*349cc55cSDimitry Andric              class = __enable_if_t<
2410b57cec5SDimitry Andric                  _And<
2420b57cec5SDimitry Andric                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
2430b57cec5SDimitry Andric                      is_constructible<_Hp, _Tp>
2440b57cec5SDimitry Andric                    >::value
2450b57cec5SDimitry Andric                >
2460b57cec5SDimitry Andric            >
2470b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2480b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
2490b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
2500b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
2510b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
254fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2550b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
2560b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
2570b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
2580b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
261fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2620b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
2630b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
2640b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2650b57cec5SDimitry Andric            "Attempted to uses-allocator construct a reference element in a tuple");}
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
268fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2690b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
2700b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t), __a)
2710b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2720b57cec5SDimitry Andric           "Attempted to uses-allocator construct a reference element in a tuple");}
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric    __tuple_leaf(const __tuple_leaf& __t) = default;
2750b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf&& __t) = default;
2760b57cec5SDimitry Andric
277fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2780b57cec5SDimitry Andric    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
2790b57cec5SDimitry Andric    {
2800b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
2810b57cec5SDimitry Andric        return 0;
2820b57cec5SDimitry Andric    }
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
2850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
2860b57cec5SDimitry Andric};
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp>
2890b57cec5SDimitry Andricclass __tuple_leaf<_Ip, _Hp, true>
2900b57cec5SDimitry Andric    : private _Hp
2910b57cec5SDimitry Andric{
292fe6060f1SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11
2930b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
2940b57cec5SDimitry Andricpublic:
295fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
2960b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric    template <class _Alloc>
299fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3000b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric    template <class _Alloc>
303fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3040b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3050b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a) {}
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric    template <class _Alloc>
308fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3090b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3100b57cec5SDimitry Andric            : _Hp(__a) {}
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric    template <class _Tp,
313*349cc55cSDimitry Andric              class = __enable_if_t<
3140b57cec5SDimitry Andric                  _And<
3150b57cec5SDimitry Andric                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3160b57cec5SDimitry Andric                    is_constructible<_Hp, _Tp>
3170b57cec5SDimitry Andric                  >::value
3180b57cec5SDimitry Andric                >
3190b57cec5SDimitry Andric            >
3200b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3210b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3220b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
325fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3260b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
3270b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
330fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3310b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
3320b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
335fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3360b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
3370b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf const &) = default;
3400b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf &&) = default;
3410b57cec5SDimitry Andric
342fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3430b57cec5SDimitry Andric    int
3440b57cec5SDimitry Andric    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3450b57cec5SDimitry Andric    {
3460b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
3470b57cec5SDimitry Andric        return 0;
3480b57cec5SDimitry Andric    }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
3510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
3520b57cec5SDimitry Andric};
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andrictemplate <class ..._Tp>
355fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3560b57cec5SDimitry Andricvoid __swallow(_Tp&&...) _NOEXCEPT {}
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andrictemplate <class _Tp>
3590b57cec5SDimitry Andricstruct __all_default_constructible;
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andrictemplate <class ..._Tp>
3620b57cec5SDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>>
3630b57cec5SDimitry Andric    : __all<is_default_constructible<_Tp>::value...>
3640b57cec5SDimitry Andric{ };
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric// __tuple_impl
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andrictemplate<class _Indx, class ..._Tp> struct __tuple_impl;
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andrictemplate<size_t ..._Indx, class ..._Tp>
3710b57cec5SDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
3720b57cec5SDimitry Andric    : public __tuple_leaf<_Indx, _Tp>...
3730b57cec5SDimitry Andric{
3740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
375fe6060f1SDimitry Andric    constexpr __tuple_impl()
3760b57cec5SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric    template <size_t ..._Uf, class ..._Tf,
3790b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
3800b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3810b57cec5SDimitry Andric        explicit
3820b57cec5SDimitry Andric        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3830b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3840b57cec5SDimitry Andric                     _Up&&... __u)
3850b57cec5SDimitry Andric                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
3860b57cec5SDimitry Andric                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
3870b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
3880b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>()...
3890b57cec5SDimitry Andric            {}
3900b57cec5SDimitry Andric
3910b57cec5SDimitry Andric    template <class _Alloc, size_t ..._Uf, class ..._Tf,
3920b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
393fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3940b57cec5SDimitry Andric        explicit
3950b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a,
3960b57cec5SDimitry Andric                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
3970b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
3980b57cec5SDimitry Andric                     _Up&&... __u) :
3990b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
4000b57cec5SDimitry Andric            _VSTD::forward<_Up>(__u))...,
4010b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
4020b57cec5SDimitry Andric            {}
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric    template <class _Tuple,
4050b57cec5SDimitry Andric              class = typename enable_if
4060b57cec5SDimitry Andric                      <
4070b57cec5SDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4080b57cec5SDimitry Andric                      >::type
4090b57cec5SDimitry Andric             >
4100b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4110b57cec5SDimitry Andric        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4120b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
4130b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
4140b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4150b57cec5SDimitry Andric            {}
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric    template <class _Alloc, class _Tuple,
4180b57cec5SDimitry Andric              class = typename enable_if
4190b57cec5SDimitry Andric                      <
4200b57cec5SDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4210b57cec5SDimitry Andric                      >::type
4220b57cec5SDimitry Andric             >
423fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4240b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
4250b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
4260b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
4270b57cec5SDimitry Andric                                       _VSTD::forward<typename tuple_element<_Indx,
4280b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4290b57cec5SDimitry Andric            {}
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andric    __tuple_impl(const __tuple_impl&) = default;
4320b57cec5SDimitry Andric    __tuple_impl(__tuple_impl&&) = default;
4330b57cec5SDimitry Andric
434fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4350b57cec5SDimitry Andric    void swap(__tuple_impl& __t)
4360b57cec5SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
4370b57cec5SDimitry Andric    {
438fe6060f1SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
4390b57cec5SDimitry Andric    }
4400b57cec5SDimitry Andric};
4410b57cec5SDimitry Andric
442fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, size_t ..._Np>
443fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444fe6060f1SDimitry Andricvoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
445fe6060f1SDimitry Andric    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
446fe6060f1SDimitry Andric}
4470b57cec5SDimitry Andric
448fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
449fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
450fe6060f1SDimitry Andricvoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
451fe6060f1SDimitry Andric    _VSTD::__swallow(((
452fe6060f1SDimitry Andric        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
453fe6060f1SDimitry Andric    ), void(), 0)...);
454fe6060f1SDimitry Andric}
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andrictemplate <class ..._Tp>
4570b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple
4580b57cec5SDimitry Andric{
4590b57cec5SDimitry Andric    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
4600b57cec5SDimitry Andric
4610b57cec5SDimitry Andric    _BaseT __base_;
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
4640b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
4650b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
4660b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
4670b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
4680b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
4690b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
4700b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
4710b57cec5SDimitry Andricpublic:
472fe6060f1SDimitry Andric    // [tuple.cnstr]
4730b57cec5SDimitry Andric
474fe6060f1SDimitry Andric    // tuple() constructors (including allocator_arg_t variants)
475*349cc55cSDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
476fe6060f1SDimitry Andric        _And<
477fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
478fe6060f1SDimitry Andric        >::value
479fe6060f1SDimitry Andric    , int> = 0>
480e40139ffSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
481e40139ffSDimitry Andric    tuple()
482fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
483fe6060f1SDimitry Andric    { }
484e40139ffSDimitry Andric
485fe6060f1SDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
486*349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
487fe6060f1SDimitry Andric        _And<
488fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
489fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
490fe6060f1SDimitry Andric        >::value
491fe6060f1SDimitry Andric    , int> = 0>
492fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
493fe6060f1SDimitry Andric    explicit tuple()
494fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
495fe6060f1SDimitry Andric    { }
4960b57cec5SDimitry Andric
497*349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
498fe6060f1SDimitry Andric        _And<
499fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
500fe6060f1SDimitry Andric        >::value
501fe6060f1SDimitry Andric    , int> = 0>
502fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
503fe6060f1SDimitry Andric    tuple(allocator_arg_t, _Alloc const& __a)
504fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
505fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
506fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
507fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
508fe6060f1SDimitry Andric
509fe6060f1SDimitry Andric    template <class _Alloc,
510fe6060f1SDimitry Andric              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
511*349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
512fe6060f1SDimitry Andric        _And<
513fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
514fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
515fe6060f1SDimitry Andric        >::value
516fe6060f1SDimitry Andric    , int> = 0>
517fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
518fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, _Alloc const& __a)
519fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
520fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
521fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
522fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
523fe6060f1SDimitry Andric
524fe6060f1SDimitry Andric    // tuple(const T&...) constructors (including allocator_arg_t variants)
525*349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
526fe6060f1SDimitry Andric        _And<
527fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
528fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
529fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
530fe6060f1SDimitry Andric        >::value
531fe6060f1SDimitry Andric    , int> = 0>
532fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
533fe6060f1SDimitry Andric    tuple(const _Tp& ... __t)
534fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
535fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
536fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
537fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
538fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
539fe6060f1SDimitry Andric                __t...
540fe6060f1SDimitry Andric               ) {}
541fe6060f1SDimitry Andric
542*349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
543fe6060f1SDimitry Andric        _And<
544fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
545fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
546fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
547fe6060f1SDimitry Andric        >::value
548fe6060f1SDimitry Andric    , int> = 0>
549fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
550fe6060f1SDimitry Andric    explicit tuple(const _Tp& ... __t)
551fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
552fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
553fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
554fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
555fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
556fe6060f1SDimitry Andric                __t...
557fe6060f1SDimitry Andric               ) {}
558fe6060f1SDimitry Andric
559*349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
560fe6060f1SDimitry Andric        _And<
561fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
562fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
563fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
564fe6060f1SDimitry Andric        >::value
565fe6060f1SDimitry Andric    , int> = 0>
566fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
567fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
568fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
569fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
570fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
571fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
572fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
573fe6060f1SDimitry Andric                __t...
574fe6060f1SDimitry Andric               ) {}
575fe6060f1SDimitry Andric
576*349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
577fe6060f1SDimitry Andric        _And<
578fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
579fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
580fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
581fe6060f1SDimitry Andric        >::value
582fe6060f1SDimitry Andric    , int> = 0>
583fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
584fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
585fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
586fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
587fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
588fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
589fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
590fe6060f1SDimitry Andric                __t...
591fe6060f1SDimitry Andric               ) {}
592fe6060f1SDimitry Andric
593fe6060f1SDimitry Andric    // tuple(U&& ...) constructors (including allocator_arg_t variants)
594fe6060f1SDimitry Andric    template <class ..._Up> struct _IsThisTuple : false_type { };
595fe6060f1SDimitry Andric    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
596fe6060f1SDimitry Andric
597fe6060f1SDimitry Andric    template <class ..._Up>
598fe6060f1SDimitry Andric    struct _EnableUTypesCtor : _And<
599fe6060f1SDimitry Andric        _BoolConstant<sizeof...(_Tp) >= 1>,
600fe6060f1SDimitry Andric        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
601fe6060f1SDimitry Andric        is_constructible<_Tp, _Up>...
602fe6060f1SDimitry Andric    > { };
603fe6060f1SDimitry Andric
604*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
605fe6060f1SDimitry Andric        _And<
606fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
607fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
608fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
609fe6060f1SDimitry Andric        >::value
610fe6060f1SDimitry Andric    , int> = 0>
611fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
612fe6060f1SDimitry Andric    tuple(_Up&&... __u)
613fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
614fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
615fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
616fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
617fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
618fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
619fe6060f1SDimitry Andric
620*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
621fe6060f1SDimitry Andric        _And<
622fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
623fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
624fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
625fe6060f1SDimitry Andric        >::value
626fe6060f1SDimitry Andric    , int> = 0>
627fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
628fe6060f1SDimitry Andric    explicit tuple(_Up&&... __u)
629fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
630fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
631fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
632fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
633fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
634fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
635fe6060f1SDimitry Andric
636*349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
637fe6060f1SDimitry Andric        _And<
638fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
639fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
640fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
641fe6060f1SDimitry Andric        >::value
642fe6060f1SDimitry Andric    , int> = 0>
643fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
644fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
645fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
646fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
647fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
648fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
649fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
650fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
651fe6060f1SDimitry Andric
652*349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
653fe6060f1SDimitry Andric        _And<
654fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
655fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
656fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
657fe6060f1SDimitry Andric        >::value
658fe6060f1SDimitry Andric    , int> = 0>
659fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
660fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
661fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
662fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
663fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
664fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
665fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
666fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
667fe6060f1SDimitry Andric
668fe6060f1SDimitry Andric    // Copy and move constructors (including the allocator_arg_t variants)
669fe6060f1SDimitry Andric    tuple(const tuple&) = default;
6700b57cec5SDimitry Andric    tuple(tuple&&) = default;
6710b57cec5SDimitry Andric
672*349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
673fe6060f1SDimitry Andric        _And<is_copy_constructible<_Tp>...>::value
674fe6060f1SDimitry Andric    , int> = 0>
675fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
676fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, __t)
677fe6060f1SDimitry Andric    { }
6780b57cec5SDimitry Andric
679*349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
680fe6060f1SDimitry Andric        _And<is_move_constructible<_Tp>...>::value
681fe6060f1SDimitry Andric    , int> = 0>
682fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
683fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
684fe6060f1SDimitry Andric    { }
685e40139ffSDimitry Andric
686fe6060f1SDimitry Andric    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
687fe6060f1SDimitry Andric    template <class ..._Up>
688fe6060f1SDimitry Andric    struct _EnableCopyFromOtherTuple : _And<
689fe6060f1SDimitry Andric        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
690fe6060f1SDimitry Andric        _Lazy<_Or,
691fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) != 1>,
692fe6060f1SDimitry Andric            // _Tp and _Up are 1-element packs - the pack expansions look
693fe6060f1SDimitry Andric            // weird to avoid tripping up the type traits in degenerate cases
694fe6060f1SDimitry Andric            _Lazy<_And,
695fe6060f1SDimitry Andric                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
696fe6060f1SDimitry Andric                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
6970b57cec5SDimitry Andric            >
698fe6060f1SDimitry Andric        >,
699fe6060f1SDimitry Andric        is_constructible<_Tp, const _Up&>...
700fe6060f1SDimitry Andric    > { };
7010b57cec5SDimitry Andric
702*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
703fe6060f1SDimitry Andric        _And<
704fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
705fe6060f1SDimitry Andric            _EnableCopyFromOtherTuple<_Up...>,
706fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
7070b57cec5SDimitry Andric        >::value
708fe6060f1SDimitry Andric    , int> = 0>
7090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
710fe6060f1SDimitry Andric    tuple(const tuple<_Up...>& __t)
711fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
712fe6060f1SDimitry Andric        : __base_(__t)
713fe6060f1SDimitry Andric    { }
714fe6060f1SDimitry Andric
715*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
716fe6060f1SDimitry Andric        _And<
717fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
718fe6060f1SDimitry Andric            _EnableCopyFromOtherTuple<_Up...>,
719fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
7200b57cec5SDimitry Andric        >::value
721fe6060f1SDimitry Andric    , int> = 0>
7220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
723fe6060f1SDimitry Andric    explicit tuple(const tuple<_Up...>& __t)
724fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
725fe6060f1SDimitry Andric        : __base_(__t)
726fe6060f1SDimitry Andric    { }
7270b57cec5SDimitry Andric
728*349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
729fe6060f1SDimitry Andric        _And<
730fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
731fe6060f1SDimitry Andric            _EnableCopyFromOtherTuple<_Up...>,
732fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
733fe6060f1SDimitry Andric        >::value
734fe6060f1SDimitry Andric    , int> = 0>
735fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
736fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
737fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
738fe6060f1SDimitry Andric    { }
7390b57cec5SDimitry Andric
740*349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
741fe6060f1SDimitry Andric        _And<
742fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
743fe6060f1SDimitry Andric            _EnableCopyFromOtherTuple<_Up...>,
744fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
745fe6060f1SDimitry Andric        >::value
746fe6060f1SDimitry Andric    , int> = 0>
747fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
748fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
749fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
750fe6060f1SDimitry Andric    { }
7510b57cec5SDimitry Andric
752fe6060f1SDimitry Andric    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
753fe6060f1SDimitry Andric    template <class ..._Up>
754fe6060f1SDimitry Andric    struct _EnableMoveFromOtherTuple : _And<
755fe6060f1SDimitry Andric        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
756fe6060f1SDimitry Andric        _Lazy<_Or,
757fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) != 1>,
758fe6060f1SDimitry Andric            // _Tp and _Up are 1-element packs - the pack expansions look
759fe6060f1SDimitry Andric            // weird to avoid tripping up the type traits in degenerate cases
760fe6060f1SDimitry Andric            _Lazy<_And,
761fe6060f1SDimitry Andric                _Not<is_convertible<tuple<_Up>, _Tp> >...,
762fe6060f1SDimitry Andric                _Not<is_constructible<_Tp, tuple<_Up> > >...
7630b57cec5SDimitry Andric            >
764fe6060f1SDimitry Andric        >,
765fe6060f1SDimitry Andric        is_constructible<_Tp, _Up>...
766fe6060f1SDimitry Andric    > { };
7670b57cec5SDimitry Andric
768*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
769fe6060f1SDimitry Andric        _And<
770fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
771fe6060f1SDimitry Andric            _EnableMoveFromOtherTuple<_Up...>,
772fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
773fe6060f1SDimitry Andric        >::value
774fe6060f1SDimitry Andric    , int> = 0>
775fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
776fe6060f1SDimitry Andric    tuple(tuple<_Up...>&& __t)
777fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
778fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
779fe6060f1SDimitry Andric    { }
7800b57cec5SDimitry Andric
781*349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
782fe6060f1SDimitry Andric        _And<
783fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
784fe6060f1SDimitry Andric            _EnableMoveFromOtherTuple<_Up...>,
785fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
786fe6060f1SDimitry Andric        >::value
787fe6060f1SDimitry Andric    , int> = 0>
788fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
789fe6060f1SDimitry Andric    explicit tuple(tuple<_Up...>&& __t)
790fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
791fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
792fe6060f1SDimitry Andric    { }
7930b57cec5SDimitry Andric
794*349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
795fe6060f1SDimitry Andric        _And<
796fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
797fe6060f1SDimitry Andric            _EnableMoveFromOtherTuple<_Up...>,
798fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
799fe6060f1SDimitry Andric        >::value
800fe6060f1SDimitry Andric    , int> = 0>
801fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
802fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
803fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
804fe6060f1SDimitry Andric    { }
805fe6060f1SDimitry Andric
806*349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
807fe6060f1SDimitry Andric        _And<
808fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
809fe6060f1SDimitry Andric            _EnableMoveFromOtherTuple<_Up...>,
810fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
811fe6060f1SDimitry Andric        >::value
812fe6060f1SDimitry Andric    , int> = 0>
813fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
814fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
815fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
816fe6060f1SDimitry Andric    { }
817fe6060f1SDimitry Andric
818fe6060f1SDimitry Andric    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
819fe6060f1SDimitry Andric    template <class _Up1, class _Up2, class ..._DependentTp>
820fe6060f1SDimitry Andric    struct _EnableImplicitCopyFromPair : _And<
821fe6060f1SDimitry Andric        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
822fe6060f1SDimitry Andric        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
823fe6060f1SDimitry Andric        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
824fe6060f1SDimitry Andric        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
825fe6060f1SDimitry Andric    > { };
826fe6060f1SDimitry Andric
827fe6060f1SDimitry Andric    template <class _Up1, class _Up2, class ..._DependentTp>
828fe6060f1SDimitry Andric    struct _EnableExplicitCopyFromPair : _And<
829fe6060f1SDimitry Andric        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
830fe6060f1SDimitry Andric        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
831fe6060f1SDimitry Andric        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
832fe6060f1SDimitry Andric        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
833fe6060f1SDimitry Andric    > { };
834fe6060f1SDimitry Andric
835*349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
836fe6060f1SDimitry Andric        _And<
837fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
838fe6060f1SDimitry Andric            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
839fe6060f1SDimitry Andric        >::value
840fe6060f1SDimitry Andric    , int> = 0>
841fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
842fe6060f1SDimitry Andric    tuple(const pair<_Up1, _Up2>& __p)
843fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
844fe6060f1SDimitry Andric            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
845fe6060f1SDimitry Andric            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
846fe6060f1SDimitry Andric        >::value))
847fe6060f1SDimitry Andric        : __base_(__p)
848fe6060f1SDimitry Andric    { }
849fe6060f1SDimitry Andric
850*349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
851fe6060f1SDimitry Andric        _And<
852fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
853fe6060f1SDimitry Andric            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
854fe6060f1SDimitry Andric        >::value
855fe6060f1SDimitry Andric    , int> = 0>
856fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
857fe6060f1SDimitry Andric    explicit tuple(const pair<_Up1, _Up2>& __p)
858fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
859fe6060f1SDimitry Andric            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
860fe6060f1SDimitry Andric            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
861fe6060f1SDimitry Andric        >::value))
862fe6060f1SDimitry Andric        : __base_(__p)
863fe6060f1SDimitry Andric    { }
864fe6060f1SDimitry Andric
865*349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
866fe6060f1SDimitry Andric        _And<
867fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
868fe6060f1SDimitry Andric            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
869fe6060f1SDimitry Andric        >::value
870fe6060f1SDimitry Andric    , int> = 0>
871fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
872fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
873fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
874fe6060f1SDimitry Andric    { }
875fe6060f1SDimitry Andric
876*349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
877fe6060f1SDimitry Andric        _And<
878fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
879fe6060f1SDimitry Andric            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
880fe6060f1SDimitry Andric        >::value
881fe6060f1SDimitry Andric    , int> = 0>
882fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
883fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
884fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
885fe6060f1SDimitry Andric    { }
886fe6060f1SDimitry Andric
887fe6060f1SDimitry Andric    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
888fe6060f1SDimitry Andric    template <class _Up1, class _Up2, class ..._DependentTp>
889fe6060f1SDimitry Andric    struct _EnableImplicitMoveFromPair : _And<
890fe6060f1SDimitry Andric        is_constructible<_FirstType<_DependentTp...>, _Up1>,
891fe6060f1SDimitry Andric        is_constructible<_SecondType<_DependentTp...>, _Up2>,
892fe6060f1SDimitry Andric        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
893fe6060f1SDimitry Andric        is_convertible<_Up2, _SecondType<_DependentTp...> >
894fe6060f1SDimitry Andric    > { };
895fe6060f1SDimitry Andric
896fe6060f1SDimitry Andric    template <class _Up1, class _Up2, class ..._DependentTp>
897fe6060f1SDimitry Andric    struct _EnableExplicitMoveFromPair : _And<
898fe6060f1SDimitry Andric        is_constructible<_FirstType<_DependentTp...>, _Up1>,
899fe6060f1SDimitry Andric        is_constructible<_SecondType<_DependentTp...>, _Up2>,
900fe6060f1SDimitry Andric        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
901fe6060f1SDimitry Andric        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
902fe6060f1SDimitry Andric    > { };
903fe6060f1SDimitry Andric
904*349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
905fe6060f1SDimitry Andric        _And<
906fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
907fe6060f1SDimitry Andric            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
908fe6060f1SDimitry Andric        >::value
909fe6060f1SDimitry Andric    , int> = 0>
910fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
911fe6060f1SDimitry Andric    tuple(pair<_Up1, _Up2>&& __p)
912fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
913fe6060f1SDimitry Andric            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
914fe6060f1SDimitry Andric            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
915fe6060f1SDimitry Andric        >::value))
916fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
917fe6060f1SDimitry Andric    { }
918fe6060f1SDimitry Andric
919*349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
920fe6060f1SDimitry Andric        _And<
921fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
922fe6060f1SDimitry Andric            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
923fe6060f1SDimitry Andric        >::value
924fe6060f1SDimitry Andric    , int> = 0>
925fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
926fe6060f1SDimitry Andric    explicit tuple(pair<_Up1, _Up2>&& __p)
927fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
928fe6060f1SDimitry Andric            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
929fe6060f1SDimitry Andric            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
930fe6060f1SDimitry Andric        >::value))
931fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
932fe6060f1SDimitry Andric    { }
933fe6060f1SDimitry Andric
934*349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
935fe6060f1SDimitry Andric        _And<
936fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
937fe6060f1SDimitry Andric            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
938fe6060f1SDimitry Andric        >::value
939fe6060f1SDimitry Andric    , int> = 0>
940fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
941fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
942fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
943fe6060f1SDimitry Andric    { }
944fe6060f1SDimitry Andric
945*349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
946fe6060f1SDimitry Andric        _And<
947fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
948fe6060f1SDimitry Andric            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
949fe6060f1SDimitry Andric        >::value
950fe6060f1SDimitry Andric    , int> = 0>
951fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
952fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
953fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
954fe6060f1SDimitry Andric    { }
955fe6060f1SDimitry Andric
956fe6060f1SDimitry Andric    // [tuple.assign]
957fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
958fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
959fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
9600b57cec5SDimitry Andric    {
961fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
962fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9630b57cec5SDimitry Andric        return *this;
9640b57cec5SDimitry Andric    }
9650b57cec5SDimitry Andric
966fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
967fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
968fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
9690b57cec5SDimitry Andric    {
970fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
971fe6060f1SDimitry Andric            __tuple_types<_Tp...>(),
972fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9730b57cec5SDimitry Andric        return *this;
9740b57cec5SDimitry Andric    }
9750b57cec5SDimitry Andric
976*349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
977fe6060f1SDimitry Andric        _And<
978fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
979fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
980fe6060f1SDimitry Andric        >::value
981fe6060f1SDimitry Andric    ,int> = 0>
982fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
983fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...> const& __tuple)
984fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
9850b57cec5SDimitry Andric    {
986fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
987fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
9880b57cec5SDimitry Andric        return *this;
9890b57cec5SDimitry Andric    }
9900b57cec5SDimitry Andric
991*349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
992fe6060f1SDimitry Andric        _And<
993fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
994fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
995fe6060f1SDimitry Andric        >::value
996fe6060f1SDimitry Andric    ,int> = 0>
997fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
998fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...>&& __tuple)
999fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1000fe6060f1SDimitry Andric    {
1001fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1002fe6060f1SDimitry Andric            __tuple_types<_Up...>(),
1003fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1004fe6060f1SDimitry Andric        return *this;
1005fe6060f1SDimitry Andric    }
1006fe6060f1SDimitry Andric
1007*349cc55cSDimitry Andric    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1008fe6060f1SDimitry Andric        _And<_Dep,
1009fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
1010fe6060f1SDimitry Andric            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1011fe6060f1SDimitry Andric            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1012fe6060f1SDimitry Andric        >::value
1013fe6060f1SDimitry Andric    ,int> = 0>
1014fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1015fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1016fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
1017fe6060f1SDimitry Andric            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1018fe6060f1SDimitry Andric            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1019fe6060f1SDimitry Andric        >::value))
1020fe6060f1SDimitry Andric    {
1021fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = __pair.first;
1022fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = __pair.second;
1023fe6060f1SDimitry Andric        return *this;
1024fe6060f1SDimitry Andric    }
1025fe6060f1SDimitry Andric
1026*349cc55cSDimitry Andric    template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
1027fe6060f1SDimitry Andric        _And<_Dep,
1028fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == 2>,
1029fe6060f1SDimitry Andric            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1030fe6060f1SDimitry Andric            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1031fe6060f1SDimitry Andric        >::value
1032fe6060f1SDimitry Andric    ,int> = 0>
1033fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1034fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1035fe6060f1SDimitry Andric        _NOEXCEPT_((_And<
1036fe6060f1SDimitry Andric            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1037fe6060f1SDimitry Andric            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1038fe6060f1SDimitry Andric        >::value))
1039fe6060f1SDimitry Andric    {
1040fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1041fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1042fe6060f1SDimitry Andric        return *this;
1043fe6060f1SDimitry Andric    }
1044fe6060f1SDimitry Andric
1045fe6060f1SDimitry Andric    // EXTENSION
1046*349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = __enable_if_t<
1047fe6060f1SDimitry Andric        _And<
1048fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1049fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1050fe6060f1SDimitry Andric        >::value
1051fe6060f1SDimitry Andric    > >
1052fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1053fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np> const& __array)
1054fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1055fe6060f1SDimitry Andric    {
1056fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __array,
1057fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1058fe6060f1SDimitry Andric        return *this;
1059fe6060f1SDimitry Andric    }
1060fe6060f1SDimitry Andric
1061fe6060f1SDimitry Andric    // EXTENSION
1062*349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1063fe6060f1SDimitry Andric        _And<
1064fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1065fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1066fe6060f1SDimitry Andric        >::value
1067fe6060f1SDimitry Andric    > >
1068fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1069fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np>&& __array)
1070fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1071fe6060f1SDimitry Andric    {
1072fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1073fe6060f1SDimitry Andric            __tuple_types<_If<true, _Up, _Tp>...>(),
1074fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1075fe6060f1SDimitry Andric        return *this;
1076fe6060f1SDimitry Andric    }
1077fe6060f1SDimitry Andric
1078fe6060f1SDimitry Andric    // [tuple.swap]
1079fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10800b57cec5SDimitry Andric    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
10810b57cec5SDimitry Andric        {__base_.swap(__t.__base_);}
10820b57cec5SDimitry Andric};
10830b57cec5SDimitry Andric
10840b57cec5SDimitry Andrictemplate <>
10850b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<>
10860b57cec5SDimitry Andric{
10870b57cec5SDimitry Andricpublic:
1088fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr
1089fe6060f1SDimitry Andric        tuple() _NOEXCEPT = default;
10900b57cec5SDimitry Andric    template <class _Alloc>
1091fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10920b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
10930b57cec5SDimitry Andric    template <class _Alloc>
1094fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10950b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
10960b57cec5SDimitry Andric    template <class _Up>
1097fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
10980b57cec5SDimitry Andric        tuple(array<_Up, 0>) _NOEXCEPT {}
10990b57cec5SDimitry Andric    template <class _Alloc, class _Up>
1100fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11010b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1102fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11030b57cec5SDimitry Andric    void swap(tuple&) _NOEXCEPT {}
11040b57cec5SDimitry Andric};
11050b57cec5SDimitry Andric
1106*349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
1107e40139ffSDimitry Andrictemplate <class ..._Tp>
1108e40139ffSDimitry Andrictuple(_Tp...) -> tuple<_Tp...>;
1109e40139ffSDimitry Andrictemplate <class _Tp1, class _Tp2>
1110e40139ffSDimitry Andrictuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1111e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1112e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1113e40139ffSDimitry Andrictemplate <class _Alloc, class _Tp1, class _Tp2>
1114e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1115e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1116e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
11170b57cec5SDimitry Andric#endif
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andrictemplate <class ..._Tp>
1120fe6060f1SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
11210b57cec5SDimitry Andrictypename enable_if
11220b57cec5SDimitry Andric<
11230b57cec5SDimitry Andric    __all<__is_swappable<_Tp>::value...>::value,
11240b57cec5SDimitry Andric    void
11250b57cec5SDimitry Andric>::type
11260b57cec5SDimitry Andricswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
11270b57cec5SDimitry Andric                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
11280b57cec5SDimitry Andric    {__t.swap(__u);}
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andric// get
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
11330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11340b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&
11350b57cec5SDimitry Andricget(tuple<_Tp...>& __t) _NOEXCEPT
11360b57cec5SDimitry Andric{
1137*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11380b57cec5SDimitry Andric    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
11390b57cec5SDimitry Andric}
11400b57cec5SDimitry Andric
11410b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
11420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11430b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
11440b57cec5SDimitry Andricget(const tuple<_Tp...>& __t) _NOEXCEPT
11450b57cec5SDimitry Andric{
1146*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11470b57cec5SDimitry Andric    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
11480b57cec5SDimitry Andric}
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
11510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11520b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&&
11530b57cec5SDimitry Andricget(tuple<_Tp...>&& __t) _NOEXCEPT
11540b57cec5SDimitry Andric{
1155*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11560b57cec5SDimitry Andric    return static_cast<type&&>(
11570b57cec5SDimitry Andric             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
11580b57cec5SDimitry Andric}
11590b57cec5SDimitry Andric
11600b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
11610b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
11620b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
11630b57cec5SDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT
11640b57cec5SDimitry Andric{
1165*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
11660b57cec5SDimitry Andric    return static_cast<const type&&>(
11670b57cec5SDimitry Andric             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
11680b57cec5SDimitry Andric}
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andricnamespace __find_detail {
11730b57cec5SDimitry Andric
1174fe6060f1SDimitry Andricstatic constexpr size_t __not_found = static_cast<size_t>(-1);
11750b57cec5SDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1;
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11780b57cec5SDimitry Andricconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
11790b57cec5SDimitry Andric    return !__matches ? __res :
11800b57cec5SDimitry Andric        (__res == __not_found ? __curr_i : __ambiguous);
11810b57cec5SDimitry Andric}
11820b57cec5SDimitry Andric
11830b57cec5SDimitry Andrictemplate <size_t _Nx>
11840b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11850b57cec5SDimitry Andricconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
11860b57cec5SDimitry Andric  return __i == _Nx ? __not_found :
11870b57cec5SDimitry Andric      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
11880b57cec5SDimitry Andric}
11890b57cec5SDimitry Andric
11900b57cec5SDimitry Andrictemplate <class _T1, class ..._Args>
11910b57cec5SDimitry Andricstruct __find_exactly_one_checked {
11920b57cec5SDimitry Andric    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
11930b57cec5SDimitry Andric    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
11940b57cec5SDimitry Andric    static_assert(value != __not_found, "type not found in type list" );
11950b57cec5SDimitry Andric    static_assert(value != __ambiguous, "type occurs more than once in type list");
11960b57cec5SDimitry Andric};
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andrictemplate <class _T1>
11990b57cec5SDimitry Andricstruct __find_exactly_one_checked<_T1> {
12000b57cec5SDimitry Andric    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
12010b57cec5SDimitry Andric};
12020b57cec5SDimitry Andric
12030b57cec5SDimitry Andric} // namespace __find_detail;
12040b57cec5SDimitry Andric
12050b57cec5SDimitry Andrictemplate <typename _T1, typename... _Args>
12060b57cec5SDimitry Andricstruct __find_exactly_one_t
12070b57cec5SDimitry Andric    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
12080b57cec5SDimitry Andric};
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
12110b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
12120b57cec5SDimitry Andricconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
12130b57cec5SDimitry Andric{
12140b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
12150b57cec5SDimitry Andric}
12160b57cec5SDimitry Andric
12170b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
12180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
12190b57cec5SDimitry Andricconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
12200b57cec5SDimitry Andric{
12210b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
12220b57cec5SDimitry Andric}
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
12250b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
12260b57cec5SDimitry Andricconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
12270b57cec5SDimitry Andric{
12280b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
12290b57cec5SDimitry Andric}
12300b57cec5SDimitry Andric
12310b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
12320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
12330b57cec5SDimitry Andricconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
12340b57cec5SDimitry Andric{
12350b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
12360b57cec5SDimitry Andric}
12370b57cec5SDimitry Andric
12380b57cec5SDimitry Andric#endif
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric// tie
12410b57cec5SDimitry Andric
12420b57cec5SDimitry Andrictemplate <class ..._Tp>
12430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12440b57cec5SDimitry Andrictuple<_Tp&...>
12450b57cec5SDimitry Andrictie(_Tp&... __t) _NOEXCEPT
12460b57cec5SDimitry Andric{
12470b57cec5SDimitry Andric    return tuple<_Tp&...>(__t...);
12480b57cec5SDimitry Andric}
12490b57cec5SDimitry Andric
12500b57cec5SDimitry Andrictemplate <class _Up>
12510b57cec5SDimitry Andricstruct __ignore_t
12520b57cec5SDimitry Andric{
12530b57cec5SDimitry Andric    template <class _Tp>
12540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12550b57cec5SDimitry Andric    const __ignore_t& operator=(_Tp&&) const {return *this;}
12560b57cec5SDimitry Andric};
12570b57cec5SDimitry Andric
12580b57cec5SDimitry Andricnamespace {
1259*349cc55cSDimitry Andric  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
12600b57cec5SDimitry Andric}
12610b57cec5SDimitry Andric
12620b57cec5SDimitry Andrictemplate <class... _Tp>
12630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12640b57cec5SDimitry Andrictuple<typename __unwrap_ref_decay<_Tp>::type...>
12650b57cec5SDimitry Andricmake_tuple(_Tp&&... __t)
12660b57cec5SDimitry Andric{
12670b57cec5SDimitry Andric    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
12680b57cec5SDimitry Andric}
12690b57cec5SDimitry Andric
12700b57cec5SDimitry Andrictemplate <class... _Tp>
12710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12720b57cec5SDimitry Andrictuple<_Tp&&...>
12730b57cec5SDimitry Andricforward_as_tuple(_Tp&&... __t) _NOEXCEPT
12740b57cec5SDimitry Andric{
12750b57cec5SDimitry Andric    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
12760b57cec5SDimitry Andric}
12770b57cec5SDimitry Andric
12780b57cec5SDimitry Andrictemplate <size_t _Ip>
12790b57cec5SDimitry Andricstruct __tuple_equal
12800b57cec5SDimitry Andric{
12810b57cec5SDimitry Andric    template <class _Tp, class _Up>
12820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12830b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
12840b57cec5SDimitry Andric    {
12850b57cec5SDimitry Andric        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
12860b57cec5SDimitry Andric    }
12870b57cec5SDimitry Andric};
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andrictemplate <>
12900b57cec5SDimitry Andricstruct __tuple_equal<0>
12910b57cec5SDimitry Andric{
12920b57cec5SDimitry Andric    template <class _Tp, class _Up>
12930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
12940b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
12950b57cec5SDimitry Andric    {
12960b57cec5SDimitry Andric        return true;
12970b57cec5SDimitry Andric    }
12980b57cec5SDimitry Andric};
12990b57cec5SDimitry Andric
13000b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13010b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13020b57cec5SDimitry Andricbool
13030b57cec5SDimitry Andricoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13040b57cec5SDimitry Andric{
13050b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13060b57cec5SDimitry Andric    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
13070b57cec5SDimitry Andric}
13080b57cec5SDimitry Andric
1309*349cc55cSDimitry Andric#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1310*349cc55cSDimitry Andric
1311*349cc55cSDimitry Andric// operator<=>
1312*349cc55cSDimitry Andric
1313*349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1314*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1315*349cc55cSDimitry Andricauto
1316*349cc55cSDimitry Andric__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1317*349cc55cSDimitry Andric    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1318*349cc55cSDimitry Andric    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1319*349cc55cSDimitry Andric    return __result;
1320*349cc55cSDimitry Andric}
1321*349cc55cSDimitry Andric
1322*349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up>
1323*349cc55cSDimitry Andricrequires (sizeof...(_Tp) == sizeof...(_Up))
1324*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1325*349cc55cSDimitry Andriccommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1326*349cc55cSDimitry Andricoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1327*349cc55cSDimitry Andric{
1328*349cc55cSDimitry Andric    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1329*349cc55cSDimitry Andric}
1330*349cc55cSDimitry Andric
1331*349cc55cSDimitry Andric#else // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1332*349cc55cSDimitry Andric
13330b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13350b57cec5SDimitry Andricbool
13360b57cec5SDimitry Andricoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13370b57cec5SDimitry Andric{
13380b57cec5SDimitry Andric    return !(__x == __y);
13390b57cec5SDimitry Andric}
13400b57cec5SDimitry Andric
13410b57cec5SDimitry Andrictemplate <size_t _Ip>
13420b57cec5SDimitry Andricstruct __tuple_less
13430b57cec5SDimitry Andric{
13440b57cec5SDimitry Andric    template <class _Tp, class _Up>
13450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13460b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
13470b57cec5SDimitry Andric    {
13480b57cec5SDimitry Andric        const size_t __idx = tuple_size<_Tp>::value - _Ip;
13490b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
13500b57cec5SDimitry Andric            return true;
13510b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
13520b57cec5SDimitry Andric            return false;
13530b57cec5SDimitry Andric        return __tuple_less<_Ip-1>()(__x, __y);
13540b57cec5SDimitry Andric    }
13550b57cec5SDimitry Andric};
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andrictemplate <>
13580b57cec5SDimitry Andricstruct __tuple_less<0>
13590b57cec5SDimitry Andric{
13600b57cec5SDimitry Andric    template <class _Tp, class _Up>
13610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13620b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
13630b57cec5SDimitry Andric    {
13640b57cec5SDimitry Andric        return false;
13650b57cec5SDimitry Andric    }
13660b57cec5SDimitry Andric};
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13690b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13700b57cec5SDimitry Andricbool
13710b57cec5SDimitry Andricoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13720b57cec5SDimitry Andric{
13730b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
13740b57cec5SDimitry Andric    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
13750b57cec5SDimitry Andric}
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13790b57cec5SDimitry Andricbool
13800b57cec5SDimitry Andricoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13810b57cec5SDimitry Andric{
13820b57cec5SDimitry Andric    return __y < __x;
13830b57cec5SDimitry Andric}
13840b57cec5SDimitry Andric
13850b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13860b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13870b57cec5SDimitry Andricbool
13880b57cec5SDimitry Andricoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13890b57cec5SDimitry Andric{
13900b57cec5SDimitry Andric    return !(__x < __y);
13910b57cec5SDimitry Andric}
13920b57cec5SDimitry Andric
13930b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
13940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13950b57cec5SDimitry Andricbool
13960b57cec5SDimitry Andricoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
13970b57cec5SDimitry Andric{
13980b57cec5SDimitry Andric    return !(__y < __x);
13990b57cec5SDimitry Andric}
14000b57cec5SDimitry Andric
1401*349cc55cSDimitry Andric#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1402*349cc55cSDimitry Andric
14030b57cec5SDimitry Andric// tuple_cat
14040b57cec5SDimitry Andric
14050b57cec5SDimitry Andrictemplate <class _Tp, class _Up> struct __tuple_cat_type;
14060b57cec5SDimitry Andric
14070b57cec5SDimitry Andrictemplate <class ..._Ttypes, class ..._Utypes>
14080b57cec5SDimitry Andricstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
14090b57cec5SDimitry Andric{
1410*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
14110b57cec5SDimitry Andric};
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andrictemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
14140b57cec5SDimitry Andricstruct __tuple_cat_return_1
14150b57cec5SDimitry Andric{
14160b57cec5SDimitry Andric};
14170b57cec5SDimitry Andric
14180b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0>
14190b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
14200b57cec5SDimitry Andric{
1421*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename __tuple_cat_type<tuple<_Types...>,
14220b57cec5SDimitry Andric            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
14230b57cec5SDimitry Andric                                                                           type;
14240b57cec5SDimitry Andric};
14250b57cec5SDimitry Andric
14260b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
14270b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
14280b57cec5SDimitry Andric    : public __tuple_cat_return_1<
14290b57cec5SDimitry Andric                 typename __tuple_cat_type<
14300b57cec5SDimitry Andric                     tuple<_Types...>,
14310b57cec5SDimitry Andric                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
14320b57cec5SDimitry Andric                 >::type,
14330b57cec5SDimitry Andric                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
14340b57cec5SDimitry Andric                 _Tuple1, _Tuples...>
14350b57cec5SDimitry Andric{
14360b57cec5SDimitry Andric};
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andrictemplate <class ..._Tuples> struct __tuple_cat_return;
14390b57cec5SDimitry Andric
14400b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
14410b57cec5SDimitry Andricstruct __tuple_cat_return<_Tuple0, _Tuples...>
14420b57cec5SDimitry Andric    : public __tuple_cat_return_1<tuple<>,
14430b57cec5SDimitry Andric         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
14440b57cec5SDimitry Andric                                                                     _Tuples...>
14450b57cec5SDimitry Andric{
14460b57cec5SDimitry Andric};
14470b57cec5SDimitry Andric
14480b57cec5SDimitry Andrictemplate <>
14490b57cec5SDimitry Andricstruct __tuple_cat_return<>
14500b57cec5SDimitry Andric{
1451*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<> type;
14520b57cec5SDimitry Andric};
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14550b57cec5SDimitry Andrictuple<>
14560b57cec5SDimitry Andrictuple_cat()
14570b57cec5SDimitry Andric{
14580b57cec5SDimitry Andric    return tuple<>();
14590b57cec5SDimitry Andric}
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andrictemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
14620b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp;
14630b57cec5SDimitry Andric
14640b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0>
14650b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
14660b57cec5SDimitry Andric{
1467*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
14680b57cec5SDimitry Andric    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
14690b57cec5SDimitry Andric                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
14700b57cec5SDimitry Andric};
14710b57cec5SDimitry Andric
14720b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
14730b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
14740b57cec5SDimitry Andric                                  _Tuple0, _Tuple1, _Tuples...>
14750b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<
14760b57cec5SDimitry Andric         tuple<_Types..., typename __apply_cv<_Tuple0,
14770b57cec5SDimitry Andric               typename tuple_element<_I0,
14780b57cec5SDimitry Andric                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
14790b57cec5SDimitry Andric         typename __make_tuple_indices<tuple_size<typename
14800b57cec5SDimitry Andric                                 remove_reference<_Tuple1>::type>::value>::type,
14810b57cec5SDimitry Andric         _Tuple1, _Tuples...>
14820b57cec5SDimitry Andric{
14830b57cec5SDimitry Andric};
14840b57cec5SDimitry Andric
14850b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
14860b57cec5SDimitry Andricstruct __tuple_cat_return_ref
14870b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<tuple<>,
14880b57cec5SDimitry Andric               typename __make_tuple_indices<
14890b57cec5SDimitry Andric                        tuple_size<typename remove_reference<_Tuple0>::type>::value
14900b57cec5SDimitry Andric               >::type, _Tuple0, _Tuples...>
14910b57cec5SDimitry Andric{
14920b57cec5SDimitry Andric};
14930b57cec5SDimitry Andric
14940b57cec5SDimitry Andrictemplate <class _Types, class _I0, class _J0>
14950b57cec5SDimitry Andricstruct __tuple_cat;
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
14980b57cec5SDimitry Andricstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
14990b57cec5SDimitry Andric{
15000b57cec5SDimitry Andric    template <class _Tuple0>
15010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15020b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
15030b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
15040b57cec5SDimitry Andric    {
1505480093f4SDimitry Andric        return _VSTD::forward_as_tuple(
1506480093f4SDimitry Andric            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
15070b57cec5SDimitry Andric            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
15080b57cec5SDimitry Andric    }
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andric    template <class _Tuple0, class _Tuple1, class ..._Tuples>
15110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15120b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
15130b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
15140b57cec5SDimitry Andric    {
1515*349cc55cSDimitry Andric        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1516*349cc55cSDimitry Andric        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
15170b57cec5SDimitry Andric        return __tuple_cat<
1518480093f4SDimitry Andric            tuple<_Types...,
1519480093f4SDimitry Andric                  typename __apply_cv<_Tuple0, typename tuple_element<
1520480093f4SDimitry Andric                                                   _J0, _T0>::type>::type&&...>,
1521480093f4SDimitry Andric            typename __make_tuple_indices<sizeof...(_Types) +
1522480093f4SDimitry Andric                                          tuple_size<_T0>::value>::type,
1523480093f4SDimitry Andric            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1524480093f4SDimitry Andric            _VSTD::forward_as_tuple(
15250b57cec5SDimitry Andric                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1526480093f4SDimitry Andric                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1527480093f4SDimitry Andric            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
15280b57cec5SDimitry Andric    }
15290b57cec5SDimitry Andric};
15300b57cec5SDimitry Andric
15310b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples>
15320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15330b57cec5SDimitry Andrictypename __tuple_cat_return<_Tuple0, _Tuples...>::type
15340b57cec5SDimitry Andrictuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
15350b57cec5SDimitry Andric{
1536*349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
15370b57cec5SDimitry Andric    return __tuple_cat<tuple<>, __tuple_indices<>,
15380b57cec5SDimitry Andric                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
15390b57cec5SDimitry Andric                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
15400b57cec5SDimitry Andric                                            _VSTD::forward<_Tuples>(__tpls)...);
15410b57cec5SDimitry Andric}
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andrictemplate <class ..._Tp, class _Alloc>
15440b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
15450b57cec5SDimitry Andric    : true_type {};
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andrictemplate <class _T1, class _T2>
15480b57cec5SDimitry Andrictemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1549e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15500b57cec5SDimitry Andricpair<_T1, _T2>::pair(piecewise_construct_t,
15510b57cec5SDimitry Andric                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
15520b57cec5SDimitry Andric                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
15530b57cec5SDimitry Andric    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
15540b57cec5SDimitry Andric      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
15550b57cec5SDimitry Andric{
15560b57cec5SDimitry Andric}
15570b57cec5SDimitry Andric
15580b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
15590b57cec5SDimitry Andrictemplate <class _Tp>
1560*349cc55cSDimitry Andricinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
15610b57cec5SDimitry Andric
15620b57cec5SDimitry Andric#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple, size_t ..._Id>
15650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
15660b57cec5SDimitry Andricconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
15670b57cec5SDimitry Andric                                            __tuple_indices<_Id...>)
15680b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
15690b57cec5SDimitry Andric    _VSTD::__invoke_constexpr(
15700b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f),
15710b57cec5SDimitry Andric        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
15720b57cec5SDimitry Andric)
15730b57cec5SDimitry Andric
15740b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple>
15750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
15760b57cec5SDimitry Andricconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
15770b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
15780b57cec5SDimitry Andric    _VSTD::__apply_tuple_impl(
15790b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
15800b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
15810b57cec5SDimitry Andric)
15820b57cec5SDimitry Andric
15830b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx>
15840b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
15850b57cec5SDimitry Andricconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
15860b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
15870b57cec5SDimitry Andric    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
15880b57cec5SDimitry Andric)
15890b57cec5SDimitry Andric
15900b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple>
15910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
15920b57cec5SDimitry Andricconstexpr _Tp make_from_tuple(_Tuple&& __t)
15930b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
15940b57cec5SDimitry Andric    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
15950b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
15960b57cec5SDimitry Andric)
15970b57cec5SDimitry Andric
15980b57cec5SDimitry Andric#undef _LIBCPP_NOEXCEPT_RETURN
15990b57cec5SDimitry Andric
16000b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
16050b57cec5SDimitry Andric
16060b57cec5SDimitry Andric#endif // _LIBCPP_TUPLE
1607