xref: /freebsd/contrib/llvm-project/libcxx/include/tuple (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry 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;
28*81ad6265SDimitry Andric
29*81ad6265SDimitry Andric    template<class... UTypes>
30*81ad6265SDimitry Andric        constexpr explicit(see-below) tuple(tuple<UTypes...>&);  // C++23
310b57cec5SDimitry Andric    template <class... U>
32e40139ffSDimitry Andric        explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
330b57cec5SDimitry Andric    template <class... U>
34e40139ffSDimitry Andric        explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
35*81ad6265SDimitry Andric    template<class... UTypes>
36*81ad6265SDimitry Andric        constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23
37*81ad6265SDimitry Andric
38*81ad6265SDimitry Andric    template<class U1, class U2>
39*81ad6265SDimitry Andric        constexpr explicit(see-below) tuple(pair<U1, U2>&);  // iff sizeof...(Types) == 2 // C++23
400b57cec5SDimitry Andric    template <class U1, class U2>
41e40139ffSDimitry Andric        explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
420b57cec5SDimitry Andric    template <class U1, class U2>
43e40139ffSDimitry Andric        explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
44*81ad6265SDimitry Andric    template<class U1, class U2>
45*81ad6265SDimitry Andric        constexpr explicit(see-below) tuple(const pair<U1, U2>&&);  // iff sizeof...(Types) == 2 // C++23
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric    // allocator-extended constructors
480b57cec5SDimitry Andric    template <class Alloc>
490b57cec5SDimitry Andric        tuple(allocator_arg_t, const Alloc& a);
500b57cec5SDimitry Andric    template <class Alloc>
51fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
520b57cec5SDimitry Andric    template <class Alloc, class... U>
53fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
540b57cec5SDimitry Andric    template <class Alloc>
55fe6060f1SDimitry Andric        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
560b57cec5SDimitry Andric    template <class Alloc>
57fe6060f1SDimitry Andric        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
58*81ad6265SDimitry Andric    template<class Alloc, class... UTypes>
59*81ad6265SDimitry Andric        constexpr explicit(see-below)
60*81ad6265SDimitry Andric          tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&);                      // C++23
610b57cec5SDimitry Andric    template <class Alloc, class... U>
62fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
630b57cec5SDimitry Andric    template <class Alloc, class... U>
64fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
65*81ad6265SDimitry Andric    template<class Alloc, class... UTypes>
66*81ad6265SDimitry Andric        constexpr explicit(see-below)
67*81ad6265SDimitry Andric          tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);               // C++23
68*81ad6265SDimitry Andric    template<class Alloc, class U1, class U2>
69*81ad6265SDimitry Andric        constexpr explicit(see-below)
70*81ad6265SDimitry Andric          tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&);                          // C++23
710b57cec5SDimitry Andric    template <class Alloc, class U1, class U2>
72fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
730b57cec5SDimitry Andric    template <class Alloc, class U1, class U2>
74fe6060f1SDimitry Andric        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
75*81ad6265SDimitry Andric    template<class Alloc, class U1, class U2>
76*81ad6265SDimitry Andric        constexpr explicit(see-below)
77*81ad6265SDimitry Andric          tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&);                   // C++23
780b57cec5SDimitry Andric
79fe6060f1SDimitry Andric    tuple& operator=(const tuple&);                                                       // constexpr in C++20
80*81ad6265SDimitry Andric    constexpr const tuple& operator=(const tuple&) const;                                 // C++23
81fe6060f1SDimitry Andric    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
82*81ad6265SDimitry Andric    constexpr const tuple& operator=(tuple&&) const;                                      // C++23
830b57cec5SDimitry Andric    template <class... U>
84fe6060f1SDimitry Andric        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
85*81ad6265SDimitry Andric    template<class... UTypes>
86*81ad6265SDimitry Andric        constexpr const tuple& operator=(const tuple<UTypes...>&) const;                  // C++23
870b57cec5SDimitry Andric    template <class... U>
88fe6060f1SDimitry Andric        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
89*81ad6265SDimitry Andric    template<class... UTypes>
90*81ad6265SDimitry Andric        constexpr const tuple& operator=(tuple<UTypes...>&&) const;                       // C++23
910b57cec5SDimitry Andric    template <class U1, class U2>
92fe6060f1SDimitry Andric        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
930b57cec5SDimitry Andric    template<class U1, class U2>
94*81ad6265SDimitry Andric        constexpr const tuple& operator=(const pair<U1, U2>&) const;   // iff sizeof...(Types) == 2 // C++23
95*81ad6265SDimitry Andric    template <class U1, class U2>
96fe6060f1SDimitry Andric        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
97*81ad6265SDimitry Andric    template<class U1, class U2>
98*81ad6265SDimitry Andric        constexpr const tuple& operator=(pair<U1, U2>&&) const;  // iff sizeof...(Types) == 2 // C++23
990b57cec5SDimitry Andric
100fe6060f1SDimitry Andric    template<class U, size_t N>
101fe6060f1SDimitry Andric        tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
102fe6060f1SDimitry Andric    template<class U, size_t N>
103fe6060f1SDimitry Andric        tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
104fe6060f1SDimitry Andric
105fe6060f1SDimitry Andric    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
106*81ad6265SDimitry Andric    constexpr void swap(const tuple&) const noexcept(see-below);                          // C++23
1070b57cec5SDimitry Andric};
1080b57cec5SDimitry Andric
10904eeddc0SDimitry Andric
11004eeddc0SDimitry Andrictemplate<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23
11104eeddc0SDimitry Andric  requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; }
11204eeddc0SDimitry Andricstruct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> {
11304eeddc0SDimitry Andric  using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>;
11404eeddc0SDimitry Andric};
11504eeddc0SDimitry Andric
11604eeddc0SDimitry Andrictemplate<class... TTypes, class... UTypes>                                // since C++23
11704eeddc0SDimitry Andric  requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; }
11804eeddc0SDimitry Andricstruct common_type<tuple<TTypes...>, tuple<UTypes...>> {
11904eeddc0SDimitry Andric  using type = tuple<common_type_t<TTypes, UTypes>...>;
12004eeddc0SDimitry Andric};
12104eeddc0SDimitry Andric
122e40139ffSDimitry Andrictemplate <class ...T>
123e40139ffSDimitry Andrictuple(T...) -> tuple<T...>;                                         // since C++17
124e40139ffSDimitry Andrictemplate <class T1, class T2>
125e40139ffSDimitry Andrictuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
126e40139ffSDimitry Andrictemplate <class Alloc, class ...T>
127e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
128e40139ffSDimitry Andrictemplate <class Alloc, class T1, class T2>
129e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
130e40139ffSDimitry Andrictemplate <class Alloc, class ...T>
131e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
132e40139ffSDimitry Andric
1330b57cec5SDimitry Andricinline constexpr unspecified ignore;
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andrictemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
1360b57cec5SDimitry Andrictemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
1370b57cec5SDimitry Andrictemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
1380b57cec5SDimitry Andrictemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andric// [tuple.apply], calling a function with a tuple of arguments:
1410b57cec5SDimitry Andrictemplate <class F, class Tuple>
1420b57cec5SDimitry Andric  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
1430b57cec5SDimitry Andrictemplate <class T, class Tuple>
1440b57cec5SDimitry Andric  constexpr T make_from_tuple(Tuple&& t); // C++17
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric// 20.4.1.4, tuple helper classes:
1470b57cec5SDimitry Andrictemplate <class T> struct tuple_size; // undefined
1480b57cec5SDimitry Andrictemplate <class... T> struct tuple_size<tuple<T...>>;
1490b57cec5SDimitry Andrictemplate <class T>
1500b57cec5SDimitry Andric inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
1510b57cec5SDimitry Andrictemplate <size_t I, class T> struct tuple_element; // undefined
1520b57cec5SDimitry Andrictemplate <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
1530b57cec5SDimitry Andrictemplate <size_t I, class T>
1540b57cec5SDimitry Andric  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric// 20.4.1.5, element access:
1570b57cec5SDimitry Andrictemplate <size_t I, class... T>
1580b57cec5SDimitry Andric    typename tuple_element<I, tuple<T...>>::type&
1590b57cec5SDimitry Andric    get(tuple<T...>&) noexcept; // constexpr in C++14
1600b57cec5SDimitry Andrictemplate <size_t I, class... T>
1610b57cec5SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&
1620b57cec5SDimitry Andric    get(const tuple<T...>&) noexcept; // constexpr in C++14
1630b57cec5SDimitry Andrictemplate <size_t I, class... T>
1640b57cec5SDimitry Andric    typename tuple_element<I, tuple<T...>>::type&&
1650b57cec5SDimitry Andric    get(tuple<T...>&&) noexcept; // constexpr in C++14
1660b57cec5SDimitry Andrictemplate <size_t I, class... T>
1670b57cec5SDimitry Andric    const typename tuple_element<I, tuple<T...>>::type&&
1680b57cec5SDimitry Andric    get(const tuple<T...>&&) noexcept; // constexpr in C++14
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andrictemplate <class T1, class... T>
1710b57cec5SDimitry Andric    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
1720b57cec5SDimitry Andrictemplate <class T1, class... T>
1730b57cec5SDimitry Andric    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
1740b57cec5SDimitry Andrictemplate <class T1, class... T>
1750b57cec5SDimitry Andric    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
1760b57cec5SDimitry Andrictemplate <class T1, class... T>
1770b57cec5SDimitry Andric    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric// 20.4.1.6, relational operators:
1800b57cec5SDimitry Andrictemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
181349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
182349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
183349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
184349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
185349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
186349cc55cSDimitry Andrictemplate<class... T, class... U>
187349cc55cSDimitry Andric  constexpr common_comparison_category_t<synth-three-way-result<T, U>...>
188349cc55cSDimitry Andric    operator<=>(const tuple<T...>&, const tuple<U...>&);                                  // since C++20
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andrictemplate <class... Types, class Alloc>
1910b57cec5SDimitry Andric  struct uses_allocator<tuple<Types...>, Alloc>;
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andrictemplate <class... Types>
1940b57cec5SDimitry Andric  void
1950b57cec5SDimitry Andric  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
1960b57cec5SDimitry Andric
197*81ad6265SDimitry Andrictemplate <class... Types>
198*81ad6265SDimitry Andric  constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below);   // C++23
199*81ad6265SDimitry Andric
2000b57cec5SDimitry Andric}  // std
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric*/
2030b57cec5SDimitry Andric
204*81ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
205349cc55cSDimitry Andric#include <__compare/common_comparison_category.h>
206349cc55cSDimitry Andric#include <__compare/synth_three_way.h>
2070b57cec5SDimitry Andric#include <__config>
208fe6060f1SDimitry Andric#include <__functional/unwrap_ref.h>
209fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
210fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
2110b57cec5SDimitry Andric#include <__tuple>
212fe6060f1SDimitry Andric#include <__utility/forward.h>
213349cc55cSDimitry Andric#include <__utility/integer_sequence.h>
214fe6060f1SDimitry Andric#include <__utility/move.h>
215*81ad6265SDimitry Andric#include <__utility/pair.h>
216*81ad6265SDimitry Andric#include <__utility/piecewise_construct.h>
217*81ad6265SDimitry Andric#include <__utility/swap.h>
2180b57cec5SDimitry Andric#include <cstddef>
2190b57cec5SDimitry Andric#include <type_traits>
2200b57cec5SDimitry Andric#include <version>
2210b57cec5SDimitry Andric
222*81ad6265SDimitry Andric#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
223*81ad6265SDimitry Andric#  include <exception>
224*81ad6265SDimitry Andric#  include <iosfwd>
225*81ad6265SDimitry Andric#  include <new>
226*81ad6265SDimitry Andric#  include <typeinfo>
227*81ad6265SDimitry Andric#  include <utility>
228*81ad6265SDimitry Andric#endif
229*81ad6265SDimitry Andric
230*81ad6265SDimitry Andric// standard-mandated includes
231*81ad6265SDimitry Andric#include <compare>
232*81ad6265SDimitry Andric
2330b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2340b57cec5SDimitry Andric#  pragma GCC system_header
2350b57cec5SDimitry Andric#endif
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric// __tuple_leaf
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp,
2450b57cec5SDimitry Andric          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
2460b57cec5SDimitry Andric         >
2470b57cec5SDimitry Andricclass __tuple_leaf;
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
250fe6060f1SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2510b57cec5SDimitry Andricvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
2520b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
2530b57cec5SDimitry Andric{
2540b57cec5SDimitry Andric    swap(__x.get(), __y.get());
2550b57cec5SDimitry Andric}
2560b57cec5SDimitry Andric
257*81ad6265SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
258*81ad6265SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
259*81ad6265SDimitry Andricvoid swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y)
260*81ad6265SDimitry Andric     _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) {
261*81ad6265SDimitry Andric  swap(__x.get(), __y.get());
262*81ad6265SDimitry Andric}
263*81ad6265SDimitry Andric
2640b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool>
2650b57cec5SDimitry Andricclass __tuple_leaf
2660b57cec5SDimitry Andric{
2670b57cec5SDimitry Andric    _Hp __value_;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric    template <class _Tp>
2700b57cec5SDimitry Andric    static constexpr bool __can_bind_reference() {
2710b57cec5SDimitry Andric#if __has_keyword(__reference_binds_to_temporary)
2720b57cec5SDimitry Andric      return !__reference_binds_to_temporary(_Hp, _Tp);
2730b57cec5SDimitry Andric#else
2740b57cec5SDimitry Andric      return true;
2750b57cec5SDimitry Andric#endif
2760b57cec5SDimitry Andric    }
2770b57cec5SDimitry Andric
278fe6060f1SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11
2790b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
2800b57cec5SDimitry Andricpublic:
281fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
2820b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
2830b57cec5SDimitry Andric       {static_assert(!is_reference<_Hp>::value,
2840b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric    template <class _Alloc>
287fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
2880b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
2890b57cec5SDimitry Andric            : __value_()
2900b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2910b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2920b57cec5SDimitry Andric
2930b57cec5SDimitry Andric    template <class _Alloc>
294fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
2950b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
2960b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a)
2970b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
2980b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric    template <class _Alloc>
301fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3020b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3030b57cec5SDimitry Andric            : __value_(__a)
3040b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3050b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric    template <class _Tp,
308349cc55cSDimitry Andric              class = __enable_if_t<
3090b57cec5SDimitry Andric                  _And<
3100b57cec5SDimitry Andric                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3110b57cec5SDimitry Andric                      is_constructible<_Hp, _Tp>
3120b57cec5SDimitry Andric                    >::value
3130b57cec5SDimitry Andric                >
3140b57cec5SDimitry Andric            >
3150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3160b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3170b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3180b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3190b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
322fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3230b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
3240b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3250b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3260b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
329fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3300b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
3310b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
3320b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3330b57cec5SDimitry Andric            "Attempted to uses-allocator construct a reference element in a tuple");}
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
336fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3370b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
3380b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t), __a)
3390b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3400b57cec5SDimitry Andric           "Attempted to uses-allocator construct a reference element in a tuple");}
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric    __tuple_leaf(const __tuple_leaf& __t) = default;
3430b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf&& __t) = default;
3440b57cec5SDimitry Andric
345fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3460b57cec5SDimitry Andric    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3470b57cec5SDimitry Andric    {
3480b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
3490b57cec5SDimitry Andric        return 0;
3500b57cec5SDimitry Andric    }
3510b57cec5SDimitry Andric
352*81ad6265SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
353*81ad6265SDimitry Andric    int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
354*81ad6265SDimitry Andric        _VSTD::swap(*this, __t);
355*81ad6265SDimitry Andric        return 0;
356*81ad6265SDimitry Andric    }
357*81ad6265SDimitry Andric
3580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
3590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
3600b57cec5SDimitry Andric};
3610b57cec5SDimitry Andric
3620b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp>
3630b57cec5SDimitry Andricclass __tuple_leaf<_Ip, _Hp, true>
3640b57cec5SDimitry Andric    : private _Hp
3650b57cec5SDimitry Andric{
366fe6060f1SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11
3670b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
3680b57cec5SDimitry Andricpublic:
369fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
3700b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric    template <class _Alloc>
373fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3740b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andric    template <class _Alloc>
377fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3780b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3790b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a) {}
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric    template <class _Alloc>
382fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3830b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3840b57cec5SDimitry Andric            : _Hp(__a) {}
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andric    template <class _Tp,
387349cc55cSDimitry Andric              class = __enable_if_t<
3880b57cec5SDimitry Andric                  _And<
3890b57cec5SDimitry Andric                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
3900b57cec5SDimitry Andric                    is_constructible<_Hp, _Tp>
3910b57cec5SDimitry Andric                  >::value
3920b57cec5SDimitry Andric                >
3930b57cec5SDimitry Andric            >
3940b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
3950b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3960b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
399fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4000b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
4010b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
404fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4050b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
4060b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
409fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4100b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
4110b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf const &) = default;
4140b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf &&) = default;
4150b57cec5SDimitry Andric
416fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4170b57cec5SDimitry Andric    int
4180b57cec5SDimitry Andric    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
4190b57cec5SDimitry Andric    {
4200b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
4210b57cec5SDimitry Andric        return 0;
4220b57cec5SDimitry Andric    }
4230b57cec5SDimitry Andric
424*81ad6265SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
425*81ad6265SDimitry Andric    int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
426*81ad6265SDimitry Andric        _VSTD::swap(*this, __rhs);
427*81ad6265SDimitry Andric        return 0;
428*81ad6265SDimitry Andric    }
429*81ad6265SDimitry Andric
4300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
4310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
4320b57cec5SDimitry Andric};
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andrictemplate <class ..._Tp>
435fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4360b57cec5SDimitry Andricvoid __swallow(_Tp&&...) _NOEXCEPT {}
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andrictemplate <class _Tp>
4390b57cec5SDimitry Andricstruct __all_default_constructible;
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andrictemplate <class ..._Tp>
4420b57cec5SDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>>
4430b57cec5SDimitry Andric    : __all<is_default_constructible<_Tp>::value...>
4440b57cec5SDimitry Andric{ };
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric// __tuple_impl
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andrictemplate<class _Indx, class ..._Tp> struct __tuple_impl;
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andrictemplate<size_t ..._Indx, class ..._Tp>
4510b57cec5SDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
4520b57cec5SDimitry Andric    : public __tuple_leaf<_Indx, _Tp>...
4530b57cec5SDimitry Andric{
4540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
455fe6060f1SDimitry Andric    constexpr __tuple_impl()
4560b57cec5SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric    template <size_t ..._Uf, class ..._Tf,
4590b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
4600b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4610b57cec5SDimitry Andric        explicit
4620b57cec5SDimitry Andric        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
4630b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
4640b57cec5SDimitry Andric                     _Up&&... __u)
4650b57cec5SDimitry Andric                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
4660b57cec5SDimitry Andric                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
4670b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
4680b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>()...
4690b57cec5SDimitry Andric            {}
4700b57cec5SDimitry Andric
4710b57cec5SDimitry Andric    template <class _Alloc, size_t ..._Uf, class ..._Tf,
4720b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
473fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4740b57cec5SDimitry Andric        explicit
4750b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a,
4760b57cec5SDimitry Andric                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
4770b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
4780b57cec5SDimitry Andric                     _Up&&... __u) :
4790b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
4800b57cec5SDimitry Andric            _VSTD::forward<_Up>(__u))...,
4810b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
4820b57cec5SDimitry Andric            {}
4830b57cec5SDimitry Andric
4840b57cec5SDimitry Andric    template <class _Tuple,
4850b57cec5SDimitry Andric              class = typename enable_if
4860b57cec5SDimitry Andric                      <
4870b57cec5SDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
4880b57cec5SDimitry Andric                      >::type
4890b57cec5SDimitry Andric             >
4900b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4910b57cec5SDimitry Andric        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
4920b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
4930b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
4940b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
4950b57cec5SDimitry Andric            {}
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andric    template <class _Alloc, class _Tuple,
4980b57cec5SDimitry Andric              class = typename enable_if
4990b57cec5SDimitry Andric                      <
5000b57cec5SDimitry Andric                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
5010b57cec5SDimitry Andric                      >::type
5020b57cec5SDimitry Andric             >
503fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
5040b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
5050b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
5060b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
5070b57cec5SDimitry Andric                                       _VSTD::forward<typename tuple_element<_Indx,
5080b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
5090b57cec5SDimitry Andric            {}
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andric    __tuple_impl(const __tuple_impl&) = default;
5120b57cec5SDimitry Andric    __tuple_impl(__tuple_impl&&) = default;
5130b57cec5SDimitry Andric
514fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
5150b57cec5SDimitry Andric    void swap(__tuple_impl& __t)
5160b57cec5SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
5170b57cec5SDimitry Andric    {
518fe6060f1SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
5190b57cec5SDimitry Andric    }
520*81ad6265SDimitry Andric
521*81ad6265SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
522*81ad6265SDimitry Andric    void swap(const __tuple_impl& __t) const
523*81ad6265SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value)
524*81ad6265SDimitry Andric    {
525*81ad6265SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...);
526*81ad6265SDimitry Andric    }
5270b57cec5SDimitry Andric};
5280b57cec5SDimitry Andric
529fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, size_t ..._Np>
530fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
531fe6060f1SDimitry Andricvoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
532fe6060f1SDimitry Andric    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
533fe6060f1SDimitry Andric}
5340b57cec5SDimitry Andric
535fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
536fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
537fe6060f1SDimitry Andricvoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
538fe6060f1SDimitry Andric    _VSTD::__swallow(((
539fe6060f1SDimitry Andric        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
540fe6060f1SDimitry Andric    ), void(), 0)...);
541fe6060f1SDimitry Andric}
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andrictemplate <class ..._Tp>
5440b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple
5450b57cec5SDimitry Andric{
5460b57cec5SDimitry Andric    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric    _BaseT __base_;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
5510b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
5520b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
5530b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
5540b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
5550b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
5560b57cec5SDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
5570b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
5580b57cec5SDimitry Andricpublic:
559fe6060f1SDimitry Andric    // [tuple.cnstr]
5600b57cec5SDimitry Andric
561fe6060f1SDimitry Andric    // tuple() constructors (including allocator_arg_t variants)
562349cc55cSDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
563fe6060f1SDimitry Andric        _And<
564fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
565fe6060f1SDimitry Andric        >::value
566fe6060f1SDimitry Andric    , int> = 0>
567e40139ffSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
568e40139ffSDimitry Andric    tuple()
569fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
570fe6060f1SDimitry Andric    { }
571e40139ffSDimitry Andric
572fe6060f1SDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
573349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
574fe6060f1SDimitry Andric        _And<
575fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
576fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
577fe6060f1SDimitry Andric        >::value
578fe6060f1SDimitry Andric    , int> = 0>
579fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
580fe6060f1SDimitry Andric    explicit tuple()
581fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
582fe6060f1SDimitry Andric    { }
5830b57cec5SDimitry Andric
584349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
585fe6060f1SDimitry Andric        _And<
586fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
587fe6060f1SDimitry Andric        >::value
588fe6060f1SDimitry Andric    , int> = 0>
589fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
590fe6060f1SDimitry Andric    tuple(allocator_arg_t, _Alloc const& __a)
591fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
592fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
593fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
594fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
595fe6060f1SDimitry Andric
596fe6060f1SDimitry Andric    template <class _Alloc,
597fe6060f1SDimitry Andric              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
598349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
599fe6060f1SDimitry Andric        _And<
600fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
601fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
602fe6060f1SDimitry Andric        >::value
603fe6060f1SDimitry Andric    , int> = 0>
604fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
605fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, _Alloc const& __a)
606fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
607fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
608fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
609fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
610fe6060f1SDimitry Andric
611fe6060f1SDimitry Andric    // tuple(const T&...) constructors (including allocator_arg_t variants)
612349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
613fe6060f1SDimitry Andric        _And<
614fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
615fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
616fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
617fe6060f1SDimitry Andric        >::value
618fe6060f1SDimitry Andric    , int> = 0>
619fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
620fe6060f1SDimitry Andric    tuple(const _Tp& ... __t)
621fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
622fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
623fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
624fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
625fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
626fe6060f1SDimitry Andric                __t...
627fe6060f1SDimitry Andric               ) {}
628fe6060f1SDimitry Andric
629349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
630fe6060f1SDimitry Andric        _And<
631fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
632fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
633fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
634fe6060f1SDimitry Andric        >::value
635fe6060f1SDimitry Andric    , int> = 0>
636fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
637fe6060f1SDimitry Andric    explicit tuple(const _Tp& ... __t)
638fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
639fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
640fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
641fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
642fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
643fe6060f1SDimitry Andric                __t...
644fe6060f1SDimitry Andric               ) {}
645fe6060f1SDimitry Andric
646349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
647fe6060f1SDimitry Andric        _And<
648fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
649fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
650fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
651fe6060f1SDimitry Andric        >::value
652fe6060f1SDimitry Andric    , int> = 0>
653fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
655fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
656fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
657fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
658fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
659fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
660fe6060f1SDimitry Andric                __t...
661fe6060f1SDimitry Andric               ) {}
662fe6060f1SDimitry Andric
663349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
664fe6060f1SDimitry Andric        _And<
665fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
666fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
667fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
668fe6060f1SDimitry Andric        >::value
669fe6060f1SDimitry Andric    , int> = 0>
670fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
671fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
672fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
673fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
674fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
675fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
676fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
677fe6060f1SDimitry Andric                __t...
678fe6060f1SDimitry Andric               ) {}
679fe6060f1SDimitry Andric
680fe6060f1SDimitry Andric    // tuple(U&& ...) constructors (including allocator_arg_t variants)
681fe6060f1SDimitry Andric    template <class ..._Up> struct _IsThisTuple : false_type { };
682fe6060f1SDimitry Andric    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
683fe6060f1SDimitry Andric
684fe6060f1SDimitry Andric    template <class ..._Up>
685fe6060f1SDimitry Andric    struct _EnableUTypesCtor : _And<
686fe6060f1SDimitry Andric        _BoolConstant<sizeof...(_Tp) >= 1>,
687fe6060f1SDimitry Andric        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
688fe6060f1SDimitry Andric        is_constructible<_Tp, _Up>...
689fe6060f1SDimitry Andric    > { };
690fe6060f1SDimitry Andric
691349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
692fe6060f1SDimitry Andric        _And<
693fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
694fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
695fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
696fe6060f1SDimitry Andric        >::value
697fe6060f1SDimitry Andric    , int> = 0>
698fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
699fe6060f1SDimitry Andric    tuple(_Up&&... __u)
700fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
701fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
702fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
703fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
704fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
705fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
706fe6060f1SDimitry Andric
707349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
708fe6060f1SDimitry Andric        _And<
709fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
710fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
711fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
712fe6060f1SDimitry Andric        >::value
713fe6060f1SDimitry Andric    , int> = 0>
714fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
715fe6060f1SDimitry Andric    explicit tuple(_Up&&... __u)
716fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
717fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
718fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
719fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
720fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
721fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
722fe6060f1SDimitry Andric
723349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
724fe6060f1SDimitry Andric        _And<
725fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
726fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
727fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
728fe6060f1SDimitry Andric        >::value
729fe6060f1SDimitry Andric    , int> = 0>
730fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
731fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
732fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
733fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
734fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
735fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
736fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
737fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
738fe6060f1SDimitry Andric
739349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
740fe6060f1SDimitry Andric        _And<
741fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
742fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
743fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
744fe6060f1SDimitry Andric        >::value
745fe6060f1SDimitry Andric    , int> = 0>
746fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
747fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
748fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
749fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
750fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
751fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
752fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
753fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
754fe6060f1SDimitry Andric
755fe6060f1SDimitry Andric    // Copy and move constructors (including the allocator_arg_t variants)
756fe6060f1SDimitry Andric    tuple(const tuple&) = default;
7570b57cec5SDimitry Andric    tuple(tuple&&) = default;
7580b57cec5SDimitry Andric
759349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
760fe6060f1SDimitry Andric        _And<is_copy_constructible<_Tp>...>::value
761fe6060f1SDimitry Andric    , int> = 0>
762*81ad6265SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
763fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
764fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, __t)
765fe6060f1SDimitry Andric    { }
7660b57cec5SDimitry Andric
767349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
768fe6060f1SDimitry Andric        _And<is_move_constructible<_Tp>...>::value
769fe6060f1SDimitry Andric    , int> = 0>
770*81ad6265SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
771fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
772fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
773fe6060f1SDimitry Andric    { }
774e40139ffSDimitry Andric
775fe6060f1SDimitry Andric    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
776*81ad6265SDimitry Andric
777*81ad6265SDimitry Andric    template <class _OtherTuple, class _DecayedOtherTuple = __uncvref_t<_OtherTuple>, class = void>
778*81ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple : false_type {};
779*81ad6265SDimitry Andric
780*81ad6265SDimitry Andric    template <class _OtherTuple, class... _Up>
781*81ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>,
782*81ad6265SDimitry Andric              // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below
783*81ad6265SDimitry Andric               __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And<
784*81ad6265SDimitry Andric        // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work.
785*81ad6265SDimitry Andric        // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE
786*81ad6265SDimitry Andric        _Not<is_same<_OtherTuple, const tuple&> >,
787*81ad6265SDimitry Andric        _Not<is_same<_OtherTuple, tuple&&> >,
788*81ad6265SDimitry Andric        is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
789*81ad6265SDimitry Andric        _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>,
790fe6060f1SDimitry Andric            // _Tp and _Up are 1-element packs - the pack expansions look
791fe6060f1SDimitry Andric            // weird to avoid tripping up the type traits in degenerate cases
792fe6060f1SDimitry Andric            _Lazy<_And,
793*81ad6265SDimitry Andric                _Not<is_same<_Tp, _Up> >...,
794*81ad6265SDimitry Andric                _Not<is_convertible<_OtherTuple, _Tp> >...,
795*81ad6265SDimitry Andric                _Not<is_constructible<_Tp, _OtherTuple> >...
7960b57cec5SDimitry Andric            >
797*81ad6265SDimitry Andric        >
798fe6060f1SDimitry Andric    > {};
7990b57cec5SDimitry Andric
800349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
801fe6060f1SDimitry Andric        _And<
802*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
803fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
8040b57cec5SDimitry Andric        >::value
805fe6060f1SDimitry Andric    , int> = 0>
8060b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
807fe6060f1SDimitry Andric    tuple(const tuple<_Up...>& __t)
808fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
809fe6060f1SDimitry Andric        : __base_(__t)
810fe6060f1SDimitry Andric    { }
811fe6060f1SDimitry Andric
812349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
813fe6060f1SDimitry Andric        _And<
814*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
815fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
8160b57cec5SDimitry Andric        >::value
817fe6060f1SDimitry Andric    , int> = 0>
8180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
819fe6060f1SDimitry Andric    explicit tuple(const tuple<_Up...>& __t)
820fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
821fe6060f1SDimitry Andric        : __base_(__t)
822fe6060f1SDimitry Andric    { }
8230b57cec5SDimitry Andric
824349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
825fe6060f1SDimitry Andric        _And<
826*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
827fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
828fe6060f1SDimitry Andric        >::value
829fe6060f1SDimitry Andric    , int> = 0>
830fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
831fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
832fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
833fe6060f1SDimitry Andric    { }
8340b57cec5SDimitry Andric
835349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
836fe6060f1SDimitry Andric        _And<
837*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
838fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
839fe6060f1SDimitry Andric        >::value
840fe6060f1SDimitry Andric    , int> = 0>
841fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
842fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
843fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
844fe6060f1SDimitry Andric    { }
8450b57cec5SDimitry Andric
846*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
847*81ad6265SDimitry Andric    // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
848*81ad6265SDimitry Andric
849*81ad6265SDimitry Andric    template <class... _Up, enable_if_t<
850*81ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
851*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
852*81ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
853*81ad6265SDimitry Andric    tuple(tuple<_Up...>& __t) : __base_(__t) {}
854*81ad6265SDimitry Andric
855*81ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
856*81ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
857*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
858*81ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
859*81ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
860*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
861*81ad6265SDimitry Andric
862fe6060f1SDimitry Andric    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
8630b57cec5SDimitry Andric
864349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
865fe6060f1SDimitry Andric        _And<
866*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
867fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
868fe6060f1SDimitry Andric        >::value
869fe6060f1SDimitry Andric    , int> = 0>
870fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
871fe6060f1SDimitry Andric    tuple(tuple<_Up...>&& __t)
872fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
873fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
874fe6060f1SDimitry Andric    { }
8750b57cec5SDimitry Andric
876349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
877fe6060f1SDimitry Andric        _And<
878*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
879fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
880fe6060f1SDimitry Andric        >::value
881fe6060f1SDimitry Andric    , int> = 0>
882fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
883fe6060f1SDimitry Andric    explicit tuple(tuple<_Up...>&& __t)
884fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
885fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
886fe6060f1SDimitry Andric    { }
8870b57cec5SDimitry Andric
888349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
889fe6060f1SDimitry Andric        _And<
890*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
891fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
892fe6060f1SDimitry Andric        >::value
893fe6060f1SDimitry Andric    , int> = 0>
894fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
895fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
896fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
897fe6060f1SDimitry Andric    { }
898fe6060f1SDimitry Andric
899349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
900fe6060f1SDimitry Andric        _And<
901*81ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
902fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
903fe6060f1SDimitry Andric        >::value
904fe6060f1SDimitry Andric    , int> = 0>
905fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
906fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
907fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
908fe6060f1SDimitry Andric    { }
909fe6060f1SDimitry Andric
910*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
911*81ad6265SDimitry Andric    // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
912*81ad6265SDimitry Andric
913*81ad6265SDimitry Andric    template <class... _Up, enable_if_t<
914*81ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
915*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
916*81ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
917*81ad6265SDimitry Andric    tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {}
918*81ad6265SDimitry Andric
919*81ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
920*81ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
921*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
922*81ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
923*81ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
924*81ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
925*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
926*81ad6265SDimitry Andric
927fe6060f1SDimitry Andric    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
928*81ad6265SDimitry Andric
929*81ad6265SDimitry Andric    template <template <class...> class Pred, class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
930*81ad6265SDimitry Andric    struct _CtorPredicateFromPair : false_type{};
931*81ad6265SDimitry Andric
932*81ad6265SDimitry Andric    template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
933*81ad6265SDimitry Andric    struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
934*81ad6265SDimitry Andric        Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
935*81ad6265SDimitry Andric        Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
936fe6060f1SDimitry Andric    > {};
937fe6060f1SDimitry Andric
938*81ad6265SDimitry Andric    template <class _Pair>
939*81ad6265SDimitry Andric    struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{};
940*81ad6265SDimitry Andric
941*81ad6265SDimitry Andric    template <class _Pair>
942*81ad6265SDimitry Andric    struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{};
943*81ad6265SDimitry Andric
944*81ad6265SDimitry Andric    template <class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
945*81ad6265SDimitry Andric    struct _BothImplicitlyConvertible : false_type{};
946*81ad6265SDimitry Andric
947*81ad6265SDimitry Andric    template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
948*81ad6265SDimitry Andric    struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
949*81ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>,
950*81ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2>
951fe6060f1SDimitry Andric    > {};
952fe6060f1SDimitry Andric
953349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
954fe6060f1SDimitry Andric        _And<
955*81ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
956*81ad6265SDimitry Andric            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
957fe6060f1SDimitry Andric        >::value
958fe6060f1SDimitry Andric    , int> = 0>
959fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
960fe6060f1SDimitry Andric    tuple(const pair<_Up1, _Up2>& __p)
961*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
962fe6060f1SDimitry Andric        : __base_(__p)
963fe6060f1SDimitry Andric    { }
964fe6060f1SDimitry Andric
965349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
966fe6060f1SDimitry Andric        _And<
967*81ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
968*81ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
969fe6060f1SDimitry Andric        >::value
970fe6060f1SDimitry Andric    , int> = 0>
971fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
972fe6060f1SDimitry Andric    explicit tuple(const pair<_Up1, _Up2>& __p)
973*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
974fe6060f1SDimitry Andric        : __base_(__p)
975fe6060f1SDimitry Andric    { }
976fe6060f1SDimitry Andric
977349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
978fe6060f1SDimitry Andric        _And<
979*81ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
980*81ad6265SDimitry Andric            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
981fe6060f1SDimitry Andric        >::value
982fe6060f1SDimitry Andric    , int> = 0>
983fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
984fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
985fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
986fe6060f1SDimitry Andric    { }
987fe6060f1SDimitry Andric
988349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
989fe6060f1SDimitry Andric        _And<
990*81ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
991*81ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
992fe6060f1SDimitry Andric        >::value
993fe6060f1SDimitry Andric    , int> = 0>
994fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
995fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
996fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
997fe6060f1SDimitry Andric    { }
998fe6060f1SDimitry Andric
999*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1000*81ad6265SDimitry Andric    // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
1001fe6060f1SDimitry Andric
1002*81ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
1003*81ad6265SDimitry Andric        _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
1004*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1005*81ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
1006*81ad6265SDimitry Andric    tuple(pair<_U1, _U2>& __p) : __base_(__p) {}
1007*81ad6265SDimitry Andric
1008*81ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
1009*81ad6265SDimitry Andric        _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
1010*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1011*81ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
1012*81ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {}
1013*81ad6265SDimitry Andric#endif
1014*81ad6265SDimitry Andric
1015*81ad6265SDimitry Andric    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
1016fe6060f1SDimitry Andric
1017349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1018fe6060f1SDimitry Andric        _And<
1019*81ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
1020*81ad6265SDimitry Andric            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1021fe6060f1SDimitry Andric        >::value
1022fe6060f1SDimitry Andric    , int> = 0>
1023fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1024fe6060f1SDimitry Andric    tuple(pair<_Up1, _Up2>&& __p)
1025*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
1026fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
1027fe6060f1SDimitry Andric    { }
1028fe6060f1SDimitry Andric
1029349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1030fe6060f1SDimitry Andric        _And<
1031*81ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
1032*81ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1033fe6060f1SDimitry Andric        >::value
1034fe6060f1SDimitry Andric    , int> = 0>
1035fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1036fe6060f1SDimitry Andric    explicit tuple(pair<_Up1, _Up2>&& __p)
1037*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
1038fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
1039fe6060f1SDimitry Andric    { }
1040fe6060f1SDimitry Andric
1041349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1042fe6060f1SDimitry Andric        _And<
1043*81ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
1044*81ad6265SDimitry Andric            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1045fe6060f1SDimitry Andric        >::value
1046fe6060f1SDimitry Andric    , int> = 0>
1047fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1048fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1049fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1050fe6060f1SDimitry Andric    { }
1051fe6060f1SDimitry Andric
1052349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1053fe6060f1SDimitry Andric        _And<
1054*81ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
1055*81ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1056fe6060f1SDimitry Andric        >::value
1057fe6060f1SDimitry Andric    , int> = 0>
1058fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1059fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1060fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1061fe6060f1SDimitry Andric    { }
1062fe6060f1SDimitry Andric
1063*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1064*81ad6265SDimitry Andric    // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
1065*81ad6265SDimitry Andric
1066*81ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
1067*81ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
1068*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1069*81ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
1070*81ad6265SDimitry Andric    tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {}
1071*81ad6265SDimitry Andric
1072*81ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
1073*81ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
1074*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1075*81ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
1076*81ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
1077*81ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
1078*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
1079*81ad6265SDimitry Andric
1080fe6060f1SDimitry Andric    // [tuple.assign]
1081fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1082fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
1083fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
10840b57cec5SDimitry Andric    {
1085fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1086fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
10870b57cec5SDimitry Andric        return *this;
10880b57cec5SDimitry Andric    }
10890b57cec5SDimitry Andric
1090*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1091*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1092*81ad6265SDimitry Andric    const tuple& operator=(tuple const& __tuple) const
1093*81ad6265SDimitry Andric      requires (_And<is_copy_assignable<const _Tp>...>::value) {
1094*81ad6265SDimitry Andric        std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
1095*81ad6265SDimitry Andric        return *this;
1096*81ad6265SDimitry Andric    }
1097*81ad6265SDimitry Andric
1098*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1099*81ad6265SDimitry Andric    const tuple& operator=(tuple&& __tuple) const
1100*81ad6265SDimitry Andric      requires (_And<is_assignable<const _Tp&, _Tp>...>::value) {
1101*81ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
1102*81ad6265SDimitry Andric                                         std::move(__tuple),
1103*81ad6265SDimitry Andric                                         __tuple_types<_Tp...>(),
1104*81ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
1105*81ad6265SDimitry Andric        return *this;
1106*81ad6265SDimitry Andric    }
1107*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
1108*81ad6265SDimitry Andric
1109fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1110fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
1111fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
11120b57cec5SDimitry Andric    {
1113fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1114fe6060f1SDimitry Andric            __tuple_types<_Tp...>(),
1115fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11160b57cec5SDimitry Andric        return *this;
11170b57cec5SDimitry Andric    }
11180b57cec5SDimitry Andric
1119349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1120fe6060f1SDimitry Andric        _And<
1121fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1122fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1123fe6060f1SDimitry Andric        >::value
1124fe6060f1SDimitry Andric    ,int> = 0>
1125fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1126fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...> const& __tuple)
1127fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
11280b57cec5SDimitry Andric    {
1129fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1130fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11310b57cec5SDimitry Andric        return *this;
11320b57cec5SDimitry Andric    }
11330b57cec5SDimitry Andric
1134349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1135fe6060f1SDimitry Andric        _And<
1136fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1137fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1138fe6060f1SDimitry Andric        >::value
1139fe6060f1SDimitry Andric    ,int> = 0>
1140fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1141fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...>&& __tuple)
1142fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1143fe6060f1SDimitry Andric    {
1144fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1145fe6060f1SDimitry Andric            __tuple_types<_Up...>(),
1146fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1147fe6060f1SDimitry Andric        return *this;
1148fe6060f1SDimitry Andric    }
1149fe6060f1SDimitry Andric
1150*81ad6265SDimitry Andric
1151*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1152*81ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
1153*81ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
1154*81ad6265SDimitry Andric             is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
1155*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1156*81ad6265SDimitry Andric    const tuple& operator=(const tuple<_UTypes...>& __u) const {
1157*81ad6265SDimitry Andric        std::__memberwise_copy_assign(*this,
1158*81ad6265SDimitry Andric                                      __u,
1159*81ad6265SDimitry Andric                                      typename __make_tuple_indices<sizeof...(_Tp)>::type());
1160*81ad6265SDimitry Andric        return *this;
1161*81ad6265SDimitry Andric    }
1162*81ad6265SDimitry Andric
1163*81ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
1164*81ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
1165*81ad6265SDimitry Andric             is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
1166*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1167*81ad6265SDimitry Andric    const tuple& operator=(tuple<_UTypes...>&& __u) const {
1168*81ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
1169*81ad6265SDimitry Andric                                         __u,
1170*81ad6265SDimitry Andric                                         __tuple_types<_UTypes...>(),
1171*81ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
1172*81ad6265SDimitry Andric        return *this;
1173*81ad6265SDimitry Andric    }
1174*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
1175*81ad6265SDimitry Andric
1176*81ad6265SDimitry Andric    template <template<class...> class Pred, bool _Const,
1177*81ad6265SDimitry Andric              class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
1178*81ad6265SDimitry Andric    struct _AssignPredicateFromPair : false_type {};
1179*81ad6265SDimitry Andric
1180*81ad6265SDimitry Andric    template <template<class...> class Pred, bool _Const,
1181*81ad6265SDimitry Andric              class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
1182*81ad6265SDimitry Andric    struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
1183*81ad6265SDimitry Andric        _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
1184*81ad6265SDimitry Andric             Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
1185*81ad6265SDimitry Andric            > {};
1186*81ad6265SDimitry Andric
1187*81ad6265SDimitry Andric    template <bool _Const, class _Pair>
1188*81ad6265SDimitry Andric    struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {};
1189*81ad6265SDimitry Andric
1190*81ad6265SDimitry Andric    template <bool _Const, class _Pair>
1191*81ad6265SDimitry Andric    struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
1192*81ad6265SDimitry Andric
1193*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1194*81ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
1195*81ad6265SDimitry Andric        _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
1196*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1197*81ad6265SDimitry Andric    const tuple& operator=(const pair<_U1, _U2>& __pair) const
1198*81ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) {
1199*81ad6265SDimitry Andric        std::get<0>(*this) = __pair.first;
1200*81ad6265SDimitry Andric        std::get<1>(*this) = __pair.second;
1201*81ad6265SDimitry Andric        return *this;
1202*81ad6265SDimitry Andric    }
1203*81ad6265SDimitry Andric
1204*81ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
1205*81ad6265SDimitry Andric        _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr>
1206*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1207*81ad6265SDimitry Andric    const tuple& operator=(pair<_U1, _U2>&& __pair) const
1208*81ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) {
1209*81ad6265SDimitry Andric        std::get<0>(*this) = std::move(__pair.first);
1210*81ad6265SDimitry Andric        std::get<1>(*this) = std::move(__pair.second);
1211*81ad6265SDimitry Andric        return *this;
1212*81ad6265SDimitry Andric    }
1213*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
1214*81ad6265SDimitry Andric
1215*81ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
1216*81ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
1217fe6060f1SDimitry Andric    ,int> = 0>
1218fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1219fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1220*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value))
1221fe6060f1SDimitry Andric    {
1222fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = __pair.first;
1223fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = __pair.second;
1224fe6060f1SDimitry Andric        return *this;
1225fe6060f1SDimitry Andric    }
1226fe6060f1SDimitry Andric
1227*81ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
1228*81ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value
1229fe6060f1SDimitry Andric    ,int> = 0>
1230fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1231fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1232*81ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value))
1233fe6060f1SDimitry Andric    {
1234fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1235fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1236fe6060f1SDimitry Andric        return *this;
1237fe6060f1SDimitry Andric    }
1238fe6060f1SDimitry Andric
1239fe6060f1SDimitry Andric    // EXTENSION
1240349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = __enable_if_t<
1241fe6060f1SDimitry Andric        _And<
1242fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1243fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1244fe6060f1SDimitry Andric        >::value
1245fe6060f1SDimitry Andric    > >
1246fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1247fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np> const& __array)
1248fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1249fe6060f1SDimitry Andric    {
1250fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __array,
1251fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1252fe6060f1SDimitry Andric        return *this;
1253fe6060f1SDimitry Andric    }
1254fe6060f1SDimitry Andric
1255fe6060f1SDimitry Andric    // EXTENSION
1256349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1257fe6060f1SDimitry Andric        _And<
1258fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1259fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1260fe6060f1SDimitry Andric        >::value
1261fe6060f1SDimitry Andric    > >
1262fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1263fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np>&& __array)
1264fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1265fe6060f1SDimitry Andric    {
1266fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1267fe6060f1SDimitry Andric            __tuple_types<_If<true, _Up, _Tp>...>(),
1268fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1269fe6060f1SDimitry Andric        return *this;
1270fe6060f1SDimitry Andric    }
1271fe6060f1SDimitry Andric
1272fe6060f1SDimitry Andric    // [tuple.swap]
1273fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
12740b57cec5SDimitry Andric    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
12750b57cec5SDimitry Andric        {__base_.swap(__t.__base_);}
1276*81ad6265SDimitry Andric
1277*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1278*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1279*81ad6265SDimitry Andric    void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
1280*81ad6265SDimitry Andric        __base_.swap(__t.__base_);
1281*81ad6265SDimitry Andric    }
1282*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
12830b57cec5SDimitry Andric};
12840b57cec5SDimitry Andric
12850b57cec5SDimitry Andrictemplate <>
12860b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<>
12870b57cec5SDimitry Andric{
12880b57cec5SDimitry Andricpublic:
1289fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr
1290fe6060f1SDimitry Andric        tuple() _NOEXCEPT = default;
12910b57cec5SDimitry Andric    template <class _Alloc>
1292fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
12930b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
12940b57cec5SDimitry Andric    template <class _Alloc>
1295fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
12960b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
12970b57cec5SDimitry Andric    template <class _Up>
1298fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
12990b57cec5SDimitry Andric        tuple(array<_Up, 0>) _NOEXCEPT {}
13000b57cec5SDimitry Andric    template <class _Alloc, class _Up>
1301fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
13020b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1303fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
13040b57cec5SDimitry Andric    void swap(tuple&) _NOEXCEPT {}
1305*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1306*81ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
1307*81ad6265SDimitry Andric#endif
13080b57cec5SDimitry Andric};
13090b57cec5SDimitry Andric
131004eeddc0SDimitry Andric#if _LIBCPP_STD_VER > 20
131104eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
131204eeddc0SDimitry Andric    requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
131304eeddc0SDimitry Andricstruct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
131404eeddc0SDimitry Andric    using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
131504eeddc0SDimitry Andric};
131604eeddc0SDimitry Andric
131704eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes>
131804eeddc0SDimitry Andric    requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
131904eeddc0SDimitry Andricstruct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
132004eeddc0SDimitry Andric    using type = tuple<common_type_t<_TTypes, _UTypes>...>;
132104eeddc0SDimitry Andric};
1322*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
132304eeddc0SDimitry Andric
132404eeddc0SDimitry Andric#if _LIBCPP_STD_VER > 14
1325e40139ffSDimitry Andrictemplate <class ..._Tp>
1326e40139ffSDimitry Andrictuple(_Tp...) -> tuple<_Tp...>;
1327e40139ffSDimitry Andrictemplate <class _Tp1, class _Tp2>
1328e40139ffSDimitry Andrictuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1329e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1330e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1331e40139ffSDimitry Andrictemplate <class _Alloc, class _Tp1, class _Tp2>
1332e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1333e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1334e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
13350b57cec5SDimitry Andric#endif
13360b57cec5SDimitry Andric
13370b57cec5SDimitry Andrictemplate <class ..._Tp>
1338fe6060f1SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
13390b57cec5SDimitry Andrictypename enable_if
13400b57cec5SDimitry Andric<
13410b57cec5SDimitry Andric    __all<__is_swappable<_Tp>::value...>::value,
13420b57cec5SDimitry Andric    void
13430b57cec5SDimitry Andric>::type
13440b57cec5SDimitry Andricswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
13450b57cec5SDimitry Andric                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
13460b57cec5SDimitry Andric    {__t.swap(__u);}
13470b57cec5SDimitry Andric
1348*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
1349*81ad6265SDimitry Andrictemplate <class... _Tp>
1350*81ad6265SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1351*81ad6265SDimitry Andricenable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
1352*81ad6265SDimitry Andricswap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs)
1353*81ad6265SDimitry Andric        noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) {
1354*81ad6265SDimitry Andric    __lhs.swap(__rhs);
1355*81ad6265SDimitry Andric}
1356*81ad6265SDimitry Andric#endif
1357*81ad6265SDimitry Andric
13580b57cec5SDimitry Andric// get
13590b57cec5SDimitry Andric
13600b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
13610b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13620b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&
13630b57cec5SDimitry Andricget(tuple<_Tp...>& __t) _NOEXCEPT
13640b57cec5SDimitry Andric{
1365349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13660b57cec5SDimitry Andric    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
13670b57cec5SDimitry Andric}
13680b57cec5SDimitry Andric
13690b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
13700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13710b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
13720b57cec5SDimitry Andricget(const tuple<_Tp...>& __t) _NOEXCEPT
13730b57cec5SDimitry Andric{
1374349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13750b57cec5SDimitry Andric    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
13760b57cec5SDimitry Andric}
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
13790b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13800b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&&
13810b57cec5SDimitry Andricget(tuple<_Tp...>&& __t) _NOEXCEPT
13820b57cec5SDimitry Andric{
1383349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13840b57cec5SDimitry Andric    return static_cast<type&&>(
13850b57cec5SDimitry Andric             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
13860b57cec5SDimitry Andric}
13870b57cec5SDimitry Andric
13880b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
13890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
13900b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
13910b57cec5SDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT
13920b57cec5SDimitry Andric{
1393349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13940b57cec5SDimitry Andric    return static_cast<const type&&>(
13950b57cec5SDimitry Andric             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
13960b57cec5SDimitry Andric}
13970b57cec5SDimitry Andric
13980b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
13990b57cec5SDimitry Andric
14000b57cec5SDimitry Andricnamespace __find_detail {
14010b57cec5SDimitry Andric
1402fe6060f1SDimitry Andricstatic constexpr size_t __not_found = static_cast<size_t>(-1);
14030b57cec5SDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1;
14040b57cec5SDimitry Andric
14050b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14060b57cec5SDimitry Andricconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
14070b57cec5SDimitry Andric    return !__matches ? __res :
14080b57cec5SDimitry Andric        (__res == __not_found ? __curr_i : __ambiguous);
14090b57cec5SDimitry Andric}
14100b57cec5SDimitry Andric
14110b57cec5SDimitry Andrictemplate <size_t _Nx>
14120b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14130b57cec5SDimitry Andricconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
14140b57cec5SDimitry Andric  return __i == _Nx ? __not_found :
14150b57cec5SDimitry Andric      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
14160b57cec5SDimitry Andric}
14170b57cec5SDimitry Andric
14180b57cec5SDimitry Andrictemplate <class _T1, class ..._Args>
14190b57cec5SDimitry Andricstruct __find_exactly_one_checked {
14200b57cec5SDimitry Andric    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
14210b57cec5SDimitry Andric    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
14220b57cec5SDimitry Andric    static_assert(value != __not_found, "type not found in type list" );
14230b57cec5SDimitry Andric    static_assert(value != __ambiguous, "type occurs more than once in type list");
14240b57cec5SDimitry Andric};
14250b57cec5SDimitry Andric
14260b57cec5SDimitry Andrictemplate <class _T1>
14270b57cec5SDimitry Andricstruct __find_exactly_one_checked<_T1> {
14280b57cec5SDimitry Andric    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
14290b57cec5SDimitry Andric};
14300b57cec5SDimitry Andric
14310eae32dcSDimitry Andric} // namespace __find_detail
14320b57cec5SDimitry Andric
14330b57cec5SDimitry Andrictemplate <typename _T1, typename... _Args>
14340b57cec5SDimitry Andricstruct __find_exactly_one_t
14350b57cec5SDimitry Andric    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
14360b57cec5SDimitry Andric};
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14400b57cec5SDimitry Andricconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
14410b57cec5SDimitry Andric{
14420b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14430b57cec5SDimitry Andric}
14440b57cec5SDimitry Andric
14450b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14470b57cec5SDimitry Andricconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
14480b57cec5SDimitry Andric{
14490b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14500b57cec5SDimitry Andric}
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14540b57cec5SDimitry Andricconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
14550b57cec5SDimitry Andric{
14560b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14570b57cec5SDimitry Andric}
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14610b57cec5SDimitry Andricconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
14620b57cec5SDimitry Andric{
14630b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14640b57cec5SDimitry Andric}
14650b57cec5SDimitry Andric
14660b57cec5SDimitry Andric#endif
14670b57cec5SDimitry Andric
14680b57cec5SDimitry Andric// tie
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andrictemplate <class ..._Tp>
14710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14720b57cec5SDimitry Andrictuple<_Tp&...>
14730b57cec5SDimitry Andrictie(_Tp&... __t) _NOEXCEPT
14740b57cec5SDimitry Andric{
14750b57cec5SDimitry Andric    return tuple<_Tp&...>(__t...);
14760b57cec5SDimitry Andric}
14770b57cec5SDimitry Andric
14780b57cec5SDimitry Andrictemplate <class _Up>
14790b57cec5SDimitry Andricstruct __ignore_t
14800b57cec5SDimitry Andric{
14810b57cec5SDimitry Andric    template <class _Tp>
14820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14830b57cec5SDimitry Andric    const __ignore_t& operator=(_Tp&&) const {return *this;}
14840b57cec5SDimitry Andric};
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andricnamespace {
1487349cc55cSDimitry Andric  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
14880eae32dcSDimitry Andric} // namespace
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andrictemplate <class... _Tp>
14910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14920b57cec5SDimitry Andrictuple<typename __unwrap_ref_decay<_Tp>::type...>
14930b57cec5SDimitry Andricmake_tuple(_Tp&&... __t)
14940b57cec5SDimitry Andric{
14950b57cec5SDimitry Andric    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
14960b57cec5SDimitry Andric}
14970b57cec5SDimitry Andric
14980b57cec5SDimitry Andrictemplate <class... _Tp>
14990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15000b57cec5SDimitry Andrictuple<_Tp&&...>
15010b57cec5SDimitry Andricforward_as_tuple(_Tp&&... __t) _NOEXCEPT
15020b57cec5SDimitry Andric{
15030b57cec5SDimitry Andric    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
15040b57cec5SDimitry Andric}
15050b57cec5SDimitry Andric
15060b57cec5SDimitry Andrictemplate <size_t _Ip>
15070b57cec5SDimitry Andricstruct __tuple_equal
15080b57cec5SDimitry Andric{
15090b57cec5SDimitry Andric    template <class _Tp, class _Up>
15100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15110b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
15120b57cec5SDimitry Andric    {
15130b57cec5SDimitry Andric        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
15140b57cec5SDimitry Andric    }
15150b57cec5SDimitry Andric};
15160b57cec5SDimitry Andric
15170b57cec5SDimitry Andrictemplate <>
15180b57cec5SDimitry Andricstruct __tuple_equal<0>
15190b57cec5SDimitry Andric{
15200b57cec5SDimitry Andric    template <class _Tp, class _Up>
15210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15220b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
15230b57cec5SDimitry Andric    {
15240b57cec5SDimitry Andric        return true;
15250b57cec5SDimitry Andric    }
15260b57cec5SDimitry Andric};
15270b57cec5SDimitry Andric
15280b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
15290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15300b57cec5SDimitry Andricbool
15310b57cec5SDimitry Andricoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15320b57cec5SDimitry Andric{
15330b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
15340b57cec5SDimitry Andric    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
15350b57cec5SDimitry Andric}
15360b57cec5SDimitry Andric
1537*81ad6265SDimitry Andric#if _LIBCPP_STD_VER > 17
1538349cc55cSDimitry Andric
1539349cc55cSDimitry Andric// operator<=>
1540349cc55cSDimitry Andric
1541349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1542349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1543349cc55cSDimitry Andricauto
1544349cc55cSDimitry Andric__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1545349cc55cSDimitry Andric    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1546349cc55cSDimitry Andric    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1547349cc55cSDimitry Andric    return __result;
1548349cc55cSDimitry Andric}
1549349cc55cSDimitry Andric
1550349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up>
1551349cc55cSDimitry Andricrequires (sizeof...(_Tp) == sizeof...(_Up))
1552349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1553349cc55cSDimitry Andriccommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1554349cc55cSDimitry Andricoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1555349cc55cSDimitry Andric{
1556349cc55cSDimitry Andric    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1557349cc55cSDimitry Andric}
1558349cc55cSDimitry Andric
1559*81ad6265SDimitry Andric#else // _LIBCPP_STD_VER > 17
1560349cc55cSDimitry Andric
15610b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
15620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15630b57cec5SDimitry Andricbool
15640b57cec5SDimitry Andricoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15650b57cec5SDimitry Andric{
15660b57cec5SDimitry Andric    return !(__x == __y);
15670b57cec5SDimitry Andric}
15680b57cec5SDimitry Andric
15690b57cec5SDimitry Andrictemplate <size_t _Ip>
15700b57cec5SDimitry Andricstruct __tuple_less
15710b57cec5SDimitry Andric{
15720b57cec5SDimitry Andric    template <class _Tp, class _Up>
15730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15740b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
15750b57cec5SDimitry Andric    {
15760b57cec5SDimitry Andric        const size_t __idx = tuple_size<_Tp>::value - _Ip;
15770b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
15780b57cec5SDimitry Andric            return true;
15790b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
15800b57cec5SDimitry Andric            return false;
15810b57cec5SDimitry Andric        return __tuple_less<_Ip-1>()(__x, __y);
15820b57cec5SDimitry Andric    }
15830b57cec5SDimitry Andric};
15840b57cec5SDimitry Andric
15850b57cec5SDimitry Andrictemplate <>
15860b57cec5SDimitry Andricstruct __tuple_less<0>
15870b57cec5SDimitry Andric{
15880b57cec5SDimitry Andric    template <class _Tp, class _Up>
15890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15900b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
15910b57cec5SDimitry Andric    {
15920b57cec5SDimitry Andric        return false;
15930b57cec5SDimitry Andric    }
15940b57cec5SDimitry Andric};
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
15970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
15980b57cec5SDimitry Andricbool
15990b57cec5SDimitry Andricoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16000b57cec5SDimitry Andric{
16010b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
16020b57cec5SDimitry Andric    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
16030b57cec5SDimitry Andric}
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
16060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
16070b57cec5SDimitry Andricbool
16080b57cec5SDimitry Andricoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16090b57cec5SDimitry Andric{
16100b57cec5SDimitry Andric    return __y < __x;
16110b57cec5SDimitry Andric}
16120b57cec5SDimitry Andric
16130b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
16140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
16150b57cec5SDimitry Andricbool
16160b57cec5SDimitry Andricoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16170b57cec5SDimitry Andric{
16180b57cec5SDimitry Andric    return !(__x < __y);
16190b57cec5SDimitry Andric}
16200b57cec5SDimitry Andric
16210b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
16220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
16230b57cec5SDimitry Andricbool
16240b57cec5SDimitry Andricoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16250b57cec5SDimitry Andric{
16260b57cec5SDimitry Andric    return !(__y < __x);
16270b57cec5SDimitry Andric}
16280b57cec5SDimitry Andric
1629*81ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 17
1630349cc55cSDimitry Andric
16310b57cec5SDimitry Andric// tuple_cat
16320b57cec5SDimitry Andric
16330b57cec5SDimitry Andrictemplate <class _Tp, class _Up> struct __tuple_cat_type;
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andrictemplate <class ..._Ttypes, class ..._Utypes>
16360b57cec5SDimitry Andricstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
16370b57cec5SDimitry Andric{
1638349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
16390b57cec5SDimitry Andric};
16400b57cec5SDimitry Andric
16410b57cec5SDimitry Andrictemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
16420b57cec5SDimitry Andricstruct __tuple_cat_return_1
16430b57cec5SDimitry Andric{
16440b57cec5SDimitry Andric};
16450b57cec5SDimitry Andric
16460b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0>
16470b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
16480b57cec5SDimitry Andric{
1649*81ad6265SDimitry Andric  using type _LIBCPP_NODEBUG = typename __tuple_cat_type<
1650*81ad6265SDimitry Andric      tuple<_Types...>,
1651*81ad6265SDimitry Andric      typename __make_tuple_types<__uncvref_t<_Tuple0> >::type
1652*81ad6265SDimitry Andric    >::type;
16530b57cec5SDimitry Andric};
16540b57cec5SDimitry Andric
16550b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
16560b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
16570b57cec5SDimitry Andric    : public __tuple_cat_return_1<
16580b57cec5SDimitry Andric                 typename __tuple_cat_type<
16590b57cec5SDimitry Andric                     tuple<_Types...>,
1660*81ad6265SDimitry Andric                     typename __make_tuple_types<__uncvref_t<_Tuple0> >::type
16610b57cec5SDimitry Andric                 >::type,
16620b57cec5SDimitry Andric                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
16630b57cec5SDimitry Andric                 _Tuple1, _Tuples...>
16640b57cec5SDimitry Andric{
16650b57cec5SDimitry Andric};
16660b57cec5SDimitry Andric
16670b57cec5SDimitry Andrictemplate <class ..._Tuples> struct __tuple_cat_return;
16680b57cec5SDimitry Andric
16690b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
16700b57cec5SDimitry Andricstruct __tuple_cat_return<_Tuple0, _Tuples...>
16710b57cec5SDimitry Andric    : public __tuple_cat_return_1<tuple<>,
16720b57cec5SDimitry Andric         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
16730b57cec5SDimitry Andric                                                                     _Tuples...>
16740b57cec5SDimitry Andric{
16750b57cec5SDimitry Andric};
16760b57cec5SDimitry Andric
16770b57cec5SDimitry Andrictemplate <>
16780b57cec5SDimitry Andricstruct __tuple_cat_return<>
16790b57cec5SDimitry Andric{
1680349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<> type;
16810b57cec5SDimitry Andric};
16820b57cec5SDimitry Andric
16830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
16840b57cec5SDimitry Andrictuple<>
16850b57cec5SDimitry Andrictuple_cat()
16860b57cec5SDimitry Andric{
16870b57cec5SDimitry Andric    return tuple<>();
16880b57cec5SDimitry Andric}
16890b57cec5SDimitry Andric
16900b57cec5SDimitry Andrictemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
16910b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp;
16920b57cec5SDimitry Andric
16930b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0>
16940b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
16950b57cec5SDimitry Andric{
1696349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
16970b57cec5SDimitry Andric    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
16980b57cec5SDimitry Andric                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
16990b57cec5SDimitry Andric};
17000b57cec5SDimitry Andric
17010b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
17020b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
17030b57cec5SDimitry Andric                                  _Tuple0, _Tuple1, _Tuples...>
17040b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<
17050b57cec5SDimitry Andric         tuple<_Types..., typename __apply_cv<_Tuple0,
17060b57cec5SDimitry Andric               typename tuple_element<_I0,
17070b57cec5SDimitry Andric                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
17080b57cec5SDimitry Andric         typename __make_tuple_indices<tuple_size<typename
17090b57cec5SDimitry Andric                                 remove_reference<_Tuple1>::type>::value>::type,
17100b57cec5SDimitry Andric         _Tuple1, _Tuples...>
17110b57cec5SDimitry Andric{
17120b57cec5SDimitry Andric};
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
17150b57cec5SDimitry Andricstruct __tuple_cat_return_ref
17160b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<tuple<>,
17170b57cec5SDimitry Andric               typename __make_tuple_indices<
17180b57cec5SDimitry Andric                        tuple_size<typename remove_reference<_Tuple0>::type>::value
17190b57cec5SDimitry Andric               >::type, _Tuple0, _Tuples...>
17200b57cec5SDimitry Andric{
17210b57cec5SDimitry Andric};
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andrictemplate <class _Types, class _I0, class _J0>
17240b57cec5SDimitry Andricstruct __tuple_cat;
17250b57cec5SDimitry Andric
17260b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
17270b57cec5SDimitry Andricstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
17280b57cec5SDimitry Andric{
17290b57cec5SDimitry Andric    template <class _Tuple0>
17300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
17310b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
17320b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
17330b57cec5SDimitry Andric    {
1734*81ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1735480093f4SDimitry Andric        return _VSTD::forward_as_tuple(
1736480093f4SDimitry Andric            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
17370b57cec5SDimitry Andric            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
17380b57cec5SDimitry Andric    }
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andric    template <class _Tuple0, class _Tuple1, class ..._Tuples>
17410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
17420b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
17430b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
17440b57cec5SDimitry Andric    {
1745*81ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1746349cc55cSDimitry Andric        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
1747349cc55cSDimitry Andric        typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
17480b57cec5SDimitry Andric        return __tuple_cat<
1749480093f4SDimitry Andric            tuple<_Types...,
1750480093f4SDimitry Andric                  typename __apply_cv<_Tuple0, typename tuple_element<
1751480093f4SDimitry Andric                                                   _J0, _T0>::type>::type&&...>,
1752480093f4SDimitry Andric            typename __make_tuple_indices<sizeof...(_Types) +
1753480093f4SDimitry Andric                                          tuple_size<_T0>::value>::type,
1754480093f4SDimitry Andric            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1755480093f4SDimitry Andric            _VSTD::forward_as_tuple(
17560b57cec5SDimitry Andric                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1757480093f4SDimitry Andric                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1758480093f4SDimitry Andric            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
17590b57cec5SDimitry Andric    }
17600b57cec5SDimitry Andric};
17610b57cec5SDimitry Andric
17620b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples>
17630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
17640b57cec5SDimitry Andrictypename __tuple_cat_return<_Tuple0, _Tuples...>::type
17650b57cec5SDimitry Andrictuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
17660b57cec5SDimitry Andric{
1767349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
17680b57cec5SDimitry Andric    return __tuple_cat<tuple<>, __tuple_indices<>,
17690b57cec5SDimitry Andric                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
17700b57cec5SDimitry Andric                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
17710b57cec5SDimitry Andric                                            _VSTD::forward<_Tuples>(__tpls)...);
17720b57cec5SDimitry Andric}
17730b57cec5SDimitry Andric
17740b57cec5SDimitry Andrictemplate <class ..._Tp, class _Alloc>
17750b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
17760b57cec5SDimitry Andric    : true_type {};
17770b57cec5SDimitry Andric
17780b57cec5SDimitry Andrictemplate <class _T1, class _T2>
17790b57cec5SDimitry Andrictemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1780e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17810b57cec5SDimitry Andricpair<_T1, _T2>::pair(piecewise_construct_t,
17820b57cec5SDimitry Andric                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
17830b57cec5SDimitry Andric                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
17840b57cec5SDimitry Andric    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
17850b57cec5SDimitry Andric      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
17860b57cec5SDimitry Andric{
17870b57cec5SDimitry Andric}
17880b57cec5SDimitry Andric
17890b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
17900b57cec5SDimitry Andrictemplate <class _Tp>
1791349cc55cSDimitry Andricinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andric#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple, size_t ..._Id>
17960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
17970b57cec5SDimitry Andricconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
17980b57cec5SDimitry Andric                                            __tuple_indices<_Id...>)
17990b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
1800*81ad6265SDimitry Andric    _VSTD::__invoke(
18010b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f),
18020b57cec5SDimitry Andric        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
18030b57cec5SDimitry Andric)
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple>
18060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18070b57cec5SDimitry Andricconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
18080b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18090b57cec5SDimitry Andric    _VSTD::__apply_tuple_impl(
18100b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
18110b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18120b57cec5SDimitry Andric)
18130b57cec5SDimitry Andric
18140b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx>
18150b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18160b57cec5SDimitry Andricconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
18170b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18180b57cec5SDimitry Andric    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
18190b57cec5SDimitry Andric)
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple>
18220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18230b57cec5SDimitry Andricconstexpr _Tp make_from_tuple(_Tuple&& __t)
18240b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18250b57cec5SDimitry Andric    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
18260b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18270b57cec5SDimitry Andric)
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andric#undef _LIBCPP_NOEXCEPT_RETURN
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andric#endif // _LIBCPP_TUPLE
1838