xref: /freebsd/contrib/llvm-project/libcxx/include/tuple (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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;
2881ad6265SDimitry Andric
2981ad6265SDimitry Andric    template<class... UTypes>
3081ad6265SDimitry 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
3581ad6265SDimitry Andric    template<class... UTypes>
3681ad6265SDimitry Andric        constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23
3781ad6265SDimitry Andric
3881ad6265SDimitry Andric    template<class U1, class U2>
3981ad6265SDimitry 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
4481ad6265SDimitry Andric    template<class U1, class U2>
4581ad6265SDimitry 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
5881ad6265SDimitry Andric    template<class Alloc, class... UTypes>
5981ad6265SDimitry Andric        constexpr explicit(see-below)
6081ad6265SDimitry 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
6581ad6265SDimitry Andric    template<class Alloc, class... UTypes>
6681ad6265SDimitry Andric        constexpr explicit(see-below)
6781ad6265SDimitry Andric          tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);               // C++23
6881ad6265SDimitry Andric    template<class Alloc, class U1, class U2>
6981ad6265SDimitry Andric        constexpr explicit(see-below)
7081ad6265SDimitry 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
7581ad6265SDimitry Andric    template<class Alloc, class U1, class U2>
7681ad6265SDimitry Andric        constexpr explicit(see-below)
7781ad6265SDimitry 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
8081ad6265SDimitry 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
8281ad6265SDimitry 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
8581ad6265SDimitry Andric    template<class... UTypes>
8681ad6265SDimitry 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
8981ad6265SDimitry Andric    template<class... UTypes>
9081ad6265SDimitry 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>
9481ad6265SDimitry Andric        constexpr const tuple& operator=(const pair<U1, U2>&) const;   // iff sizeof...(Types) == 2 // C++23
9581ad6265SDimitry Andric    template <class U1, class U2>
96fe6060f1SDimitry Andric        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
9781ad6265SDimitry Andric    template<class U1, class U2>
9881ad6265SDimitry 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
10681ad6265SDimitry 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
19781ad6265SDimitry Andrictemplate <class... Types>
19881ad6265SDimitry Andric  constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below);   // C++23
19981ad6265SDimitry Andric
2000b57cec5SDimitry Andric}  // std
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric*/
2030b57cec5SDimitry Andric
20481ad6265SDimitry 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>
208*bdd1243dSDimitry Andric#include <__functional/invoke.h>
209fe6060f1SDimitry Andric#include <__functional/unwrap_ref.h>
210*bdd1243dSDimitry Andric#include <__fwd/array.h>
211fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
212fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
213*bdd1243dSDimitry Andric#include <__type_traits/apply_cv.h>
214*bdd1243dSDimitry Andric#include <__type_traits/common_reference.h>
215*bdd1243dSDimitry Andric#include <__type_traits/common_type.h>
216*bdd1243dSDimitry Andric#include <__type_traits/conditional.h>
217*bdd1243dSDimitry Andric#include <__type_traits/conjunction.h>
218*bdd1243dSDimitry Andric#include <__type_traits/copy_cvref.h>
219*bdd1243dSDimitry Andric#include <__type_traits/disjunction.h>
220*bdd1243dSDimitry Andric#include <__type_traits/is_arithmetic.h>
221*bdd1243dSDimitry Andric#include <__type_traits/is_assignable.h>
222*bdd1243dSDimitry Andric#include <__type_traits/is_constructible.h>
223*bdd1243dSDimitry Andric#include <__type_traits/is_convertible.h>
224*bdd1243dSDimitry Andric#include <__type_traits/is_copy_assignable.h>
225*bdd1243dSDimitry Andric#include <__type_traits/is_copy_constructible.h>
226*bdd1243dSDimitry Andric#include <__type_traits/is_default_constructible.h>
227*bdd1243dSDimitry Andric#include <__type_traits/is_empty.h>
228*bdd1243dSDimitry Andric#include <__type_traits/is_final.h>
229*bdd1243dSDimitry Andric#include <__type_traits/is_implicitly_default_constructible.h>
230*bdd1243dSDimitry Andric#include <__type_traits/is_move_assignable.h>
231*bdd1243dSDimitry Andric#include <__type_traits/is_move_constructible.h>
232*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_assignable.h>
233*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_constructible.h>
234*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_assignable.h>
235*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_constructible.h>
236*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_default_constructible.h>
237*bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_move_assignable.h>
238*bdd1243dSDimitry Andric#include <__type_traits/is_reference.h>
239*bdd1243dSDimitry Andric#include <__type_traits/is_same.h>
240*bdd1243dSDimitry Andric#include <__type_traits/is_swappable.h>
241*bdd1243dSDimitry Andric#include <__type_traits/lazy.h>
242*bdd1243dSDimitry Andric#include <__type_traits/maybe_const.h>
243*bdd1243dSDimitry Andric#include <__type_traits/nat.h>
244*bdd1243dSDimitry Andric#include <__type_traits/negation.h>
245*bdd1243dSDimitry Andric#include <__type_traits/remove_cvref.h>
246*bdd1243dSDimitry Andric#include <__type_traits/remove_reference.h>
247fe6060f1SDimitry Andric#include <__utility/forward.h>
248349cc55cSDimitry Andric#include <__utility/integer_sequence.h>
249fe6060f1SDimitry Andric#include <__utility/move.h>
25081ad6265SDimitry Andric#include <__utility/pair.h>
25181ad6265SDimitry Andric#include <__utility/piecewise_construct.h>
25281ad6265SDimitry Andric#include <__utility/swap.h>
2530b57cec5SDimitry Andric#include <cstddef>
2540b57cec5SDimitry Andric#include <version>
2550b57cec5SDimitry Andric
25681ad6265SDimitry Andric// standard-mandated includes
257*bdd1243dSDimitry Andric
258*bdd1243dSDimitry Andric// [tuple.syn]
25981ad6265SDimitry Andric#include <compare>
26081ad6265SDimitry Andric
2610b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2620b57cec5SDimitry Andric#  pragma GCC system_header
2630b57cec5SDimitry Andric#endif
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andric// __tuple_leaf
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp,
2730b57cec5SDimitry Andric          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
2740b57cec5SDimitry Andric         >
2750b57cec5SDimitry Andricclass __tuple_leaf;
2760b57cec5SDimitry Andric
2770b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
278*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
2790b57cec5SDimitry Andricvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
2800b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
2810b57cec5SDimitry Andric{
2820b57cec5SDimitry Andric    swap(__x.get(), __y.get());
2830b57cec5SDimitry Andric}
2840b57cec5SDimitry Andric
28581ad6265SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
286*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
28781ad6265SDimitry Andricvoid swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y)
28881ad6265SDimitry Andric     _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) {
28981ad6265SDimitry Andric  swap(__x.get(), __y.get());
29081ad6265SDimitry Andric}
29181ad6265SDimitry Andric
2920b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool>
2930b57cec5SDimitry Andricclass __tuple_leaf
2940b57cec5SDimitry Andric{
2950b57cec5SDimitry Andric    _Hp __value_;
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric    template <class _Tp>
2980b57cec5SDimitry Andric    static constexpr bool __can_bind_reference() {
2990b57cec5SDimitry Andric#if __has_keyword(__reference_binds_to_temporary)
3000b57cec5SDimitry Andric      return !__reference_binds_to_temporary(_Hp, _Tp);
3010b57cec5SDimitry Andric#else
3020b57cec5SDimitry Andric      return true;
3030b57cec5SDimitry Andric#endif
3040b57cec5SDimitry Andric    }
3050b57cec5SDimitry Andric
306*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX14
3070b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
3080b57cec5SDimitry Andricpublic:
309fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
3100b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
3110b57cec5SDimitry Andric       {static_assert(!is_reference<_Hp>::value,
3120b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric    template <class _Alloc>
315fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3160b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
3170b57cec5SDimitry Andric            : __value_()
3180b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3190b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric    template <class _Alloc>
322fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3230b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3240b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a)
3250b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3260b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric    template <class _Alloc>
329fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3300b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3310b57cec5SDimitry Andric            : __value_(__a)
3320b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3330b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    template <class _Tp,
336349cc55cSDimitry Andric              class = __enable_if_t<
3370b57cec5SDimitry Andric                  _And<
338*bdd1243dSDimitry Andric                      _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
3390b57cec5SDimitry Andric                      is_constructible<_Hp, _Tp>
3400b57cec5SDimitry Andric                    >::value
3410b57cec5SDimitry Andric                >
3420b57cec5SDimitry Andric            >
343*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3440b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3450b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3460b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3470b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
350*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3510b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
3520b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3530b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3540b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
357*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3580b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
3590b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
3600b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3610b57cec5SDimitry Andric            "Attempted to uses-allocator construct a reference element in a tuple");}
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
364*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3650b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
3660b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t), __a)
3670b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3680b57cec5SDimitry Andric           "Attempted to uses-allocator construct a reference element in a tuple");}
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andric    __tuple_leaf(const __tuple_leaf& __t) = default;
3710b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf&& __t) = default;
3720b57cec5SDimitry Andric
373*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3740b57cec5SDimitry Andric    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3750b57cec5SDimitry Andric    {
3760b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
3770b57cec5SDimitry Andric        return 0;
3780b57cec5SDimitry Andric    }
3790b57cec5SDimitry Andric
380*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
38181ad6265SDimitry Andric    int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
38281ad6265SDimitry Andric        _VSTD::swap(*this, __t);
38381ad6265SDimitry Andric        return 0;
38481ad6265SDimitry Andric    }
38581ad6265SDimitry Andric
386*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return __value_;}
387*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return __value_;}
3880b57cec5SDimitry Andric};
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp>
3910b57cec5SDimitry Andricclass __tuple_leaf<_Ip, _Hp, true>
3920b57cec5SDimitry Andric    : private _Hp
3930b57cec5SDimitry Andric{
394*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX14
3950b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
3960b57cec5SDimitry Andricpublic:
397fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
3980b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric    template <class _Alloc>
401fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4020b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric    template <class _Alloc>
405fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4060b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
4070b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a) {}
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric    template <class _Alloc>
410fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4110b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
4120b57cec5SDimitry Andric            : _Hp(__a) {}
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric    template <class _Tp,
415349cc55cSDimitry Andric              class = __enable_if_t<
4160b57cec5SDimitry Andric                  _And<
417*bdd1243dSDimitry Andric                    _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
4180b57cec5SDimitry Andric                    is_constructible<_Hp, _Tp>
4190b57cec5SDimitry Andric                  >::value
4200b57cec5SDimitry Andric                >
4210b57cec5SDimitry Andric            >
422*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4230b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
4240b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
427fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4280b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
4290b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
432fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4330b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
4340b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
4350b57cec5SDimitry Andric
4360b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
437fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4380b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
4390b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf const &) = default;
4420b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf &&) = default;
4430b57cec5SDimitry Andric
444*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4450b57cec5SDimitry Andric    int
4460b57cec5SDimitry Andric    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
4470b57cec5SDimitry Andric    {
4480b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
4490b57cec5SDimitry Andric        return 0;
4500b57cec5SDimitry Andric    }
4510b57cec5SDimitry Andric
452*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
45381ad6265SDimitry Andric    int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
45481ad6265SDimitry Andric        _VSTD::swap(*this, __rhs);
45581ad6265SDimitry Andric        return 0;
45681ad6265SDimitry Andric    }
45781ad6265SDimitry Andric
458*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
459*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
4600b57cec5SDimitry Andric};
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andrictemplate <class ..._Tp>
463*bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4640b57cec5SDimitry Andricvoid __swallow(_Tp&&...) _NOEXCEPT {}
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andrictemplate <class _Tp>
4670b57cec5SDimitry Andricstruct __all_default_constructible;
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andrictemplate <class ..._Tp>
4700b57cec5SDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>>
4710b57cec5SDimitry Andric    : __all<is_default_constructible<_Tp>::value...>
4720b57cec5SDimitry Andric{ };
4730b57cec5SDimitry Andric
4740b57cec5SDimitry Andric// __tuple_impl
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andrictemplate<class _Indx, class ..._Tp> struct __tuple_impl;
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andrictemplate<size_t ..._Indx, class ..._Tp>
4790b57cec5SDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
4800b57cec5SDimitry Andric    : public __tuple_leaf<_Indx, _Tp>...
4810b57cec5SDimitry Andric{
4820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
483fe6060f1SDimitry Andric    constexpr __tuple_impl()
4840b57cec5SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andric    template <size_t ..._Uf, class ..._Tf,
4870b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
488*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4890b57cec5SDimitry Andric        explicit
4900b57cec5SDimitry Andric        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
4910b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
4920b57cec5SDimitry Andric                     _Up&&... __u)
4930b57cec5SDimitry Andric                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
4940b57cec5SDimitry Andric                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
4950b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
4960b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>()...
4970b57cec5SDimitry Andric            {}
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric    template <class _Alloc, size_t ..._Uf, class ..._Tf,
5000b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
501*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5020b57cec5SDimitry Andric        explicit
5030b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a,
5040b57cec5SDimitry Andric                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
5050b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
5060b57cec5SDimitry Andric                     _Up&&... __u) :
5070b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
5080b57cec5SDimitry Andric            _VSTD::forward<_Up>(__u))...,
5090b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
5100b57cec5SDimitry Andric            {}
5110b57cec5SDimitry Andric
5120b57cec5SDimitry Andric    template <class _Tuple,
513753f127fSDimitry Andric              class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
5140b57cec5SDimitry Andric             >
515*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5160b57cec5SDimitry Andric        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
5170b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
5180b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
5190b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
5200b57cec5SDimitry Andric            {}
5210b57cec5SDimitry Andric
5220b57cec5SDimitry Andric    template <class _Alloc, class _Tuple,
523753f127fSDimitry Andric              class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
5240b57cec5SDimitry Andric             >
525*bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5260b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
5270b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
5280b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
5290b57cec5SDimitry Andric                                       _VSTD::forward<typename tuple_element<_Indx,
5300b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
5310b57cec5SDimitry Andric            {}
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric    __tuple_impl(const __tuple_impl&) = default;
5340b57cec5SDimitry Andric    __tuple_impl(__tuple_impl&&) = default;
5350b57cec5SDimitry Andric
536*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5370b57cec5SDimitry Andric    void swap(__tuple_impl& __t)
5380b57cec5SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
5390b57cec5SDimitry Andric    {
540fe6060f1SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
5410b57cec5SDimitry Andric    }
54281ad6265SDimitry Andric
543*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
54481ad6265SDimitry Andric    void swap(const __tuple_impl& __t) const
54581ad6265SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value)
54681ad6265SDimitry Andric    {
54781ad6265SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...);
54881ad6265SDimitry Andric    }
5490b57cec5SDimitry Andric};
5500b57cec5SDimitry Andric
551fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, size_t ..._Np>
552*bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
553fe6060f1SDimitry Andricvoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
554fe6060f1SDimitry Andric    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
555fe6060f1SDimitry Andric}
5560b57cec5SDimitry Andric
557fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
558*bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
559fe6060f1SDimitry Andricvoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
560fe6060f1SDimitry Andric    _VSTD::__swallow(((
561fe6060f1SDimitry Andric        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
562fe6060f1SDimitry Andric    ), void(), 0)...);
563fe6060f1SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andrictemplate <class ..._Tp>
5660b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple
5670b57cec5SDimitry Andric{
5680b57cec5SDimitry Andric    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andric    _BaseT __base_;
5710b57cec5SDimitry Andric
572*bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5730b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
574*bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5750b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
576*bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5770b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
578*bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5790b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
5800b57cec5SDimitry Andricpublic:
581fe6060f1SDimitry Andric    // [tuple.cnstr]
5820b57cec5SDimitry Andric
583fe6060f1SDimitry Andric    // tuple() constructors (including allocator_arg_t variants)
584349cc55cSDimitry Andric    template <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>
589e40139ffSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
590e40139ffSDimitry Andric    tuple()
591fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
592fe6060f1SDimitry Andric    { }
593e40139ffSDimitry Andric
594fe6060f1SDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
595349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
596fe6060f1SDimitry Andric        _And<
597fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
598fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
599fe6060f1SDimitry Andric        >::value
600fe6060f1SDimitry Andric    , int> = 0>
601fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
602fe6060f1SDimitry Andric    explicit tuple()
603fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
604fe6060f1SDimitry Andric    { }
6050b57cec5SDimitry Andric
606349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
607fe6060f1SDimitry Andric        _And<
608fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
609fe6060f1SDimitry Andric        >::value
610fe6060f1SDimitry Andric    , int> = 0>
611*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
612fe6060f1SDimitry Andric    tuple(allocator_arg_t, _Alloc const& __a)
613fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
614fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
615fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
616fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
617fe6060f1SDimitry Andric
618fe6060f1SDimitry Andric    template <class _Alloc,
619fe6060f1SDimitry Andric              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
620349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
621fe6060f1SDimitry Andric        _And<
622fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
623fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
624fe6060f1SDimitry Andric        >::value
625fe6060f1SDimitry Andric    , int> = 0>
626*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
627fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, _Alloc const& __a)
628fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
629fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
630fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
631fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
632fe6060f1SDimitry Andric
633fe6060f1SDimitry Andric    // tuple(const T&...) constructors (including allocator_arg_t variants)
634349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
635fe6060f1SDimitry Andric        _And<
636fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
637fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
638fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
639fe6060f1SDimitry Andric        >::value
640fe6060f1SDimitry Andric    , int> = 0>
641*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
642fe6060f1SDimitry Andric    tuple(const _Tp& ... __t)
643fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
644fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
645fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
646fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
647fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
648fe6060f1SDimitry Andric                __t...
649fe6060f1SDimitry Andric               ) {}
650fe6060f1SDimitry Andric
651349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
652fe6060f1SDimitry Andric        _And<
653fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
654fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
655fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
656fe6060f1SDimitry Andric        >::value
657fe6060f1SDimitry Andric    , int> = 0>
658*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
659fe6060f1SDimitry Andric    explicit tuple(const _Tp& ... __t)
660fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
661fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
662fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
663fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
664fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
665fe6060f1SDimitry Andric                __t...
666fe6060f1SDimitry Andric               ) {}
667fe6060f1SDimitry Andric
668349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
669fe6060f1SDimitry Andric        _And<
670fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
671fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
672fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
673fe6060f1SDimitry Andric        >::value
674fe6060f1SDimitry Andric    , int> = 0>
675*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
676fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
677fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
678fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
679fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
680fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
681fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
682fe6060f1SDimitry Andric                __t...
683fe6060f1SDimitry Andric               ) {}
684fe6060f1SDimitry Andric
685349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
686fe6060f1SDimitry Andric        _And<
687fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
688fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
689fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
690fe6060f1SDimitry Andric        >::value
691fe6060f1SDimitry Andric    , int> = 0>
692*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
693fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
694fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
695fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
696fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
697fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
698fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
699fe6060f1SDimitry Andric                __t...
700fe6060f1SDimitry Andric               ) {}
701fe6060f1SDimitry Andric
702fe6060f1SDimitry Andric    // tuple(U&& ...) constructors (including allocator_arg_t variants)
703fe6060f1SDimitry Andric    template <class ..._Up> struct _IsThisTuple : false_type { };
704*bdd1243dSDimitry Andric    template <class _Up> struct _IsThisTuple<_Up> : is_same<__remove_cvref_t<_Up>, tuple> { };
705fe6060f1SDimitry Andric
706fe6060f1SDimitry Andric    template <class ..._Up>
707fe6060f1SDimitry Andric    struct _EnableUTypesCtor : _And<
708fe6060f1SDimitry Andric        _BoolConstant<sizeof...(_Tp) >= 1>,
709fe6060f1SDimitry Andric        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
710fe6060f1SDimitry Andric        is_constructible<_Tp, _Up>...
711fe6060f1SDimitry Andric    > { };
712fe6060f1SDimitry Andric
713349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
714fe6060f1SDimitry Andric        _And<
715fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
716fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
717fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
718fe6060f1SDimitry Andric        >::value
719fe6060f1SDimitry Andric    , int> = 0>
720*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
721fe6060f1SDimitry Andric    tuple(_Up&&... __u)
722fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
723fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
724fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
725fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
726fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
727fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
728fe6060f1SDimitry Andric
729349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
730fe6060f1SDimitry Andric        _And<
731fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
732fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
733fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
734fe6060f1SDimitry Andric        >::value
735fe6060f1SDimitry Andric    , int> = 0>
736*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
737fe6060f1SDimitry Andric    explicit tuple(_Up&&... __u)
738fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
739fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
740fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
741fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
742fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
743fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
744fe6060f1SDimitry Andric
745349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
746fe6060f1SDimitry Andric        _And<
747fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
748fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
749fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
750fe6060f1SDimitry Andric        >::value
751fe6060f1SDimitry Andric    , int> = 0>
752*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
753fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
754fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
755fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
756fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
757fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
758fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
759fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
760fe6060f1SDimitry Andric
761349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
762fe6060f1SDimitry Andric        _And<
763fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
764fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
765fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
766fe6060f1SDimitry Andric        >::value
767fe6060f1SDimitry Andric    , int> = 0>
768*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
769fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
770fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
771fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
772fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
773fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
774fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
775fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
776fe6060f1SDimitry Andric
777fe6060f1SDimitry Andric    // Copy and move constructors (including the allocator_arg_t variants)
778fe6060f1SDimitry Andric    tuple(const tuple&) = default;
7790b57cec5SDimitry Andric    tuple(tuple&&) = default;
7800b57cec5SDimitry Andric
781349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
782fe6060f1SDimitry Andric        _And<is_copy_constructible<_Tp>...>::value
783fe6060f1SDimitry Andric    , int> = 0>
784*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
785fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
786fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, __t)
787fe6060f1SDimitry Andric    { }
7880b57cec5SDimitry Andric
789349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
790fe6060f1SDimitry Andric        _And<is_move_constructible<_Tp>...>::value
791fe6060f1SDimitry Andric    , int> = 0>
792*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
793fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
794fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
795fe6060f1SDimitry Andric    { }
796e40139ffSDimitry Andric
797fe6060f1SDimitry Andric    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
79881ad6265SDimitry Andric
799*bdd1243dSDimitry Andric    template <class _OtherTuple, class _DecayedOtherTuple = __remove_cvref_t<_OtherTuple>, class = void>
80081ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple : false_type {};
80181ad6265SDimitry Andric
80281ad6265SDimitry Andric    template <class _OtherTuple, class... _Up>
80381ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>,
80481ad6265SDimitry Andric              // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below
80581ad6265SDimitry Andric               __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And<
80681ad6265SDimitry Andric        // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work.
80781ad6265SDimitry Andric        // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE
80881ad6265SDimitry Andric        _Not<is_same<_OtherTuple, const tuple&> >,
80981ad6265SDimitry Andric        _Not<is_same<_OtherTuple, tuple&&> >,
81081ad6265SDimitry Andric        is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
81181ad6265SDimitry Andric        _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>,
812fe6060f1SDimitry Andric            // _Tp and _Up are 1-element packs - the pack expansions look
813fe6060f1SDimitry Andric            // weird to avoid tripping up the type traits in degenerate cases
814fe6060f1SDimitry Andric            _Lazy<_And,
81581ad6265SDimitry Andric                _Not<is_same<_Tp, _Up> >...,
81681ad6265SDimitry Andric                _Not<is_convertible<_OtherTuple, _Tp> >...,
81781ad6265SDimitry Andric                _Not<is_constructible<_Tp, _OtherTuple> >...
8180b57cec5SDimitry Andric            >
81981ad6265SDimitry Andric        >
820fe6060f1SDimitry Andric    > {};
8210b57cec5SDimitry Andric
822349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
823fe6060f1SDimitry Andric        _And<
82481ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
825fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
8260b57cec5SDimitry Andric        >::value
827fe6060f1SDimitry Andric    , int> = 0>
828*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
829fe6060f1SDimitry Andric    tuple(const tuple<_Up...>& __t)
830fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
831fe6060f1SDimitry Andric        : __base_(__t)
832fe6060f1SDimitry Andric    { }
833fe6060f1SDimitry Andric
834349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
835fe6060f1SDimitry Andric        _And<
83681ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
837fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
8380b57cec5SDimitry Andric        >::value
839fe6060f1SDimitry Andric    , int> = 0>
840*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
841fe6060f1SDimitry Andric    explicit tuple(const tuple<_Up...>& __t)
842fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
843fe6060f1SDimitry Andric        : __base_(__t)
844fe6060f1SDimitry Andric    { }
8450b57cec5SDimitry Andric
846349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
847fe6060f1SDimitry Andric        _And<
84881ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
849fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
850fe6060f1SDimitry Andric        >::value
851fe6060f1SDimitry Andric    , int> = 0>
852*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
853fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
854fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
855fe6060f1SDimitry Andric    { }
8560b57cec5SDimitry Andric
857349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
858fe6060f1SDimitry Andric        _And<
85981ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
860fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
861fe6060f1SDimitry Andric        >::value
862fe6060f1SDimitry Andric    , int> = 0>
863*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
864fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
865fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
866fe6060f1SDimitry Andric    { }
8670b57cec5SDimitry Andric
86881ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
86981ad6265SDimitry Andric    // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
87081ad6265SDimitry Andric
87181ad6265SDimitry Andric    template <class... _Up, enable_if_t<
87281ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
87381ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
87481ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
87581ad6265SDimitry Andric    tuple(tuple<_Up...>& __t) : __base_(__t) {}
87681ad6265SDimitry Andric
87781ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
87881ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
87981ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
88081ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
88181ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
88281ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
88381ad6265SDimitry Andric
884fe6060f1SDimitry Andric    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
8850b57cec5SDimitry Andric
886349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
887fe6060f1SDimitry Andric        _And<
88881ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
889fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
890fe6060f1SDimitry Andric        >::value
891fe6060f1SDimitry Andric    , int> = 0>
892*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
893fe6060f1SDimitry Andric    tuple(tuple<_Up...>&& __t)
894fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
895fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
896fe6060f1SDimitry Andric    { }
8970b57cec5SDimitry Andric
898349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
899fe6060f1SDimitry Andric        _And<
90081ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
901fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
902fe6060f1SDimitry Andric        >::value
903fe6060f1SDimitry Andric    , int> = 0>
904*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
905fe6060f1SDimitry Andric    explicit tuple(tuple<_Up...>&& __t)
906fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
907fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
908fe6060f1SDimitry Andric    { }
9090b57cec5SDimitry Andric
910349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
911fe6060f1SDimitry Andric        _And<
91281ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
913fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
914fe6060f1SDimitry Andric        >::value
915fe6060f1SDimitry Andric    , int> = 0>
916*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
917fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
918fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
919fe6060f1SDimitry Andric    { }
920fe6060f1SDimitry Andric
921349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
922fe6060f1SDimitry Andric        _And<
92381ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
924fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
925fe6060f1SDimitry Andric        >::value
926fe6060f1SDimitry Andric    , int> = 0>
927*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
928fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
929fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
930fe6060f1SDimitry Andric    { }
931fe6060f1SDimitry Andric
93281ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
93381ad6265SDimitry Andric    // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
93481ad6265SDimitry Andric
93581ad6265SDimitry Andric    template <class... _Up, enable_if_t<
93681ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
93781ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
93881ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
93981ad6265SDimitry Andric    tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {}
94081ad6265SDimitry Andric
94181ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
94281ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
94381ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
94481ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
94581ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
94681ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
94781ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
94881ad6265SDimitry Andric
949fe6060f1SDimitry Andric    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
95081ad6265SDimitry Andric
951*bdd1243dSDimitry Andric    template <template <class...> class Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
95281ad6265SDimitry Andric    struct _CtorPredicateFromPair : false_type{};
95381ad6265SDimitry Andric
95481ad6265SDimitry Andric    template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
95581ad6265SDimitry Andric    struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
95681ad6265SDimitry Andric        Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
95781ad6265SDimitry Andric        Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
958fe6060f1SDimitry Andric    > {};
959fe6060f1SDimitry Andric
96081ad6265SDimitry Andric    template <class _Pair>
96181ad6265SDimitry Andric    struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{};
96281ad6265SDimitry Andric
96381ad6265SDimitry Andric    template <class _Pair>
96481ad6265SDimitry Andric    struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{};
96581ad6265SDimitry Andric
966*bdd1243dSDimitry Andric    template <class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
96781ad6265SDimitry Andric    struct _BothImplicitlyConvertible : false_type{};
96881ad6265SDimitry Andric
96981ad6265SDimitry Andric    template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
97081ad6265SDimitry Andric    struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
97181ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>,
97281ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2>
973fe6060f1SDimitry Andric    > {};
974fe6060f1SDimitry Andric
975349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
976fe6060f1SDimitry Andric        _And<
97781ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
97881ad6265SDimitry Andric            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
979fe6060f1SDimitry Andric        >::value
980fe6060f1SDimitry Andric    , int> = 0>
981*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
982fe6060f1SDimitry Andric    tuple(const pair<_Up1, _Up2>& __p)
98381ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
984fe6060f1SDimitry Andric        : __base_(__p)
985fe6060f1SDimitry Andric    { }
986fe6060f1SDimitry Andric
987349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
988fe6060f1SDimitry Andric        _And<
98981ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
99081ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
991fe6060f1SDimitry Andric        >::value
992fe6060f1SDimitry Andric    , int> = 0>
993*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
994fe6060f1SDimitry Andric    explicit tuple(const pair<_Up1, _Up2>& __p)
99581ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
996fe6060f1SDimitry Andric        : __base_(__p)
997fe6060f1SDimitry Andric    { }
998fe6060f1SDimitry Andric
999349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1000fe6060f1SDimitry Andric        _And<
100181ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
100281ad6265SDimitry Andric            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
1003fe6060f1SDimitry Andric        >::value
1004fe6060f1SDimitry Andric    , int> = 0>
1005*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1006fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
1007fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
1008fe6060f1SDimitry Andric    { }
1009fe6060f1SDimitry Andric
1010349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1011fe6060f1SDimitry Andric        _And<
101281ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
101381ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
1014fe6060f1SDimitry Andric        >::value
1015fe6060f1SDimitry Andric    , int> = 0>
1016*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1017fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
1018fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
1019fe6060f1SDimitry Andric    { }
1020fe6060f1SDimitry Andric
102181ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
102281ad6265SDimitry Andric    // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
1023fe6060f1SDimitry Andric
102481ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
102581ad6265SDimitry Andric        _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
102681ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
102781ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
102881ad6265SDimitry Andric    tuple(pair<_U1, _U2>& __p) : __base_(__p) {}
102981ad6265SDimitry Andric
103081ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
103181ad6265SDimitry Andric        _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
103281ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
103381ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
103481ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {}
103581ad6265SDimitry Andric#endif
103681ad6265SDimitry Andric
103781ad6265SDimitry Andric    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
1038fe6060f1SDimitry Andric
1039349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1040fe6060f1SDimitry Andric        _And<
104181ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
104281ad6265SDimitry Andric            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1043fe6060f1SDimitry Andric        >::value
1044fe6060f1SDimitry Andric    , int> = 0>
1045*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
1046fe6060f1SDimitry Andric    tuple(pair<_Up1, _Up2>&& __p)
104781ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
1048fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
1049fe6060f1SDimitry Andric    { }
1050fe6060f1SDimitry Andric
1051349cc55cSDimitry Andric    template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1052fe6060f1SDimitry Andric        _And<
105381ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
105481ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1055fe6060f1SDimitry Andric        >::value
1056fe6060f1SDimitry Andric    , int> = 0>
1057*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
1058fe6060f1SDimitry Andric    explicit tuple(pair<_Up1, _Up2>&& __p)
105981ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
1060fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
1061fe6060f1SDimitry Andric    { }
1062fe6060f1SDimitry Andric
1063349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1064fe6060f1SDimitry Andric        _And<
106581ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
106681ad6265SDimitry Andric            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1067fe6060f1SDimitry Andric        >::value
1068fe6060f1SDimitry Andric    , int> = 0>
1069*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1070fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1071fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1072fe6060f1SDimitry Andric    { }
1073fe6060f1SDimitry Andric
1074349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1075fe6060f1SDimitry Andric        _And<
107681ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
107781ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1078fe6060f1SDimitry Andric        >::value
1079fe6060f1SDimitry Andric    , int> = 0>
1080*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1081fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1082fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1083fe6060f1SDimitry Andric    { }
1084fe6060f1SDimitry Andric
108581ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
108681ad6265SDimitry Andric    // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
108781ad6265SDimitry Andric
108881ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
108981ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
109081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
109181ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
109281ad6265SDimitry Andric    tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {}
109381ad6265SDimitry Andric
109481ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
109581ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
109681ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
109781ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
109881ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
109981ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
110081ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
110181ad6265SDimitry Andric
1102fe6060f1SDimitry Andric    // [tuple.assign]
1103*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1104fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
1105fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
11060b57cec5SDimitry Andric    {
1107fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1108fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11090b57cec5SDimitry Andric        return *this;
11100b57cec5SDimitry Andric    }
11110b57cec5SDimitry Andric
111281ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
111381ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
111481ad6265SDimitry Andric    const tuple& operator=(tuple const& __tuple) const
111581ad6265SDimitry Andric      requires (_And<is_copy_assignable<const _Tp>...>::value) {
111681ad6265SDimitry Andric        std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
111781ad6265SDimitry Andric        return *this;
111881ad6265SDimitry Andric    }
111981ad6265SDimitry Andric
112081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
112181ad6265SDimitry Andric    const tuple& operator=(tuple&& __tuple) const
112281ad6265SDimitry Andric      requires (_And<is_assignable<const _Tp&, _Tp>...>::value) {
112381ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
112481ad6265SDimitry Andric                                         std::move(__tuple),
112581ad6265SDimitry Andric                                         __tuple_types<_Tp...>(),
112681ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
112781ad6265SDimitry Andric        return *this;
112881ad6265SDimitry Andric    }
112981ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
113081ad6265SDimitry Andric
1131*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1132fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
1133fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
11340b57cec5SDimitry Andric    {
1135fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1136fe6060f1SDimitry Andric            __tuple_types<_Tp...>(),
1137fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11380b57cec5SDimitry Andric        return *this;
11390b57cec5SDimitry Andric    }
11400b57cec5SDimitry Andric
1141349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1142fe6060f1SDimitry Andric        _And<
1143fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1144fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1145fe6060f1SDimitry Andric        >::value
1146fe6060f1SDimitry Andric    ,int> = 0>
1147*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1148fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...> const& __tuple)
1149fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
11500b57cec5SDimitry Andric    {
1151fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1152fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11530b57cec5SDimitry Andric        return *this;
11540b57cec5SDimitry Andric    }
11550b57cec5SDimitry Andric
1156349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1157fe6060f1SDimitry Andric        _And<
1158fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1159fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1160fe6060f1SDimitry Andric        >::value
1161fe6060f1SDimitry Andric    ,int> = 0>
1162*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1163fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...>&& __tuple)
1164fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1165fe6060f1SDimitry Andric    {
1166fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1167fe6060f1SDimitry Andric            __tuple_types<_Up...>(),
1168fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1169fe6060f1SDimitry Andric        return *this;
1170fe6060f1SDimitry Andric    }
1171fe6060f1SDimitry Andric
117281ad6265SDimitry Andric
117381ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
117481ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
117581ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
117681ad6265SDimitry Andric             is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
117781ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
117881ad6265SDimitry Andric    const tuple& operator=(const tuple<_UTypes...>& __u) const {
117981ad6265SDimitry Andric        std::__memberwise_copy_assign(*this,
118081ad6265SDimitry Andric                                      __u,
118181ad6265SDimitry Andric                                      typename __make_tuple_indices<sizeof...(_Tp)>::type());
118281ad6265SDimitry Andric        return *this;
118381ad6265SDimitry Andric    }
118481ad6265SDimitry Andric
118581ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
118681ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
118781ad6265SDimitry Andric             is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
118881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
118981ad6265SDimitry Andric    const tuple& operator=(tuple<_UTypes...>&& __u) const {
119081ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
119181ad6265SDimitry Andric                                         __u,
119281ad6265SDimitry Andric                                         __tuple_types<_UTypes...>(),
119381ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
119481ad6265SDimitry Andric        return *this;
119581ad6265SDimitry Andric    }
119681ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
119781ad6265SDimitry Andric
119881ad6265SDimitry Andric    template <template<class...> class Pred, bool _Const,
1199*bdd1243dSDimitry Andric              class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
120081ad6265SDimitry Andric    struct _AssignPredicateFromPair : false_type {};
120181ad6265SDimitry Andric
120281ad6265SDimitry Andric    template <template<class...> class Pred, bool _Const,
120381ad6265SDimitry Andric              class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
120481ad6265SDimitry Andric    struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
120581ad6265SDimitry Andric        _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
120681ad6265SDimitry Andric             Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
120781ad6265SDimitry Andric            > {};
120881ad6265SDimitry Andric
120981ad6265SDimitry Andric    template <bool _Const, class _Pair>
121081ad6265SDimitry Andric    struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {};
121181ad6265SDimitry Andric
121281ad6265SDimitry Andric    template <bool _Const, class _Pair>
121381ad6265SDimitry Andric    struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
121481ad6265SDimitry Andric
121581ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
121681ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
121781ad6265SDimitry Andric        _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
121881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
121981ad6265SDimitry Andric    const tuple& operator=(const pair<_U1, _U2>& __pair) const
122081ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) {
122181ad6265SDimitry Andric        std::get<0>(*this) = __pair.first;
122281ad6265SDimitry Andric        std::get<1>(*this) = __pair.second;
122381ad6265SDimitry Andric        return *this;
122481ad6265SDimitry Andric    }
122581ad6265SDimitry Andric
122681ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
122781ad6265SDimitry Andric        _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr>
122881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
122981ad6265SDimitry Andric    const tuple& operator=(pair<_U1, _U2>&& __pair) const
123081ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) {
123181ad6265SDimitry Andric        std::get<0>(*this) = std::move(__pair.first);
123281ad6265SDimitry Andric        std::get<1>(*this) = std::move(__pair.second);
123381ad6265SDimitry Andric        return *this;
123481ad6265SDimitry Andric    }
123581ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
123681ad6265SDimitry Andric
123781ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
123881ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
1239fe6060f1SDimitry Andric    ,int> = 0>
1240*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1241fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2> const& __pair)
124281ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value))
1243fe6060f1SDimitry Andric    {
1244fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = __pair.first;
1245fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = __pair.second;
1246fe6060f1SDimitry Andric        return *this;
1247fe6060f1SDimitry Andric    }
1248fe6060f1SDimitry Andric
124981ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
125081ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value
1251fe6060f1SDimitry Andric    ,int> = 0>
1252*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1253fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2>&& __pair)
125481ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value))
1255fe6060f1SDimitry Andric    {
1256fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1257fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1258fe6060f1SDimitry Andric        return *this;
1259fe6060f1SDimitry Andric    }
1260fe6060f1SDimitry Andric
1261fe6060f1SDimitry Andric    // EXTENSION
1262349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = __enable_if_t<
1263fe6060f1SDimitry Andric        _And<
1264fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1265fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1266fe6060f1SDimitry Andric        >::value
1267fe6060f1SDimitry Andric    > >
1268*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1269fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np> const& __array)
1270fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1271fe6060f1SDimitry Andric    {
1272fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __array,
1273fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1274fe6060f1SDimitry Andric        return *this;
1275fe6060f1SDimitry Andric    }
1276fe6060f1SDimitry Andric
1277fe6060f1SDimitry Andric    // EXTENSION
1278349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1279fe6060f1SDimitry Andric        _And<
1280fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1281fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1282fe6060f1SDimitry Andric        >::value
1283fe6060f1SDimitry Andric    > >
1284*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1285fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np>&& __array)
1286fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1287fe6060f1SDimitry Andric    {
1288fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1289fe6060f1SDimitry Andric            __tuple_types<_If<true, _Up, _Tp>...>(),
1290fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1291fe6060f1SDimitry Andric        return *this;
1292fe6060f1SDimitry Andric    }
1293fe6060f1SDimitry Andric
1294fe6060f1SDimitry Andric    // [tuple.swap]
1295*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
12960b57cec5SDimitry Andric    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
12970b57cec5SDimitry Andric        {__base_.swap(__t.__base_);}
129881ad6265SDimitry Andric
129981ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
130081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
130181ad6265SDimitry Andric    void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
130281ad6265SDimitry Andric        __base_.swap(__t.__base_);
130381ad6265SDimitry Andric    }
130481ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
13050b57cec5SDimitry Andric};
13060b57cec5SDimitry Andric
13070b57cec5SDimitry Andrictemplate <>
13080b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<>
13090b57cec5SDimitry Andric{
13100b57cec5SDimitry Andricpublic:
1311fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr
1312fe6060f1SDimitry Andric        tuple() _NOEXCEPT = default;
13130b57cec5SDimitry Andric    template <class _Alloc>
1314*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13150b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
13160b57cec5SDimitry Andric    template <class _Alloc>
1317*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13180b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
13190b57cec5SDimitry Andric    template <class _Up>
1320*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13210b57cec5SDimitry Andric        tuple(array<_Up, 0>) _NOEXCEPT {}
13220b57cec5SDimitry Andric    template <class _Alloc, class _Up>
1323*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13240b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1325*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13260b57cec5SDimitry Andric    void swap(tuple&) _NOEXCEPT {}
132781ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
132881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
132981ad6265SDimitry Andric#endif
13300b57cec5SDimitry Andric};
13310b57cec5SDimitry Andric
133204eeddc0SDimitry Andric#if _LIBCPP_STD_VER > 20
133304eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
133404eeddc0SDimitry Andric    requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
133504eeddc0SDimitry Andricstruct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
133604eeddc0SDimitry Andric    using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
133704eeddc0SDimitry Andric};
133804eeddc0SDimitry Andric
133904eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes>
134004eeddc0SDimitry Andric    requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
134104eeddc0SDimitry Andricstruct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
134204eeddc0SDimitry Andric    using type = tuple<common_type_t<_TTypes, _UTypes>...>;
134304eeddc0SDimitry Andric};
134481ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 20
134504eeddc0SDimitry Andric
134604eeddc0SDimitry Andric#if _LIBCPP_STD_VER > 14
1347e40139ffSDimitry Andrictemplate <class ..._Tp>
1348e40139ffSDimitry Andrictuple(_Tp...) -> tuple<_Tp...>;
1349e40139ffSDimitry Andrictemplate <class _Tp1, class _Tp2>
1350e40139ffSDimitry Andrictuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1351e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1352e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1353e40139ffSDimitry Andrictemplate <class _Alloc, class _Tp1, class _Tp2>
1354e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1355e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1356e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
13570b57cec5SDimitry Andric#endif
13580b57cec5SDimitry Andric
13590b57cec5SDimitry Andrictemplate <class ..._Tp>
1360*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1361753f127fSDimitry Andric__enable_if_t<__all<__is_swappable<_Tp>::value...>::value, void>
13620b57cec5SDimitry Andricswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
13630b57cec5SDimitry Andric                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
13640b57cec5SDimitry Andric    {__t.swap(__u);}
13650b57cec5SDimitry Andric
136681ad6265SDimitry Andric#if _LIBCPP_STD_VER > 20
136781ad6265SDimitry Andrictemplate <class... _Tp>
136881ad6265SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
136981ad6265SDimitry Andricenable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
137081ad6265SDimitry Andricswap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs)
137181ad6265SDimitry Andric        noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) {
137281ad6265SDimitry Andric    __lhs.swap(__rhs);
137381ad6265SDimitry Andric}
137481ad6265SDimitry Andric#endif
137581ad6265SDimitry Andric
13760b57cec5SDimitry Andric// get
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1379*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
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<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
13850b57cec5SDimitry Andric}
13860b57cec5SDimitry Andric
13870b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1388*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
13890b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
13900b57cec5SDimitry Andricget(const tuple<_Tp...>& __t) _NOEXCEPT
13910b57cec5SDimitry Andric{
1392349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13930b57cec5SDimitry Andric    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
13940b57cec5SDimitry Andric}
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1397*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
13980b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&&
13990b57cec5SDimitry Andricget(tuple<_Tp...>&& __t) _NOEXCEPT
14000b57cec5SDimitry Andric{
1401349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
14020b57cec5SDimitry Andric    return static_cast<type&&>(
14030b57cec5SDimitry Andric             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
14040b57cec5SDimitry Andric}
14050b57cec5SDimitry Andric
14060b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1407*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
14080b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
14090b57cec5SDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT
14100b57cec5SDimitry Andric{
1411349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
14120b57cec5SDimitry Andric    return static_cast<const type&&>(
14130b57cec5SDimitry Andric             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
14140b57cec5SDimitry Andric}
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
14170b57cec5SDimitry Andric
14180b57cec5SDimitry Andricnamespace __find_detail {
14190b57cec5SDimitry Andric
1420fe6060f1SDimitry Andricstatic constexpr size_t __not_found = static_cast<size_t>(-1);
14210b57cec5SDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1;
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14240b57cec5SDimitry Andricconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
14250b57cec5SDimitry Andric    return !__matches ? __res :
14260b57cec5SDimitry Andric        (__res == __not_found ? __curr_i : __ambiguous);
14270b57cec5SDimitry Andric}
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andrictemplate <size_t _Nx>
14300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14310b57cec5SDimitry Andricconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
14320b57cec5SDimitry Andric  return __i == _Nx ? __not_found :
1433*bdd1243dSDimitry Andric      __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
14340b57cec5SDimitry Andric}
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andrictemplate <class _T1, class ..._Args>
14370b57cec5SDimitry Andricstruct __find_exactly_one_checked {
14380b57cec5SDimitry Andric    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
14390b57cec5SDimitry Andric    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
14400b57cec5SDimitry Andric    static_assert(value != __not_found, "type not found in type list" );
14410b57cec5SDimitry Andric    static_assert(value != __ambiguous, "type occurs more than once in type list");
14420b57cec5SDimitry Andric};
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andrictemplate <class _T1>
14450b57cec5SDimitry Andricstruct __find_exactly_one_checked<_T1> {
14460b57cec5SDimitry Andric    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
14470b57cec5SDimitry Andric};
14480b57cec5SDimitry Andric
14490eae32dcSDimitry Andric} // namespace __find_detail
14500b57cec5SDimitry Andric
14510b57cec5SDimitry Andrictemplate <typename _T1, typename... _Args>
14520b57cec5SDimitry Andricstruct __find_exactly_one_t
14530b57cec5SDimitry Andric    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
14540b57cec5SDimitry Andric};
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14580b57cec5SDimitry Andricconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
14590b57cec5SDimitry Andric{
14600b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14610b57cec5SDimitry Andric}
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14650b57cec5SDimitry Andricconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
14660b57cec5SDimitry Andric{
14670b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14680b57cec5SDimitry Andric}
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14720b57cec5SDimitry Andricconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
14730b57cec5SDimitry Andric{
14740b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14750b57cec5SDimitry Andric}
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14790b57cec5SDimitry Andricconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
14800b57cec5SDimitry Andric{
14810b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14820b57cec5SDimitry Andric}
14830b57cec5SDimitry Andric
14840b57cec5SDimitry Andric#endif
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric// tie
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andrictemplate <class ..._Tp>
1489*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
14900b57cec5SDimitry Andrictuple<_Tp&...>
14910b57cec5SDimitry Andrictie(_Tp&... __t) _NOEXCEPT
14920b57cec5SDimitry Andric{
14930b57cec5SDimitry Andric    return tuple<_Tp&...>(__t...);
14940b57cec5SDimitry Andric}
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andrictemplate <class _Up>
14970b57cec5SDimitry Andricstruct __ignore_t
14980b57cec5SDimitry Andric{
14990b57cec5SDimitry Andric    template <class _Tp>
1500*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15010b57cec5SDimitry Andric    const __ignore_t& operator=(_Tp&&) const {return *this;}
15020b57cec5SDimitry Andric};
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andricnamespace {
1505349cc55cSDimitry Andric  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
15060eae32dcSDimitry Andric} // namespace
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andrictemplate <class... _Tp>
1509*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15100b57cec5SDimitry Andrictuple<typename __unwrap_ref_decay<_Tp>::type...>
15110b57cec5SDimitry Andricmake_tuple(_Tp&&... __t)
15120b57cec5SDimitry Andric{
15130b57cec5SDimitry Andric    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
15140b57cec5SDimitry Andric}
15150b57cec5SDimitry Andric
15160b57cec5SDimitry Andrictemplate <class... _Tp>
1517*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15180b57cec5SDimitry Andrictuple<_Tp&&...>
15190b57cec5SDimitry Andricforward_as_tuple(_Tp&&... __t) _NOEXCEPT
15200b57cec5SDimitry Andric{
15210b57cec5SDimitry Andric    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
15220b57cec5SDimitry Andric}
15230b57cec5SDimitry Andric
15240b57cec5SDimitry Andrictemplate <size_t _Ip>
15250b57cec5SDimitry Andricstruct __tuple_equal
15260b57cec5SDimitry Andric{
15270b57cec5SDimitry Andric    template <class _Tp, class _Up>
1528*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15290b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
15300b57cec5SDimitry Andric    {
15310b57cec5SDimitry Andric        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
15320b57cec5SDimitry Andric    }
15330b57cec5SDimitry Andric};
15340b57cec5SDimitry Andric
15350b57cec5SDimitry Andrictemplate <>
15360b57cec5SDimitry Andricstruct __tuple_equal<0>
15370b57cec5SDimitry Andric{
15380b57cec5SDimitry Andric    template <class _Tp, class _Up>
1539*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15400b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
15410b57cec5SDimitry Andric    {
15420b57cec5SDimitry Andric        return true;
15430b57cec5SDimitry Andric    }
15440b57cec5SDimitry Andric};
15450b57cec5SDimitry Andric
15460b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1547*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15480b57cec5SDimitry Andricbool
15490b57cec5SDimitry Andricoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15500b57cec5SDimitry Andric{
15510b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
15520b57cec5SDimitry Andric    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
15530b57cec5SDimitry Andric}
15540b57cec5SDimitry Andric
155581ad6265SDimitry Andric#if _LIBCPP_STD_VER > 17
1556349cc55cSDimitry Andric
1557349cc55cSDimitry Andric// operator<=>
1558349cc55cSDimitry Andric
1559349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1560349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1561349cc55cSDimitry Andricauto
1562349cc55cSDimitry Andric__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1563349cc55cSDimitry Andric    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1564349cc55cSDimitry Andric    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1565349cc55cSDimitry Andric    return __result;
1566349cc55cSDimitry Andric}
1567349cc55cSDimitry Andric
1568349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up>
1569349cc55cSDimitry Andricrequires (sizeof...(_Tp) == sizeof...(_Up))
1570349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1571349cc55cSDimitry Andriccommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1572349cc55cSDimitry Andricoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1573349cc55cSDimitry Andric{
1574349cc55cSDimitry Andric    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1575349cc55cSDimitry Andric}
1576349cc55cSDimitry Andric
157781ad6265SDimitry Andric#else // _LIBCPP_STD_VER > 17
1578349cc55cSDimitry Andric
15790b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1580*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15810b57cec5SDimitry Andricbool
15820b57cec5SDimitry Andricoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15830b57cec5SDimitry Andric{
15840b57cec5SDimitry Andric    return !(__x == __y);
15850b57cec5SDimitry Andric}
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andrictemplate <size_t _Ip>
15880b57cec5SDimitry Andricstruct __tuple_less
15890b57cec5SDimitry Andric{
15900b57cec5SDimitry Andric    template <class _Tp, class _Up>
1591*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15920b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
15930b57cec5SDimitry Andric    {
15940b57cec5SDimitry Andric        const size_t __idx = tuple_size<_Tp>::value - _Ip;
15950b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
15960b57cec5SDimitry Andric            return true;
15970b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
15980b57cec5SDimitry Andric            return false;
15990b57cec5SDimitry Andric        return __tuple_less<_Ip-1>()(__x, __y);
16000b57cec5SDimitry Andric    }
16010b57cec5SDimitry Andric};
16020b57cec5SDimitry Andric
16030b57cec5SDimitry Andrictemplate <>
16040b57cec5SDimitry Andricstruct __tuple_less<0>
16050b57cec5SDimitry Andric{
16060b57cec5SDimitry Andric    template <class _Tp, class _Up>
1607*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16080b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
16090b57cec5SDimitry Andric    {
16100b57cec5SDimitry Andric        return false;
16110b57cec5SDimitry Andric    }
16120b57cec5SDimitry Andric};
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1615*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16160b57cec5SDimitry Andricbool
16170b57cec5SDimitry Andricoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16180b57cec5SDimitry Andric{
16190b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
16200b57cec5SDimitry Andric    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
16210b57cec5SDimitry Andric}
16220b57cec5SDimitry Andric
16230b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1624*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16250b57cec5SDimitry Andricbool
16260b57cec5SDimitry Andricoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16270b57cec5SDimitry Andric{
16280b57cec5SDimitry Andric    return __y < __x;
16290b57cec5SDimitry Andric}
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1632*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16330b57cec5SDimitry Andricbool
16340b57cec5SDimitry Andricoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16350b57cec5SDimitry Andric{
16360b57cec5SDimitry Andric    return !(__x < __y);
16370b57cec5SDimitry Andric}
16380b57cec5SDimitry Andric
16390b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1640*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16410b57cec5SDimitry Andricbool
16420b57cec5SDimitry Andricoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16430b57cec5SDimitry Andric{
16440b57cec5SDimitry Andric    return !(__y < __x);
16450b57cec5SDimitry Andric}
16460b57cec5SDimitry Andric
164781ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 17
1648349cc55cSDimitry Andric
16490b57cec5SDimitry Andric// tuple_cat
16500b57cec5SDimitry Andric
16510b57cec5SDimitry Andrictemplate <class _Tp, class _Up> struct __tuple_cat_type;
16520b57cec5SDimitry Andric
16530b57cec5SDimitry Andrictemplate <class ..._Ttypes, class ..._Utypes>
16540b57cec5SDimitry Andricstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
16550b57cec5SDimitry Andric{
1656349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
16570b57cec5SDimitry Andric};
16580b57cec5SDimitry Andric
16590b57cec5SDimitry Andrictemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
16600b57cec5SDimitry Andricstruct __tuple_cat_return_1
16610b57cec5SDimitry Andric{
16620b57cec5SDimitry Andric};
16630b57cec5SDimitry Andric
16640b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0>
16650b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
16660b57cec5SDimitry Andric{
166781ad6265SDimitry Andric  using type _LIBCPP_NODEBUG = typename __tuple_cat_type<
166881ad6265SDimitry Andric      tuple<_Types...>,
1669*bdd1243dSDimitry Andric      typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
167081ad6265SDimitry Andric    >::type;
16710b57cec5SDimitry Andric};
16720b57cec5SDimitry Andric
16730b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
16740b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
16750b57cec5SDimitry Andric    : public __tuple_cat_return_1<
16760b57cec5SDimitry Andric                 typename __tuple_cat_type<
16770b57cec5SDimitry Andric                     tuple<_Types...>,
1678*bdd1243dSDimitry Andric                     typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
16790b57cec5SDimitry Andric                 >::type,
1680*bdd1243dSDimitry Andric                 __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value,
16810b57cec5SDimitry Andric                 _Tuple1, _Tuples...>
16820b57cec5SDimitry Andric{
16830b57cec5SDimitry Andric};
16840b57cec5SDimitry Andric
16850b57cec5SDimitry Andrictemplate <class ..._Tuples> struct __tuple_cat_return;
16860b57cec5SDimitry Andric
16870b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
16880b57cec5SDimitry Andricstruct __tuple_cat_return<_Tuple0, _Tuples...>
16890b57cec5SDimitry Andric    : public __tuple_cat_return_1<tuple<>,
1690*bdd1243dSDimitry Andric         __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value, _Tuple0,
16910b57cec5SDimitry Andric                                                                     _Tuples...>
16920b57cec5SDimitry Andric{
16930b57cec5SDimitry Andric};
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andrictemplate <>
16960b57cec5SDimitry Andricstruct __tuple_cat_return<>
16970b57cec5SDimitry Andric{
1698349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<> type;
16990b57cec5SDimitry Andric};
17000b57cec5SDimitry Andric
1701*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17020b57cec5SDimitry Andrictuple<>
17030b57cec5SDimitry Andrictuple_cat()
17040b57cec5SDimitry Andric{
17050b57cec5SDimitry Andric    return tuple<>();
17060b57cec5SDimitry Andric}
17070b57cec5SDimitry Andric
17080b57cec5SDimitry Andrictemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
17090b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp;
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0>
17120b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
17130b57cec5SDimitry Andric{
1714*bdd1243dSDimitry Andric    typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
17150b57cec5SDimitry Andric    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
17160b57cec5SDimitry Andric                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
17170b57cec5SDimitry Andric};
17180b57cec5SDimitry Andric
17190b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
17200b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
17210b57cec5SDimitry Andric                                  _Tuple0, _Tuple1, _Tuples...>
17220b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<
17230b57cec5SDimitry Andric         tuple<_Types..., typename __apply_cv<_Tuple0,
17240b57cec5SDimitry Andric               typename tuple_element<_I0,
1725*bdd1243dSDimitry Andric                  __libcpp_remove_reference_t<_Tuple0> >::type>::type&&...>,
1726*bdd1243dSDimitry Andric         typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
17270b57cec5SDimitry Andric         _Tuple1, _Tuples...>
17280b57cec5SDimitry Andric{
17290b57cec5SDimitry Andric};
17300b57cec5SDimitry Andric
17310b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
17320b57cec5SDimitry Andricstruct __tuple_cat_return_ref
17330b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<tuple<>,
17340b57cec5SDimitry Andric               typename __make_tuple_indices<
1735*bdd1243dSDimitry Andric                        tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value
17360b57cec5SDimitry Andric               >::type, _Tuple0, _Tuples...>
17370b57cec5SDimitry Andric{
17380b57cec5SDimitry Andric};
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andrictemplate <class _Types, class _I0, class _J0>
17410b57cec5SDimitry Andricstruct __tuple_cat;
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
17440b57cec5SDimitry Andricstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
17450b57cec5SDimitry Andric{
17460b57cec5SDimitry Andric    template <class _Tuple0>
1747*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17480b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
17490b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
17500b57cec5SDimitry Andric    {
175181ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1752480093f4SDimitry Andric        return _VSTD::forward_as_tuple(
1753480093f4SDimitry Andric            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
17540b57cec5SDimitry Andric            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
17550b57cec5SDimitry Andric    }
17560b57cec5SDimitry Andric
17570b57cec5SDimitry Andric    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1758*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17590b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
17600b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
17610b57cec5SDimitry Andric    {
176281ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1763*bdd1243dSDimitry Andric        typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1764*bdd1243dSDimitry Andric        typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1;
17650b57cec5SDimitry Andric        return __tuple_cat<
1766480093f4SDimitry Andric            tuple<_Types...,
1767480093f4SDimitry Andric                  typename __apply_cv<_Tuple0, typename tuple_element<
1768480093f4SDimitry Andric                                                   _J0, _T0>::type>::type&&...>,
1769480093f4SDimitry Andric            typename __make_tuple_indices<sizeof...(_Types) +
1770480093f4SDimitry Andric                                          tuple_size<_T0>::value>::type,
1771480093f4SDimitry Andric            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1772480093f4SDimitry Andric            _VSTD::forward_as_tuple(
17730b57cec5SDimitry Andric                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1774480093f4SDimitry Andric                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1775480093f4SDimitry Andric            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
17760b57cec5SDimitry Andric    }
17770b57cec5SDimitry Andric};
17780b57cec5SDimitry Andric
17790b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples>
1780*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17810b57cec5SDimitry Andrictypename __tuple_cat_return<_Tuple0, _Tuples...>::type
17820b57cec5SDimitry Andrictuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
17830b57cec5SDimitry Andric{
1784*bdd1243dSDimitry Andric    typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
17850b57cec5SDimitry Andric    return __tuple_cat<tuple<>, __tuple_indices<>,
17860b57cec5SDimitry Andric                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
17870b57cec5SDimitry Andric                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
17880b57cec5SDimitry Andric                                            _VSTD::forward<_Tuples>(__tpls)...);
17890b57cec5SDimitry Andric}
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andrictemplate <class ..._Tp, class _Alloc>
17920b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
17930b57cec5SDimitry Andric    : true_type {};
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andrictemplate <class _T1, class _T2>
17960b57cec5SDimitry Andrictemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1797*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
17980b57cec5SDimitry Andricpair<_T1, _T2>::pair(piecewise_construct_t,
17990b57cec5SDimitry Andric                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
18000b57cec5SDimitry Andric                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
18010b57cec5SDimitry Andric    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
18020b57cec5SDimitry Andric      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
18030b57cec5SDimitry Andric{
18040b57cec5SDimitry Andric}
18050b57cec5SDimitry Andric
18060b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
18070b57cec5SDimitry Andrictemplate <class _Tp>
1808349cc55cSDimitry Andricinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
18110b57cec5SDimitry Andric
18120b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple, size_t ..._Id>
18130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18140b57cec5SDimitry Andricconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
18150b57cec5SDimitry Andric                                            __tuple_indices<_Id...>)
18160b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
181781ad6265SDimitry Andric    _VSTD::__invoke(
18180b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f),
18190b57cec5SDimitry Andric        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
18200b57cec5SDimitry Andric)
18210b57cec5SDimitry Andric
18220b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple>
18230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18240b57cec5SDimitry Andricconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
18250b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18260b57cec5SDimitry Andric    _VSTD::__apply_tuple_impl(
18270b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
18280b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18290b57cec5SDimitry Andric)
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx>
18320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18330b57cec5SDimitry Andricconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
18340b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18350b57cec5SDimitry Andric    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
18360b57cec5SDimitry Andric)
18370b57cec5SDimitry Andric
18380b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple>
18390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18400b57cec5SDimitry Andricconstexpr _Tp make_from_tuple(_Tuple&& __t)
18410b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18420b57cec5SDimitry Andric    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
18430b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18440b57cec5SDimitry Andric)
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric#undef _LIBCPP_NOEXCEPT_RETURN
18470b57cec5SDimitry Andric
18480b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
18490b57cec5SDimitry Andric
18500b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
18510b57cec5SDimitry Andric
18520b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
18530b57cec5SDimitry Andric
1854*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1855*bdd1243dSDimitry Andric#  include <exception>
1856*bdd1243dSDimitry Andric#  include <iosfwd>
1857*bdd1243dSDimitry Andric#  include <new>
1858*bdd1243dSDimitry Andric#  include <type_traits>
1859*bdd1243dSDimitry Andric#  include <typeinfo>
1860*bdd1243dSDimitry Andric#  include <utility>
1861*bdd1243dSDimitry Andric#endif
1862*bdd1243dSDimitry Andric
18630b57cec5SDimitry Andric#endif // _LIBCPP_TUPLE
1864