xref: /freebsd/contrib/llvm-project/libcxx/include/tuple (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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>
208bdd1243dSDimitry Andric#include <__functional/invoke.h>
209bdd1243dSDimitry Andric#include <__fwd/array.h>
210*06c3fb27SDimitry Andric#include <__fwd/get.h>
211*06c3fb27SDimitry Andric#include <__fwd/tuple.h>
212fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
213fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
214*06c3fb27SDimitry Andric#include <__tuple/make_tuple_types.h>
215*06c3fb27SDimitry Andric#include <__tuple/sfinae_helpers.h>
216*06c3fb27SDimitry Andric#include <__tuple/tuple_element.h>
217*06c3fb27SDimitry Andric#include <__tuple/tuple_indices.h>
218*06c3fb27SDimitry Andric#include <__tuple/tuple_like_ext.h>
219*06c3fb27SDimitry Andric#include <__tuple/tuple_size.h>
220*06c3fb27SDimitry Andric#include <__tuple/tuple_types.h>
221bdd1243dSDimitry Andric#include <__type_traits/apply_cv.h>
222bdd1243dSDimitry Andric#include <__type_traits/common_reference.h>
223bdd1243dSDimitry Andric#include <__type_traits/common_type.h>
224bdd1243dSDimitry Andric#include <__type_traits/conditional.h>
225bdd1243dSDimitry Andric#include <__type_traits/conjunction.h>
226bdd1243dSDimitry Andric#include <__type_traits/copy_cvref.h>
227bdd1243dSDimitry Andric#include <__type_traits/disjunction.h>
228bdd1243dSDimitry Andric#include <__type_traits/is_arithmetic.h>
229bdd1243dSDimitry Andric#include <__type_traits/is_assignable.h>
230bdd1243dSDimitry Andric#include <__type_traits/is_constructible.h>
231bdd1243dSDimitry Andric#include <__type_traits/is_convertible.h>
232bdd1243dSDimitry Andric#include <__type_traits/is_copy_assignable.h>
233bdd1243dSDimitry Andric#include <__type_traits/is_copy_constructible.h>
234bdd1243dSDimitry Andric#include <__type_traits/is_default_constructible.h>
235bdd1243dSDimitry Andric#include <__type_traits/is_empty.h>
236bdd1243dSDimitry Andric#include <__type_traits/is_final.h>
237bdd1243dSDimitry Andric#include <__type_traits/is_implicitly_default_constructible.h>
238bdd1243dSDimitry Andric#include <__type_traits/is_move_assignable.h>
239bdd1243dSDimitry Andric#include <__type_traits/is_move_constructible.h>
240bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_assignable.h>
241bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_constructible.h>
242bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_assignable.h>
243bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_constructible.h>
244bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_default_constructible.h>
245bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_move_assignable.h>
246bdd1243dSDimitry Andric#include <__type_traits/is_reference.h>
247bdd1243dSDimitry Andric#include <__type_traits/is_same.h>
248bdd1243dSDimitry Andric#include <__type_traits/is_swappable.h>
249bdd1243dSDimitry Andric#include <__type_traits/lazy.h>
250bdd1243dSDimitry Andric#include <__type_traits/maybe_const.h>
251bdd1243dSDimitry Andric#include <__type_traits/nat.h>
252bdd1243dSDimitry Andric#include <__type_traits/negation.h>
253bdd1243dSDimitry Andric#include <__type_traits/remove_cvref.h>
254bdd1243dSDimitry Andric#include <__type_traits/remove_reference.h>
255*06c3fb27SDimitry Andric#include <__type_traits/unwrap_ref.h>
256fe6060f1SDimitry Andric#include <__utility/forward.h>
257349cc55cSDimitry Andric#include <__utility/integer_sequence.h>
258fe6060f1SDimitry Andric#include <__utility/move.h>
25981ad6265SDimitry Andric#include <__utility/pair.h>
26081ad6265SDimitry Andric#include <__utility/piecewise_construct.h>
26181ad6265SDimitry Andric#include <__utility/swap.h>
2620b57cec5SDimitry Andric#include <cstddef>
2630b57cec5SDimitry Andric#include <version>
2640b57cec5SDimitry Andric
26581ad6265SDimitry Andric// standard-mandated includes
266bdd1243dSDimitry Andric
267bdd1243dSDimitry Andric// [tuple.syn]
26881ad6265SDimitry Andric#include <compare>
26981ad6265SDimitry Andric
2700b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2710b57cec5SDimitry Andric#  pragma GCC system_header
2720b57cec5SDimitry Andric#endif
2730b57cec5SDimitry Andric
274*06c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS
275*06c3fb27SDimitry Andric#include <__undef_macros>
276*06c3fb27SDimitry Andric
2770b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric// __tuple_leaf
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp,
2850b57cec5SDimitry Andric          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
2860b57cec5SDimitry Andric         >
2870b57cec5SDimitry Andricclass __tuple_leaf;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
290bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
2910b57cec5SDimitry Andricvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
2920b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
2930b57cec5SDimitry Andric{
2940b57cec5SDimitry Andric    swap(__x.get(), __y.get());
2950b57cec5SDimitry Andric}
2960b57cec5SDimitry Andric
29781ad6265SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep>
298bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
29981ad6265SDimitry Andricvoid swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y)
30081ad6265SDimitry Andric     _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) {
30181ad6265SDimitry Andric  swap(__x.get(), __y.get());
30281ad6265SDimitry Andric}
30381ad6265SDimitry Andric
3040b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool>
3050b57cec5SDimitry Andricclass __tuple_leaf
3060b57cec5SDimitry Andric{
3070b57cec5SDimitry Andric    _Hp __value_;
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric    template <class _Tp>
310*06c3fb27SDimitry Andric    static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
3110b57cec5SDimitry Andric#if __has_keyword(__reference_binds_to_temporary)
3120b57cec5SDimitry Andric      return !__reference_binds_to_temporary(_Hp, _Tp);
3130b57cec5SDimitry Andric#else
3140b57cec5SDimitry Andric      return true;
3150b57cec5SDimitry Andric#endif
3160b57cec5SDimitry Andric    }
3170b57cec5SDimitry Andric
318bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX14
3190b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
3200b57cec5SDimitry Andricpublic:
321fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
3220b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
3230b57cec5SDimitry Andric       {static_assert(!is_reference<_Hp>::value,
3240b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric    template <class _Alloc>
327fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3280b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
3290b57cec5SDimitry Andric            : __value_()
3300b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3310b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andric    template <class _Alloc>
334fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3350b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
3360b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a)
3370b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3380b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric    template <class _Alloc>
341fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
3420b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
3430b57cec5SDimitry Andric            : __value_(__a)
3440b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3450b57cec5SDimitry Andric              "Attempted to default construct a reference element in a tuple");}
3460b57cec5SDimitry Andric
3470b57cec5SDimitry Andric    template <class _Tp,
348349cc55cSDimitry Andric              class = __enable_if_t<
3490b57cec5SDimitry Andric                  _And<
350bdd1243dSDimitry Andric                      _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
3510b57cec5SDimitry Andric                      is_constructible<_Hp, _Tp>
3520b57cec5SDimitry Andric                    >::value
3530b57cec5SDimitry Andric                >
3540b57cec5SDimitry Andric            >
355bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3560b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
3570b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3580b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3590b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
362bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3630b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
3640b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t))
3650b57cec5SDimitry Andric        {static_assert(__can_bind_reference<_Tp&&>(),
3660b57cec5SDimitry Andric       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
369bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3700b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
3710b57cec5SDimitry Andric            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
3720b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3730b57cec5SDimitry Andric            "Attempted to uses-allocator construct a reference element in a tuple");}
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
376bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3770b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
3780b57cec5SDimitry Andric            : __value_(_VSTD::forward<_Tp>(__t), __a)
3790b57cec5SDimitry Andric        {static_assert(!is_reference<_Hp>::value,
3800b57cec5SDimitry Andric           "Attempted to uses-allocator construct a reference element in a tuple");}
3810b57cec5SDimitry Andric
382*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default;
383*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default;
3840b57cec5SDimitry Andric
385bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3860b57cec5SDimitry Andric    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
3870b57cec5SDimitry Andric    {
3880b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
3890b57cec5SDimitry Andric        return 0;
3900b57cec5SDimitry Andric    }
3910b57cec5SDimitry Andric
392bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
39381ad6265SDimitry Andric    int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
39481ad6265SDimitry Andric        _VSTD::swap(*this, __t);
39581ad6265SDimitry Andric        return 0;
39681ad6265SDimitry Andric    }
39781ad6265SDimitry Andric
398bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return __value_;}
399bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return __value_;}
4000b57cec5SDimitry Andric};
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp>
4030b57cec5SDimitry Andricclass __tuple_leaf<_Ip, _Hp, true>
4040b57cec5SDimitry Andric    : private _Hp
4050b57cec5SDimitry Andric{
406bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX14
4070b57cec5SDimitry Andric    __tuple_leaf& operator=(const __tuple_leaf&);
4080b57cec5SDimitry Andricpublic:
409fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
4100b57cec5SDimitry Andric             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric    template <class _Alloc>
413fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4140b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric    template <class _Alloc>
417fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4180b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
4190b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a) {}
4200b57cec5SDimitry Andric
4210b57cec5SDimitry Andric    template <class _Alloc>
422fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4230b57cec5SDimitry Andric        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
4240b57cec5SDimitry Andric            : _Hp(__a) {}
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric    template <class _Tp,
427349cc55cSDimitry Andric              class = __enable_if_t<
4280b57cec5SDimitry Andric                  _And<
429bdd1243dSDimitry Andric                    _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
4300b57cec5SDimitry Andric                    is_constructible<_Hp, _Tp>
4310b57cec5SDimitry Andric                  >::value
4320b57cec5SDimitry Andric                >
4330b57cec5SDimitry Andric            >
434bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4350b57cec5SDimitry Andric        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
4360b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
439fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4400b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
4410b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t)) {}
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
444fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4450b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
4460b57cec5SDimitry Andric            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric    template <class _Tp, class _Alloc>
449fe6060f1SDimitry Andric        _LIBCPP_INLINE_VISIBILITY constexpr
4500b57cec5SDimitry Andric        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
4510b57cec5SDimitry Andric            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf const &) = default;
4540b57cec5SDimitry Andric    __tuple_leaf(__tuple_leaf &&) = default;
4550b57cec5SDimitry Andric
456bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4570b57cec5SDimitry Andric    int
4580b57cec5SDimitry Andric    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
4590b57cec5SDimitry Andric    {
4600b57cec5SDimitry Andric        _VSTD::swap(*this, __t);
4610b57cec5SDimitry Andric        return 0;
4620b57cec5SDimitry Andric    }
4630b57cec5SDimitry Andric
464bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
46581ad6265SDimitry Andric    int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
46681ad6265SDimitry Andric        _VSTD::swap(*this, __rhs);
46781ad6265SDimitry Andric        return 0;
46881ad6265SDimitry Andric    }
46981ad6265SDimitry Andric
470bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
471bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
4720b57cec5SDimitry Andric};
4730b57cec5SDimitry Andric
4740b57cec5SDimitry Andrictemplate <class ..._Tp>
475bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
4760b57cec5SDimitry Andricvoid __swallow(_Tp&&...) _NOEXCEPT {}
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andrictemplate <class _Tp>
4790b57cec5SDimitry Andricstruct __all_default_constructible;
4800b57cec5SDimitry Andric
4810b57cec5SDimitry Andrictemplate <class ..._Tp>
4820b57cec5SDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>>
4830b57cec5SDimitry Andric    : __all<is_default_constructible<_Tp>::value...>
4840b57cec5SDimitry Andric{ };
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andric// __tuple_impl
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andrictemplate<class _Indx, class ..._Tp> struct __tuple_impl;
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andrictemplate<size_t ..._Indx, class ..._Tp>
4910b57cec5SDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
4920b57cec5SDimitry Andric    : public __tuple_leaf<_Indx, _Tp>...
4930b57cec5SDimitry Andric{
4940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
495fe6060f1SDimitry Andric    constexpr __tuple_impl()
4960b57cec5SDimitry Andric        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric    template <size_t ..._Uf, class ..._Tf,
4990b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
500bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5010b57cec5SDimitry Andric        explicit
5020b57cec5SDimitry Andric        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
5030b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
5040b57cec5SDimitry Andric                     _Up&&... __u)
5050b57cec5SDimitry Andric                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
5060b57cec5SDimitry Andric                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
5070b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
5080b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>()...
5090b57cec5SDimitry Andric            {}
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andric    template <class _Alloc, size_t ..._Uf, class ..._Tf,
5120b57cec5SDimitry Andric              size_t ..._Ul, class ..._Tl, class ..._Up>
513bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5140b57cec5SDimitry Andric        explicit
5150b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a,
5160b57cec5SDimitry Andric                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
5170b57cec5SDimitry Andric                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
5180b57cec5SDimitry Andric                     _Up&&... __u) :
5190b57cec5SDimitry Andric            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
5200b57cec5SDimitry Andric            _VSTD::forward<_Up>(__u))...,
5210b57cec5SDimitry Andric            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
5220b57cec5SDimitry Andric            {}
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric    template <class _Tuple,
525753f127fSDimitry Andric              class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
5260b57cec5SDimitry Andric             >
527bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5280b57cec5SDimitry Andric        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
5290b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
5300b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
5310b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
5320b57cec5SDimitry Andric            {}
5330b57cec5SDimitry Andric
5340b57cec5SDimitry Andric    template <class _Alloc, class _Tuple,
535753f127fSDimitry Andric              class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
5360b57cec5SDimitry Andric             >
537bdd1243dSDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5380b57cec5SDimitry Andric        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
5390b57cec5SDimitry Andric            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
5400b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
5410b57cec5SDimitry Andric                                       _VSTD::forward<typename tuple_element<_Indx,
5420b57cec5SDimitry Andric                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
5430b57cec5SDimitry Andric            {}
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric    __tuple_impl(const __tuple_impl&) = default;
5460b57cec5SDimitry Andric    __tuple_impl(__tuple_impl&&) = default;
5470b57cec5SDimitry Andric
548bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5490b57cec5SDimitry Andric    void swap(__tuple_impl& __t)
5500b57cec5SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
5510b57cec5SDimitry Andric    {
552fe6060f1SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
5530b57cec5SDimitry Andric    }
55481ad6265SDimitry Andric
555bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
55681ad6265SDimitry Andric    void swap(const __tuple_impl& __t) const
55781ad6265SDimitry Andric        _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value)
55881ad6265SDimitry Andric    {
55981ad6265SDimitry Andric        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...);
56081ad6265SDimitry Andric    }
5610b57cec5SDimitry Andric};
5620b57cec5SDimitry Andric
563fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, size_t ..._Np>
564bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
565fe6060f1SDimitry Andricvoid __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
566fe6060f1SDimitry Andric    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
567fe6060f1SDimitry Andric}
5680b57cec5SDimitry Andric
569fe6060f1SDimitry Andrictemplate<class _Dest, class _Source, class ..._Up, size_t ..._Np>
570bdd1243dSDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
571fe6060f1SDimitry Andricvoid __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
572fe6060f1SDimitry Andric    _VSTD::__swallow(((
573fe6060f1SDimitry Andric        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
574fe6060f1SDimitry Andric    ), void(), 0)...);
575fe6060f1SDimitry Andric}
5760b57cec5SDimitry Andric
5770b57cec5SDimitry Andrictemplate <class ..._Tp>
5780b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple
5790b57cec5SDimitry Andric{
5800b57cec5SDimitry Andric    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric    _BaseT __base_;
5830b57cec5SDimitry Andric
584bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5850b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
586bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5870b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
588bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5890b57cec5SDimitry Andric        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
590bdd1243dSDimitry Andric    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
5910b57cec5SDimitry Andric        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
5920b57cec5SDimitry Andricpublic:
593fe6060f1SDimitry Andric    // [tuple.cnstr]
5940b57cec5SDimitry Andric
595fe6060f1SDimitry Andric    // tuple() constructors (including allocator_arg_t variants)
596349cc55cSDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
597fe6060f1SDimitry Andric        _And<
598fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
599fe6060f1SDimitry Andric        >::value
600fe6060f1SDimitry Andric    , int> = 0>
601e40139ffSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
602e40139ffSDimitry Andric    tuple()
603fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
604fe6060f1SDimitry Andric    { }
605e40139ffSDimitry Andric
606fe6060f1SDimitry Andric    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
607349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
608fe6060f1SDimitry Andric        _And<
609fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
610fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
611fe6060f1SDimitry Andric        >::value
612fe6060f1SDimitry Andric    , int> = 0>
613fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
614fe6060f1SDimitry Andric    explicit tuple()
615fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
616fe6060f1SDimitry Andric    { }
6170b57cec5SDimitry Andric
618349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t<
619fe6060f1SDimitry Andric        _And<
620fe6060f1SDimitry Andric            _IsImpDefault<_Tp>... // explicit check
621fe6060f1SDimitry Andric        >::value
622fe6060f1SDimitry Andric    , int> = 0>
623bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
624fe6060f1SDimitry Andric    tuple(allocator_arg_t, _Alloc const& __a)
625fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
626fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
627fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
628fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
629fe6060f1SDimitry Andric
630fe6060f1SDimitry Andric    template <class _Alloc,
631fe6060f1SDimitry Andric              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
632349cc55cSDimitry Andric              template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
633fe6060f1SDimitry Andric        _And<
634fe6060f1SDimitry Andric            _IsDefault<_Tp>...,
635fe6060f1SDimitry Andric            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
636fe6060f1SDimitry Andric        >::value
637fe6060f1SDimitry Andric    , int> = 0>
638bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
639fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, _Alloc const& __a)
640fe6060f1SDimitry Andric      : __base_(allocator_arg_t(), __a,
641fe6060f1SDimitry Andric                    __tuple_indices<>(), __tuple_types<>(),
642fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
643fe6060f1SDimitry Andric                    __tuple_types<_Tp...>()) {}
644fe6060f1SDimitry Andric
645fe6060f1SDimitry Andric    // tuple(const T&...) constructors (including allocator_arg_t variants)
646349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
647fe6060f1SDimitry Andric        _And<
648fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
649fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
650fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
651fe6060f1SDimitry Andric        >::value
652fe6060f1SDimitry Andric    , int> = 0>
653bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
654fe6060f1SDimitry Andric    tuple(const _Tp& ... __t)
655fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
656fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
657fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
658fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
659fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
660fe6060f1SDimitry Andric                __t...
661fe6060f1SDimitry Andric               ) {}
662fe6060f1SDimitry Andric
663349cc55cSDimitry Andric    template <template<class...> class _And = _And, __enable_if_t<
664fe6060f1SDimitry Andric        _And<
665fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
666fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
667fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
668fe6060f1SDimitry Andric        >::value
669fe6060f1SDimitry Andric    , int> = 0>
670bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
671fe6060f1SDimitry Andric    explicit tuple(const _Tp& ... __t)
672fe6060f1SDimitry Andric        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
673fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
674fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
675fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
676fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
677fe6060f1SDimitry Andric                __t...
678fe6060f1SDimitry Andric               ) {}
679fe6060f1SDimitry Andric
680349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
681fe6060f1SDimitry Andric        _And<
682fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
683fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
684fe6060f1SDimitry Andric            is_convertible<const _Tp&, _Tp>... // explicit check
685fe6060f1SDimitry Andric        >::value
686fe6060f1SDimitry Andric    , int> = 0>
687bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
688fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
689fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
690fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
691fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
692fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
693fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
694fe6060f1SDimitry Andric                __t...
695fe6060f1SDimitry Andric               ) {}
696fe6060f1SDimitry Andric
697349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
698fe6060f1SDimitry Andric        _And<
699fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) >= 1>,
700fe6060f1SDimitry Andric            is_copy_constructible<_Tp>...,
701fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
702fe6060f1SDimitry Andric        >::value
703fe6060f1SDimitry Andric    , int> = 0>
704bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
705fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
706fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
707fe6060f1SDimitry Andric                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
708fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
709fe6060f1SDimitry Andric                typename __make_tuple_indices<0>::type(),
710fe6060f1SDimitry Andric                typename __make_tuple_types<tuple, 0>::type(),
711fe6060f1SDimitry Andric                __t...
712fe6060f1SDimitry Andric               ) {}
713fe6060f1SDimitry Andric
714fe6060f1SDimitry Andric    // tuple(U&& ...) constructors (including allocator_arg_t variants)
715fe6060f1SDimitry Andric    template <class ..._Up> struct _IsThisTuple : false_type { };
716bdd1243dSDimitry Andric    template <class _Up> struct _IsThisTuple<_Up> : is_same<__remove_cvref_t<_Up>, tuple> { };
717fe6060f1SDimitry Andric
718fe6060f1SDimitry Andric    template <class ..._Up>
719fe6060f1SDimitry Andric    struct _EnableUTypesCtor : _And<
720fe6060f1SDimitry Andric        _BoolConstant<sizeof...(_Tp) >= 1>,
721fe6060f1SDimitry Andric        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
722fe6060f1SDimitry Andric        is_constructible<_Tp, _Up>...
723fe6060f1SDimitry Andric    > { };
724fe6060f1SDimitry Andric
725349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
726fe6060f1SDimitry Andric        _And<
727fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
728fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
729fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
730fe6060f1SDimitry Andric        >::value
731fe6060f1SDimitry Andric    , int> = 0>
732bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
733fe6060f1SDimitry Andric    tuple(_Up&&... __u)
734fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
735fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
736fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
737fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
738fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
739fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
740fe6060f1SDimitry Andric
741349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
742fe6060f1SDimitry Andric        _And<
743fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
744fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
745fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
746fe6060f1SDimitry Andric        >::value
747fe6060f1SDimitry Andric    , int> = 0>
748bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
749fe6060f1SDimitry Andric    explicit tuple(_Up&&... __u)
750fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
751fe6060f1SDimitry Andric        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
752fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
753fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
754fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
755fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
756fe6060f1SDimitry Andric
757349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
758fe6060f1SDimitry Andric        _And<
759fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
760fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
761fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
762fe6060f1SDimitry Andric        >::value
763fe6060f1SDimitry Andric    , int> = 0>
764bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
765fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
766fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
767fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
768fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
769fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
770fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
771fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
772fe6060f1SDimitry Andric
773349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
774fe6060f1SDimitry Andric        _And<
775fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
776fe6060f1SDimitry Andric            _EnableUTypesCtor<_Up...>,
777fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
778fe6060f1SDimitry Andric        >::value
779fe6060f1SDimitry Andric    , int> = 0>
780bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
781fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
782fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a,
783fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
784fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
785fe6060f1SDimitry Andric                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
786fe6060f1SDimitry Andric                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
787fe6060f1SDimitry Andric                    _VSTD::forward<_Up>(__u)...) {}
788fe6060f1SDimitry Andric
789fe6060f1SDimitry Andric    // Copy and move constructors (including the allocator_arg_t variants)
790fe6060f1SDimitry Andric    tuple(const tuple&) = default;
7910b57cec5SDimitry Andric    tuple(tuple&&) = default;
7920b57cec5SDimitry Andric
793349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
794fe6060f1SDimitry Andric        _And<is_copy_constructible<_Tp>...>::value
795fe6060f1SDimitry Andric    , int> = 0>
796bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
797fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
798fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, __t)
799fe6060f1SDimitry Andric    { }
8000b57cec5SDimitry Andric
801349cc55cSDimitry Andric    template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
802fe6060f1SDimitry Andric        _And<is_move_constructible<_Tp>...>::value
803fe6060f1SDimitry Andric    , int> = 0>
804bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
805fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
806fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
807fe6060f1SDimitry Andric    { }
808e40139ffSDimitry Andric
809fe6060f1SDimitry Andric    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
81081ad6265SDimitry Andric
811bdd1243dSDimitry Andric    template <class _OtherTuple, class _DecayedOtherTuple = __remove_cvref_t<_OtherTuple>, class = void>
81281ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple : false_type {};
81381ad6265SDimitry Andric
81481ad6265SDimitry Andric    template <class _OtherTuple, class... _Up>
81581ad6265SDimitry Andric    struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>,
81681ad6265SDimitry Andric              // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below
81781ad6265SDimitry Andric               __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And<
81881ad6265SDimitry Andric        // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work.
81981ad6265SDimitry Andric        // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE
82081ad6265SDimitry Andric        _Not<is_same<_OtherTuple, const tuple&> >,
82181ad6265SDimitry Andric        _Not<is_same<_OtherTuple, tuple&&> >,
82281ad6265SDimitry Andric        is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
82381ad6265SDimitry Andric        _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>,
824fe6060f1SDimitry Andric            // _Tp and _Up are 1-element packs - the pack expansions look
825fe6060f1SDimitry Andric            // weird to avoid tripping up the type traits in degenerate cases
826fe6060f1SDimitry Andric            _Lazy<_And,
82781ad6265SDimitry Andric                _Not<is_same<_Tp, _Up> >...,
82881ad6265SDimitry Andric                _Not<is_convertible<_OtherTuple, _Tp> >...,
82981ad6265SDimitry Andric                _Not<is_constructible<_Tp, _OtherTuple> >...
8300b57cec5SDimitry Andric            >
83181ad6265SDimitry Andric        >
832fe6060f1SDimitry Andric    > {};
8330b57cec5SDimitry Andric
834349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
835fe6060f1SDimitry Andric        _And<
83681ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
837fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
8380b57cec5SDimitry Andric        >::value
839fe6060f1SDimitry Andric    , int> = 0>
840bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
841fe6060f1SDimitry Andric    tuple(const tuple<_Up...>& __t)
842fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
843fe6060f1SDimitry Andric        : __base_(__t)
844fe6060f1SDimitry Andric    { }
845fe6060f1SDimitry Andric
846349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
847fe6060f1SDimitry Andric        _And<
84881ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
849fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
8500b57cec5SDimitry Andric        >::value
851fe6060f1SDimitry Andric    , int> = 0>
852bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
853fe6060f1SDimitry Andric    explicit tuple(const tuple<_Up...>& __t)
854fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
855fe6060f1SDimitry Andric        : __base_(__t)
856fe6060f1SDimitry Andric    { }
8570b57cec5SDimitry Andric
858349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
859fe6060f1SDimitry Andric        _And<
86081ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
861fe6060f1SDimitry Andric            is_convertible<const _Up&, _Tp>... // explicit check
862fe6060f1SDimitry Andric        >::value
863fe6060f1SDimitry Andric    , int> = 0>
864bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
865fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
866fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
867fe6060f1SDimitry Andric    { }
8680b57cec5SDimitry Andric
869349cc55cSDimitry Andric    template <class ..._Up, class _Alloc, __enable_if_t<
870fe6060f1SDimitry Andric        _And<
87181ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
872fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
873fe6060f1SDimitry Andric        >::value
874fe6060f1SDimitry Andric    , int> = 0>
875bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
876fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
877fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __t)
878fe6060f1SDimitry Andric    { }
8790b57cec5SDimitry Andric
880*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
88181ad6265SDimitry Andric    // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
88281ad6265SDimitry Andric
88381ad6265SDimitry Andric    template <class... _Up, enable_if_t<
88481ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
88581ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
88681ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
88781ad6265SDimitry Andric    tuple(tuple<_Up...>& __t) : __base_(__t) {}
88881ad6265SDimitry Andric
88981ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
89081ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
89181ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
89281ad6265SDimitry Andric        explicit(!(is_convertible_v<_Up&, _Tp> && ...))
89381ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
894*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
89581ad6265SDimitry Andric
896fe6060f1SDimitry Andric    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
8970b57cec5SDimitry Andric
898349cc55cSDimitry Andric    template <class ..._Up, __enable_if_t<
899fe6060f1SDimitry Andric        _And<
90081ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
901fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
902fe6060f1SDimitry Andric        >::value
903fe6060f1SDimitry Andric    , int> = 0>
904bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
905fe6060f1SDimitry Andric    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 ..._Up, __enable_if_t<
911fe6060f1SDimitry Andric        _And<
91281ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
913fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
914fe6060f1SDimitry Andric        >::value
915fe6060f1SDimitry Andric    , int> = 0>
916bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
917fe6060f1SDimitry Andric    explicit tuple(tuple<_Up...>&& __t)
918fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
919fe6060f1SDimitry Andric        : __base_(_VSTD::move(__t))
920fe6060f1SDimitry Andric    { }
9210b57cec5SDimitry Andric
922349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
923fe6060f1SDimitry Andric        _And<
92481ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
925fe6060f1SDimitry Andric            is_convertible<_Up, _Tp>... // explicit check
926fe6060f1SDimitry Andric        >::value
927fe6060f1SDimitry Andric    , int> = 0>
928bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
929fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
930fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
931fe6060f1SDimitry Andric    { }
932fe6060f1SDimitry Andric
933349cc55cSDimitry Andric    template <class _Alloc, class ..._Up, __enable_if_t<
934fe6060f1SDimitry Andric        _And<
93581ad6265SDimitry Andric            _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
936fe6060f1SDimitry Andric            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
937fe6060f1SDimitry Andric        >::value
938fe6060f1SDimitry Andric    , int> = 0>
939bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
940fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
941fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
942fe6060f1SDimitry Andric    { }
943fe6060f1SDimitry Andric
944*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
94581ad6265SDimitry Andric    // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
94681ad6265SDimitry Andric
94781ad6265SDimitry Andric    template <class... _Up, enable_if_t<
94881ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
94981ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
95081ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
95181ad6265SDimitry Andric    tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {}
95281ad6265SDimitry Andric
95381ad6265SDimitry Andric    template <class _Alloc, class... _Up, enable_if_t<
95481ad6265SDimitry Andric        _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
95581ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
95681ad6265SDimitry Andric        explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
95781ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
95881ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
959*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
96081ad6265SDimitry Andric
961fe6060f1SDimitry Andric    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
96281ad6265SDimitry Andric
963*06c3fb27SDimitry Andric    template <template <class...> class _Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
96481ad6265SDimitry Andric    struct _CtorPredicateFromPair : false_type{};
96581ad6265SDimitry Andric
966*06c3fb27SDimitry Andric    template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
967*06c3fb27SDimitry Andric    struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
968*06c3fb27SDimitry Andric        _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
969*06c3fb27SDimitry Andric        _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
970fe6060f1SDimitry Andric    > {};
971fe6060f1SDimitry Andric
97281ad6265SDimitry Andric    template <class _Pair>
97381ad6265SDimitry Andric    struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{};
97481ad6265SDimitry Andric
97581ad6265SDimitry Andric    template <class _Pair>
97681ad6265SDimitry Andric    struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{};
97781ad6265SDimitry Andric
978bdd1243dSDimitry Andric    template <class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
97981ad6265SDimitry Andric    struct _BothImplicitlyConvertible : false_type{};
98081ad6265SDimitry Andric
98181ad6265SDimitry Andric    template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
98281ad6265SDimitry Andric    struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
98381ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>,
98481ad6265SDimitry Andric        is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2>
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            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
991fe6060f1SDimitry Andric        >::value
992fe6060f1SDimitry Andric    , int> = 0>
993bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
994fe6060f1SDimitry Andric    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 _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1000fe6060f1SDimitry Andric        _And<
100181ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
100281ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
1003fe6060f1SDimitry Andric        >::value
1004fe6060f1SDimitry Andric    , int> = 0>
1005bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
1006fe6060f1SDimitry Andric    explicit tuple(const pair<_Up1, _Up2>& __p)
100781ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
1008fe6060f1SDimitry Andric        : __base_(__p)
1009fe6060f1SDimitry Andric    { }
1010fe6060f1SDimitry Andric
1011349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1012fe6060f1SDimitry Andric        _And<
101381ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
101481ad6265SDimitry Andric            _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
1015fe6060f1SDimitry Andric        >::value
1016fe6060f1SDimitry Andric    , int> = 0>
1017bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1018fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
1019fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
1020fe6060f1SDimitry Andric    { }
1021fe6060f1SDimitry Andric
1022349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1023fe6060f1SDimitry Andric        _And<
102481ad6265SDimitry Andric            _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
102581ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
1026fe6060f1SDimitry Andric        >::value
1027fe6060f1SDimitry Andric    , int> = 0>
1028bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1029fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
1030fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, __p)
1031fe6060f1SDimitry Andric    { }
1032fe6060f1SDimitry Andric
1033*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
103481ad6265SDimitry Andric    // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
1035fe6060f1SDimitry Andric
103681ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
103781ad6265SDimitry Andric        _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
103881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
103981ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
104081ad6265SDimitry Andric    tuple(pair<_U1, _U2>& __p) : __base_(__p) {}
104181ad6265SDimitry Andric
104281ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
104381ad6265SDimitry Andric        _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
104481ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
104581ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
104681ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {}
104781ad6265SDimitry Andric#endif
104881ad6265SDimitry Andric
104981ad6265SDimitry Andric    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
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            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1055fe6060f1SDimitry Andric        >::value
1056fe6060f1SDimitry Andric    , int> = 0>
1057bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
1058fe6060f1SDimitry Andric    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 _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1064fe6060f1SDimitry Andric        _And<
106581ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
106681ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1067fe6060f1SDimitry Andric        >::value
1068fe6060f1SDimitry Andric    , int> = 0>
1069bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
1070fe6060f1SDimitry Andric    explicit tuple(pair<_Up1, _Up2>&& __p)
107181ad6265SDimitry Andric        _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
1072fe6060f1SDimitry Andric        : __base_(_VSTD::move(__p))
1073fe6060f1SDimitry Andric    { }
1074fe6060f1SDimitry Andric
1075349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1076fe6060f1SDimitry Andric        _And<
107781ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
107881ad6265SDimitry Andric            _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
1079fe6060f1SDimitry Andric        >::value
1080fe6060f1SDimitry Andric    , int> = 0>
1081bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1082fe6060f1SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1083fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1084fe6060f1SDimitry Andric    { }
1085fe6060f1SDimitry Andric
1086349cc55cSDimitry Andric    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
1087fe6060f1SDimitry Andric        _And<
108881ad6265SDimitry Andric            _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
108981ad6265SDimitry Andric            _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
1090fe6060f1SDimitry Andric        >::value
1091fe6060f1SDimitry Andric    , int> = 0>
1092bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1093fe6060f1SDimitry Andric    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
1094fe6060f1SDimitry Andric        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
1095fe6060f1SDimitry Andric    { }
1096fe6060f1SDimitry Andric
1097*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
109881ad6265SDimitry Andric    // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
109981ad6265SDimitry Andric
110081ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
110181ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
110281ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
110381ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
110481ad6265SDimitry Andric    tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {}
110581ad6265SDimitry Andric
110681ad6265SDimitry Andric    template <class _Alloc, class _U1, class _U2, enable_if_t<
110781ad6265SDimitry Andric        _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
110881ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
110981ad6265SDimitry Andric        explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
111081ad6265SDimitry Andric    tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
111181ad6265SDimitry Andric        : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
1112*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
111381ad6265SDimitry Andric
1114fe6060f1SDimitry Andric    // [tuple.assign]
1115bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1116fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
1117fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
11180b57cec5SDimitry Andric    {
1119fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1120fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11210b57cec5SDimitry Andric        return *this;
11220b57cec5SDimitry Andric    }
11230b57cec5SDimitry Andric
1124*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
112581ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
112681ad6265SDimitry Andric    const tuple& operator=(tuple const& __tuple) const
112781ad6265SDimitry Andric      requires (_And<is_copy_assignable<const _Tp>...>::value) {
112881ad6265SDimitry Andric        std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
112981ad6265SDimitry Andric        return *this;
113081ad6265SDimitry Andric    }
113181ad6265SDimitry Andric
113281ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
113381ad6265SDimitry Andric    const tuple& operator=(tuple&& __tuple) const
113481ad6265SDimitry Andric      requires (_And<is_assignable<const _Tp&, _Tp>...>::value) {
113581ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
113681ad6265SDimitry Andric                                         std::move(__tuple),
113781ad6265SDimitry Andric                                         __tuple_types<_Tp...>(),
113881ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
113981ad6265SDimitry Andric        return *this;
114081ad6265SDimitry Andric    }
1141*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
114281ad6265SDimitry Andric
1143bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1144fe6060f1SDimitry Andric    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
1145fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
11460b57cec5SDimitry Andric    {
1147fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1148fe6060f1SDimitry Andric            __tuple_types<_Tp...>(),
1149fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11500b57cec5SDimitry Andric        return *this;
11510b57cec5SDimitry Andric    }
11520b57cec5SDimitry Andric
1153349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1154fe6060f1SDimitry Andric        _And<
1155fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1156fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1157fe6060f1SDimitry Andric        >::value
1158fe6060f1SDimitry Andric    ,int> = 0>
1159bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1160fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...> const& __tuple)
1161fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
11620b57cec5SDimitry Andric    {
1163fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __tuple,
1164fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
11650b57cec5SDimitry Andric        return *this;
11660b57cec5SDimitry Andric    }
11670b57cec5SDimitry Andric
1168349cc55cSDimitry Andric    template<class... _Up, __enable_if_t<
1169fe6060f1SDimitry Andric        _And<
1170fe6060f1SDimitry Andric            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
1171fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1172fe6060f1SDimitry Andric        >::value
1173fe6060f1SDimitry Andric    ,int> = 0>
1174bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1175fe6060f1SDimitry Andric    tuple& operator=(tuple<_Up...>&& __tuple)
1176fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1177fe6060f1SDimitry Andric    {
1178fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
1179fe6060f1SDimitry Andric            __tuple_types<_Up...>(),
1180fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1181fe6060f1SDimitry Andric        return *this;
1182fe6060f1SDimitry Andric    }
1183fe6060f1SDimitry Andric
118481ad6265SDimitry Andric
1185*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
118681ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
118781ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
118881ad6265SDimitry Andric             is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
118981ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
119081ad6265SDimitry Andric    const tuple& operator=(const tuple<_UTypes...>& __u) const {
119181ad6265SDimitry Andric        std::__memberwise_copy_assign(*this,
119281ad6265SDimitry Andric                                      __u,
119381ad6265SDimitry Andric                                      typename __make_tuple_indices<sizeof...(_Tp)>::type());
119481ad6265SDimitry Andric        return *this;
119581ad6265SDimitry Andric    }
119681ad6265SDimitry Andric
119781ad6265SDimitry Andric    template <class... _UTypes, enable_if_t<
119881ad6265SDimitry Andric        _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
119981ad6265SDimitry Andric             is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
120081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
120181ad6265SDimitry Andric    const tuple& operator=(tuple<_UTypes...>&& __u) const {
120281ad6265SDimitry Andric        std::__memberwise_forward_assign(*this,
120381ad6265SDimitry Andric                                         __u,
120481ad6265SDimitry Andric                                         __tuple_types<_UTypes...>(),
120581ad6265SDimitry Andric                                         typename __make_tuple_indices<sizeof...(_Tp)>::type());
120681ad6265SDimitry Andric        return *this;
120781ad6265SDimitry Andric    }
1208*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
120981ad6265SDimitry Andric
1210*06c3fb27SDimitry Andric    template <template<class...> class _Pred, bool _Const,
1211bdd1243dSDimitry Andric              class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
121281ad6265SDimitry Andric    struct _AssignPredicateFromPair : false_type {};
121381ad6265SDimitry Andric
1214*06c3fb27SDimitry Andric    template <template<class...> class _Pred, bool _Const,
121581ad6265SDimitry Andric              class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
1216*06c3fb27SDimitry Andric    struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
1217*06c3fb27SDimitry Andric        _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
1218*06c3fb27SDimitry Andric             _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
121981ad6265SDimitry Andric            > {};
122081ad6265SDimitry Andric
122181ad6265SDimitry Andric    template <bool _Const, class _Pair>
122281ad6265SDimitry Andric    struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {};
122381ad6265SDimitry Andric
122481ad6265SDimitry Andric    template <bool _Const, class _Pair>
122581ad6265SDimitry Andric    struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
122681ad6265SDimitry Andric
1227*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
122881ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
122981ad6265SDimitry Andric        _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
123081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
123181ad6265SDimitry Andric    const tuple& operator=(const pair<_U1, _U2>& __pair) const
123281ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) {
123381ad6265SDimitry Andric        std::get<0>(*this) = __pair.first;
123481ad6265SDimitry Andric        std::get<1>(*this) = __pair.second;
123581ad6265SDimitry Andric        return *this;
123681ad6265SDimitry Andric    }
123781ad6265SDimitry Andric
123881ad6265SDimitry Andric    template <class _U1, class _U2, enable_if_t<
123981ad6265SDimitry Andric        _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr>
124081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
124181ad6265SDimitry Andric    const tuple& operator=(pair<_U1, _U2>&& __pair) const
124281ad6265SDimitry Andric      noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) {
124381ad6265SDimitry Andric        std::get<0>(*this) = std::move(__pair.first);
124481ad6265SDimitry Andric        std::get<1>(*this) = std::move(__pair.second);
124581ad6265SDimitry Andric        return *this;
124681ad6265SDimitry Andric    }
1247*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
124881ad6265SDimitry Andric
124981ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
125081ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
1251fe6060f1SDimitry Andric    ,int> = 0>
1252bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1253fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2> const& __pair)
125481ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value))
1255fe6060f1SDimitry Andric    {
1256fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = __pair.first;
1257fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = __pair.second;
1258fe6060f1SDimitry Andric        return *this;
1259fe6060f1SDimitry Andric    }
1260fe6060f1SDimitry Andric
126181ad6265SDimitry Andric    template<class _Up1, class _Up2, __enable_if_t<
126281ad6265SDimitry Andric        _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value
1263fe6060f1SDimitry Andric    ,int> = 0>
1264bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1265fe6060f1SDimitry Andric    tuple& operator=(pair<_Up1, _Up2>&& __pair)
126681ad6265SDimitry Andric        _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value))
1267fe6060f1SDimitry Andric    {
1268fe6060f1SDimitry Andric        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1269fe6060f1SDimitry Andric        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1270fe6060f1SDimitry Andric        return *this;
1271fe6060f1SDimitry Andric    }
1272fe6060f1SDimitry Andric
1273fe6060f1SDimitry Andric    // EXTENSION
1274349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = __enable_if_t<
1275fe6060f1SDimitry Andric        _And<
1276fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1277fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up const&>...
1278fe6060f1SDimitry Andric        >::value
1279fe6060f1SDimitry Andric    > >
1280bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1281fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np> const& __array)
1282fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1283fe6060f1SDimitry Andric    {
1284fe6060f1SDimitry Andric        _VSTD::__memberwise_copy_assign(*this, __array,
1285fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1286fe6060f1SDimitry Andric        return *this;
1287fe6060f1SDimitry Andric    }
1288fe6060f1SDimitry Andric
1289fe6060f1SDimitry Andric    // EXTENSION
1290349cc55cSDimitry Andric    template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1291fe6060f1SDimitry Andric        _And<
1292fe6060f1SDimitry Andric            _BoolConstant<_Np == sizeof...(_Tp)>,
1293fe6060f1SDimitry Andric            is_assignable<_Tp&, _Up>...
1294fe6060f1SDimitry Andric        >::value
1295fe6060f1SDimitry Andric    > >
1296bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1297fe6060f1SDimitry Andric    tuple& operator=(array<_Up, _Np>&& __array)
1298fe6060f1SDimitry Andric        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1299fe6060f1SDimitry Andric    {
1300fe6060f1SDimitry Andric        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1301fe6060f1SDimitry Andric            __tuple_types<_If<true, _Up, _Tp>...>(),
1302fe6060f1SDimitry Andric            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1303fe6060f1SDimitry Andric        return *this;
1304fe6060f1SDimitry Andric    }
1305fe6060f1SDimitry Andric
1306fe6060f1SDimitry Andric    // [tuple.swap]
1307bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13080b57cec5SDimitry Andric    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
13090b57cec5SDimitry Andric        {__base_.swap(__t.__base_);}
131081ad6265SDimitry Andric
1311*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
131281ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
131381ad6265SDimitry Andric    void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
131481ad6265SDimitry Andric        __base_.swap(__t.__base_);
131581ad6265SDimitry Andric    }
1316*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
13170b57cec5SDimitry Andric};
13180b57cec5SDimitry Andric
13190b57cec5SDimitry Andrictemplate <>
13200b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<>
13210b57cec5SDimitry Andric{
13220b57cec5SDimitry Andricpublic:
1323*06c3fb27SDimitry Andric    constexpr tuple() _NOEXCEPT = default;
13240b57cec5SDimitry Andric    template <class _Alloc>
1325bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13260b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
13270b57cec5SDimitry Andric    template <class _Alloc>
1328bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13290b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
13300b57cec5SDimitry Andric    template <class _Up>
1331bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13320b57cec5SDimitry Andric        tuple(array<_Up, 0>) _NOEXCEPT {}
13330b57cec5SDimitry Andric    template <class _Alloc, class _Up>
1334bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13350b57cec5SDimitry Andric        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1336bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13370b57cec5SDimitry Andric    void swap(tuple&) _NOEXCEPT {}
1338*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
133981ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
134081ad6265SDimitry Andric#endif
13410b57cec5SDimitry Andric};
13420b57cec5SDimitry Andric
1343*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
134404eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
134504eeddc0SDimitry Andric    requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
134604eeddc0SDimitry Andricstruct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
134704eeddc0SDimitry Andric    using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
134804eeddc0SDimitry Andric};
134904eeddc0SDimitry Andric
135004eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes>
135104eeddc0SDimitry Andric    requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
135204eeddc0SDimitry Andricstruct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
135304eeddc0SDimitry Andric    using type = tuple<common_type_t<_TTypes, _UTypes>...>;
135404eeddc0SDimitry Andric};
1355*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23
135604eeddc0SDimitry Andric
1357*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1358e40139ffSDimitry Andrictemplate <class ..._Tp>
1359e40139ffSDimitry Andrictuple(_Tp...) -> tuple<_Tp...>;
1360e40139ffSDimitry Andrictemplate <class _Tp1, class _Tp2>
1361e40139ffSDimitry Andrictuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1362e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1363e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1364e40139ffSDimitry Andrictemplate <class _Alloc, class _Tp1, class _Tp2>
1365e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1366e40139ffSDimitry Andrictemplate <class _Alloc, class ..._Tp>
1367e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
13680b57cec5SDimitry Andric#endif
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andrictemplate <class ..._Tp>
1371bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1372753f127fSDimitry Andric__enable_if_t<__all<__is_swappable<_Tp>::value...>::value, void>
13730b57cec5SDimitry Andricswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
13740b57cec5SDimitry Andric                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
13750b57cec5SDimitry Andric    {__t.swap(__u);}
13760b57cec5SDimitry Andric
1377*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
137881ad6265SDimitry Andrictemplate <class... _Tp>
137981ad6265SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
138081ad6265SDimitry Andricenable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
138181ad6265SDimitry Andricswap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs)
138281ad6265SDimitry Andric        noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) {
138381ad6265SDimitry Andric    __lhs.swap(__rhs);
138481ad6265SDimitry Andric}
138581ad6265SDimitry Andric#endif
138681ad6265SDimitry Andric
13870b57cec5SDimitry Andric// get
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1390bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
13910b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&
13920b57cec5SDimitry Andricget(tuple<_Tp...>& __t) _NOEXCEPT
13930b57cec5SDimitry Andric{
1394349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
13950b57cec5SDimitry Andric    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
13960b57cec5SDimitry Andric}
13970b57cec5SDimitry Andric
13980b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1399bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
14000b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
14010b57cec5SDimitry Andricget(const tuple<_Tp...>& __t) _NOEXCEPT
14020b57cec5SDimitry Andric{
1403349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
14040b57cec5SDimitry Andric    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
14050b57cec5SDimitry Andric}
14060b57cec5SDimitry Andric
14070b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1408bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
14090b57cec5SDimitry Andrictypename tuple_element<_Ip, tuple<_Tp...> >::type&&
14100b57cec5SDimitry Andricget(tuple<_Tp...>&& __t) _NOEXCEPT
14110b57cec5SDimitry Andric{
1412349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
14130b57cec5SDimitry Andric    return static_cast<type&&>(
14140b57cec5SDimitry Andric             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
14150b57cec5SDimitry Andric}
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andrictemplate <size_t _Ip, class ..._Tp>
1418bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
14190b57cec5SDimitry Andricconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
14200b57cec5SDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT
14210b57cec5SDimitry Andric{
1422349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
14230b57cec5SDimitry Andric    return static_cast<const type&&>(
14240b57cec5SDimitry Andric             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
14250b57cec5SDimitry Andric}
14260b57cec5SDimitry Andric
1427*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andricnamespace __find_detail {
14300b57cec5SDimitry Andric
1431fe6060f1SDimitry Andricstatic constexpr size_t __not_found = static_cast<size_t>(-1);
14320b57cec5SDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1;
14330b57cec5SDimitry Andric
14340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14350b57cec5SDimitry Andricconstexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
14360b57cec5SDimitry Andric    return !__matches ? __res :
14370b57cec5SDimitry Andric        (__res == __not_found ? __curr_i : __ambiguous);
14380b57cec5SDimitry Andric}
14390b57cec5SDimitry Andric
14400b57cec5SDimitry Andrictemplate <size_t _Nx>
14410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14420b57cec5SDimitry Andricconstexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
14430b57cec5SDimitry Andric  return __i == _Nx ? __not_found :
1444bdd1243dSDimitry Andric      __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
14450b57cec5SDimitry Andric}
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andrictemplate <class _T1, class ..._Args>
14480b57cec5SDimitry Andricstruct __find_exactly_one_checked {
14490b57cec5SDimitry Andric    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
14500b57cec5SDimitry Andric    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
14510b57cec5SDimitry Andric    static_assert(value != __not_found, "type not found in type list" );
14520b57cec5SDimitry Andric    static_assert(value != __ambiguous, "type occurs more than once in type list");
14530b57cec5SDimitry Andric};
14540b57cec5SDimitry Andric
14550b57cec5SDimitry Andrictemplate <class _T1>
14560b57cec5SDimitry Andricstruct __find_exactly_one_checked<_T1> {
14570b57cec5SDimitry Andric    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
14580b57cec5SDimitry Andric};
14590b57cec5SDimitry Andric
14600eae32dcSDimitry Andric} // namespace __find_detail
14610b57cec5SDimitry Andric
14620b57cec5SDimitry Andrictemplate <typename _T1, typename... _Args>
14630b57cec5SDimitry Andricstruct __find_exactly_one_t
14640b57cec5SDimitry Andric    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
14650b57cec5SDimitry Andric};
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14690b57cec5SDimitry Andricconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
14700b57cec5SDimitry Andric{
14710b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14720b57cec5SDimitry Andric}
14730b57cec5SDimitry Andric
14740b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14760b57cec5SDimitry Andricconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
14770b57cec5SDimitry Andric{
14780b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
14790b57cec5SDimitry Andric}
14800b57cec5SDimitry Andric
14810b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14830b57cec5SDimitry Andricconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
14840b57cec5SDimitry Andric{
14850b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14860b57cec5SDimitry Andric}
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andrictemplate <class _T1, class... _Args>
14890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14900b57cec5SDimitry Andricconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
14910b57cec5SDimitry Andric{
14920b57cec5SDimitry Andric    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
14930b57cec5SDimitry Andric}
14940b57cec5SDimitry Andric
14950b57cec5SDimitry Andric#endif
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andric// tie
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andrictemplate <class ..._Tp>
1500bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15010b57cec5SDimitry Andrictuple<_Tp&...>
15020b57cec5SDimitry Andrictie(_Tp&... __t) _NOEXCEPT
15030b57cec5SDimitry Andric{
15040b57cec5SDimitry Andric    return tuple<_Tp&...>(__t...);
15050b57cec5SDimitry Andric}
15060b57cec5SDimitry Andric
15070b57cec5SDimitry Andrictemplate <class _Up>
15080b57cec5SDimitry Andricstruct __ignore_t
15090b57cec5SDimitry Andric{
15100b57cec5SDimitry Andric    template <class _Tp>
1511bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15120b57cec5SDimitry Andric    const __ignore_t& operator=(_Tp&&) const {return *this;}
15130b57cec5SDimitry Andric};
15140b57cec5SDimitry Andric
1515*06c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1516*06c3fb27SDimitry Andricinline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1517*06c3fb27SDimitry Andric#  else
15180b57cec5SDimitry Andricnamespace {
1519349cc55cSDimitry Andric  constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
15200eae32dcSDimitry Andric} // namespace
1521*06c3fb27SDimitry Andric#  endif
15220b57cec5SDimitry Andric
15230b57cec5SDimitry Andrictemplate <class... _Tp>
1524bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15250b57cec5SDimitry Andrictuple<typename __unwrap_ref_decay<_Tp>::type...>
15260b57cec5SDimitry Andricmake_tuple(_Tp&&... __t)
15270b57cec5SDimitry Andric{
15280b57cec5SDimitry Andric    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
15290b57cec5SDimitry Andric}
15300b57cec5SDimitry Andric
15310b57cec5SDimitry Andrictemplate <class... _Tp>
1532bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15330b57cec5SDimitry Andrictuple<_Tp&&...>
15340b57cec5SDimitry Andricforward_as_tuple(_Tp&&... __t) _NOEXCEPT
15350b57cec5SDimitry Andric{
15360b57cec5SDimitry Andric    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
15370b57cec5SDimitry Andric}
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andrictemplate <size_t _Ip>
15400b57cec5SDimitry Andricstruct __tuple_equal
15410b57cec5SDimitry Andric{
15420b57cec5SDimitry Andric    template <class _Tp, class _Up>
1543bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15440b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
15450b57cec5SDimitry Andric    {
15460b57cec5SDimitry Andric        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
15470b57cec5SDimitry Andric    }
15480b57cec5SDimitry Andric};
15490b57cec5SDimitry Andric
15500b57cec5SDimitry Andrictemplate <>
15510b57cec5SDimitry Andricstruct __tuple_equal<0>
15520b57cec5SDimitry Andric{
15530b57cec5SDimitry Andric    template <class _Tp, class _Up>
1554bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15550b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
15560b57cec5SDimitry Andric    {
15570b57cec5SDimitry Andric        return true;
15580b57cec5SDimitry Andric    }
15590b57cec5SDimitry Andric};
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1562bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15630b57cec5SDimitry Andricbool
15640b57cec5SDimitry Andricoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15650b57cec5SDimitry Andric{
15660b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
15670b57cec5SDimitry Andric    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
15680b57cec5SDimitry Andric}
15690b57cec5SDimitry Andric
1570*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
1571349cc55cSDimitry Andric
1572349cc55cSDimitry Andric// operator<=>
1573349cc55cSDimitry Andric
1574349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up, size_t ..._Is>
1575349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1576349cc55cSDimitry Andricauto
1577349cc55cSDimitry Andric__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1578349cc55cSDimitry Andric    common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1579349cc55cSDimitry Andric    static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...));
1580349cc55cSDimitry Andric    return __result;
1581349cc55cSDimitry Andric}
1582349cc55cSDimitry Andric
1583349cc55cSDimitry Andrictemplate <class ..._Tp, class ..._Up>
1584349cc55cSDimitry Andricrequires (sizeof...(_Tp) == sizeof...(_Up))
1585349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr
1586349cc55cSDimitry Andriccommon_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1587349cc55cSDimitry Andricoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1588349cc55cSDimitry Andric{
1589349cc55cSDimitry Andric    return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1590349cc55cSDimitry Andric}
1591349cc55cSDimitry Andric
1592*06c3fb27SDimitry Andric#else // _LIBCPP_STD_VER >= 20
1593349cc55cSDimitry Andric
15940b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1595bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
15960b57cec5SDimitry Andricbool
15970b57cec5SDimitry Andricoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15980b57cec5SDimitry Andric{
15990b57cec5SDimitry Andric    return !(__x == __y);
16000b57cec5SDimitry Andric}
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andrictemplate <size_t _Ip>
16030b57cec5SDimitry Andricstruct __tuple_less
16040b57cec5SDimitry Andric{
16050b57cec5SDimitry Andric    template <class _Tp, class _Up>
1606bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16070b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Up& __y)
16080b57cec5SDimitry Andric    {
16090b57cec5SDimitry Andric        const size_t __idx = tuple_size<_Tp>::value - _Ip;
16100b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
16110b57cec5SDimitry Andric            return true;
16120b57cec5SDimitry Andric        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
16130b57cec5SDimitry Andric            return false;
16140b57cec5SDimitry Andric        return __tuple_less<_Ip-1>()(__x, __y);
16150b57cec5SDimitry Andric    }
16160b57cec5SDimitry Andric};
16170b57cec5SDimitry Andric
16180b57cec5SDimitry Andrictemplate <>
16190b57cec5SDimitry Andricstruct __tuple_less<0>
16200b57cec5SDimitry Andric{
16210b57cec5SDimitry Andric    template <class _Tp, class _Up>
1622bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16230b57cec5SDimitry Andric    bool operator()(const _Tp&, const _Up&)
16240b57cec5SDimitry Andric    {
16250b57cec5SDimitry Andric        return false;
16260b57cec5SDimitry Andric    }
16270b57cec5SDimitry Andric};
16280b57cec5SDimitry Andric
16290b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1630bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16310b57cec5SDimitry Andricbool
16320b57cec5SDimitry Andricoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16330b57cec5SDimitry Andric{
16340b57cec5SDimitry Andric    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
16350b57cec5SDimitry Andric    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
16360b57cec5SDimitry Andric}
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1639bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16400b57cec5SDimitry Andricbool
16410b57cec5SDimitry Andricoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16420b57cec5SDimitry Andric{
16430b57cec5SDimitry Andric    return __y < __x;
16440b57cec5SDimitry Andric}
16450b57cec5SDimitry Andric
16460b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1647bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16480b57cec5SDimitry Andricbool
16490b57cec5SDimitry Andricoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16500b57cec5SDimitry Andric{
16510b57cec5SDimitry Andric    return !(__x < __y);
16520b57cec5SDimitry Andric}
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andrictemplate <class ..._Tp, class ..._Up>
1655bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
16560b57cec5SDimitry Andricbool
16570b57cec5SDimitry Andricoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16580b57cec5SDimitry Andric{
16590b57cec5SDimitry Andric    return !(__y < __x);
16600b57cec5SDimitry Andric}
16610b57cec5SDimitry Andric
1662*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20
1663349cc55cSDimitry Andric
16640b57cec5SDimitry Andric// tuple_cat
16650b57cec5SDimitry Andric
16660b57cec5SDimitry Andrictemplate <class _Tp, class _Up> struct __tuple_cat_type;
16670b57cec5SDimitry Andric
16680b57cec5SDimitry Andrictemplate <class ..._Ttypes, class ..._Utypes>
16690b57cec5SDimitry Andricstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
16700b57cec5SDimitry Andric{
1671349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
16720b57cec5SDimitry Andric};
16730b57cec5SDimitry Andric
16740b57cec5SDimitry Andrictemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
16750b57cec5SDimitry Andricstruct __tuple_cat_return_1
16760b57cec5SDimitry Andric{
16770b57cec5SDimitry Andric};
16780b57cec5SDimitry Andric
16790b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0>
16800b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
16810b57cec5SDimitry Andric{
168281ad6265SDimitry Andric  using type _LIBCPP_NODEBUG = typename __tuple_cat_type<
168381ad6265SDimitry Andric      tuple<_Types...>,
1684bdd1243dSDimitry Andric      typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
168581ad6265SDimitry Andric    >::type;
16860b57cec5SDimitry Andric};
16870b57cec5SDimitry Andric
16880b57cec5SDimitry Andrictemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
16890b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
16900b57cec5SDimitry Andric    : public __tuple_cat_return_1<
16910b57cec5SDimitry Andric                 typename __tuple_cat_type<
16920b57cec5SDimitry Andric                     tuple<_Types...>,
1693bdd1243dSDimitry Andric                     typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
16940b57cec5SDimitry Andric                 >::type,
1695bdd1243dSDimitry Andric                 __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value,
16960b57cec5SDimitry Andric                 _Tuple1, _Tuples...>
16970b57cec5SDimitry Andric{
16980b57cec5SDimitry Andric};
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andrictemplate <class ..._Tuples> struct __tuple_cat_return;
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
17030b57cec5SDimitry Andricstruct __tuple_cat_return<_Tuple0, _Tuples...>
17040b57cec5SDimitry Andric    : public __tuple_cat_return_1<tuple<>,
1705bdd1243dSDimitry Andric         __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value, _Tuple0,
17060b57cec5SDimitry Andric                                                                     _Tuples...>
17070b57cec5SDimitry Andric{
17080b57cec5SDimitry Andric};
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andrictemplate <>
17110b57cec5SDimitry Andricstruct __tuple_cat_return<>
17120b57cec5SDimitry Andric{
1713349cc55cSDimitry Andric    typedef _LIBCPP_NODEBUG tuple<> type;
17140b57cec5SDimitry Andric};
17150b57cec5SDimitry Andric
1716bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17170b57cec5SDimitry Andrictuple<>
17180b57cec5SDimitry Andrictuple_cat()
17190b57cec5SDimitry Andric{
17200b57cec5SDimitry Andric    return tuple<>();
17210b57cec5SDimitry Andric}
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andrictemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
17240b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp;
17250b57cec5SDimitry Andric
17260b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0>
17270b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
17280b57cec5SDimitry Andric{
1729bdd1243dSDimitry Andric    typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1730*06c3fb27SDimitry Andric    typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type;
17310b57cec5SDimitry Andric};
17320b57cec5SDimitry Andric
17330b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
17340b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
17350b57cec5SDimitry Andric                                  _Tuple0, _Tuple1, _Tuples...>
17360b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<
1737*06c3fb27SDimitry Andric         tuple<_Types..., __apply_cv_t<_Tuple0,
1738*06c3fb27SDimitry Andric                                       typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>,
1739bdd1243dSDimitry Andric         typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
17400b57cec5SDimitry Andric         _Tuple1, _Tuples...>
17410b57cec5SDimitry Andric{
17420b57cec5SDimitry Andric};
17430b57cec5SDimitry Andric
17440b57cec5SDimitry Andrictemplate <class _Tuple0, class ..._Tuples>
17450b57cec5SDimitry Andricstruct __tuple_cat_return_ref
17460b57cec5SDimitry Andric    : public __tuple_cat_return_ref_imp<tuple<>,
17470b57cec5SDimitry Andric               typename __make_tuple_indices<
1748bdd1243dSDimitry Andric                        tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value
17490b57cec5SDimitry Andric               >::type, _Tuple0, _Tuples...>
17500b57cec5SDimitry Andric{
17510b57cec5SDimitry Andric};
17520b57cec5SDimitry Andric
17530b57cec5SDimitry Andrictemplate <class _Types, class _I0, class _J0>
17540b57cec5SDimitry Andricstruct __tuple_cat;
17550b57cec5SDimitry Andric
17560b57cec5SDimitry Andrictemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
17570b57cec5SDimitry Andricstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
17580b57cec5SDimitry Andric{
17590b57cec5SDimitry Andric    template <class _Tuple0>
1760bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17610b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
17620b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
17630b57cec5SDimitry Andric    {
176481ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1765480093f4SDimitry Andric        return _VSTD::forward_as_tuple(
1766480093f4SDimitry Andric            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
17670b57cec5SDimitry Andric            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
17680b57cec5SDimitry Andric    }
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andric    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1771bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17720b57cec5SDimitry Andric    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
17730b57cec5SDimitry Andric    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
17740b57cec5SDimitry Andric    {
177581ad6265SDimitry Andric        (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1776bdd1243dSDimitry Andric        typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1777bdd1243dSDimitry Andric        typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1;
1778*06c3fb27SDimitry Andric        return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>,
1779*06c3fb27SDimitry Andric                           typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type,
1780480093f4SDimitry Andric                           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1781480093f4SDimitry Andric            _VSTD::forward_as_tuple(
17820b57cec5SDimitry Andric                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1783480093f4SDimitry Andric                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1784480093f4SDimitry Andric            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
17850b57cec5SDimitry Andric    }
17860b57cec5SDimitry Andric};
17870b57cec5SDimitry Andric
17880b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples>
1789bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
17900b57cec5SDimitry Andrictypename __tuple_cat_return<_Tuple0, _Tuples...>::type
17910b57cec5SDimitry Andrictuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
17920b57cec5SDimitry Andric{
1793bdd1243dSDimitry Andric    typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
17940b57cec5SDimitry Andric    return __tuple_cat<tuple<>, __tuple_indices<>,
17950b57cec5SDimitry Andric                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
17960b57cec5SDimitry Andric                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
17970b57cec5SDimitry Andric                                            _VSTD::forward<_Tuples>(__tpls)...);
17980b57cec5SDimitry Andric}
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andrictemplate <class ..._Tp, class _Alloc>
18010b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
18020b57cec5SDimitry Andric    : true_type {};
18030b57cec5SDimitry Andric
18040b57cec5SDimitry Andrictemplate <class _T1, class _T2>
18050b57cec5SDimitry Andrictemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1806bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
18070b57cec5SDimitry Andricpair<_T1, _T2>::pair(piecewise_construct_t,
18080b57cec5SDimitry Andric                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
18090b57cec5SDimitry Andric                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
18100b57cec5SDimitry Andric    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
18110b57cec5SDimitry Andric      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
18120b57cec5SDimitry Andric{
18130b57cec5SDimitry Andric}
18140b57cec5SDimitry Andric
1815*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
18160b57cec5SDimitry Andrictemplate <class _Tp>
1817349cc55cSDimitry Andricinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
18180b57cec5SDimitry Andric
18190b57cec5SDimitry Andric#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple, size_t ..._Id>
18220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18230b57cec5SDimitry Andricconstexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
18240b57cec5SDimitry Andric                                            __tuple_indices<_Id...>)
18250b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
182681ad6265SDimitry Andric    _VSTD::__invoke(
18270b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f),
18280b57cec5SDimitry Andric        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
18290b57cec5SDimitry Andric)
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple>
18320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18330b57cec5SDimitry Andricconstexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
18340b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18350b57cec5SDimitry Andric    _VSTD::__apply_tuple_impl(
18360b57cec5SDimitry Andric        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
18370b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18380b57cec5SDimitry Andric)
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx>
18410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18420b57cec5SDimitry Andricconstexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
18430b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18440b57cec5SDimitry Andric    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
18450b57cec5SDimitry Andric)
18460b57cec5SDimitry Andric
18470b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple>
18480b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18490b57cec5SDimitry Andricconstexpr _Tp make_from_tuple(_Tuple&& __t)
18500b57cec5SDimitry Andric_LIBCPP_NOEXCEPT_RETURN(
18510b57cec5SDimitry Andric    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
18520b57cec5SDimitry Andric        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
18530b57cec5SDimitry Andric)
18540b57cec5SDimitry Andric
18550b57cec5SDimitry Andric#undef _LIBCPP_NOEXCEPT_RETURN
18560b57cec5SDimitry Andric
1857*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 17
18580b57cec5SDimitry Andric
18590b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
18600b57cec5SDimitry Andric
18610b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
18620b57cec5SDimitry Andric
1863*06c3fb27SDimitry Andric_LIBCPP_POP_MACROS
1864*06c3fb27SDimitry Andric
1865bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1866bdd1243dSDimitry Andric#  include <exception>
1867bdd1243dSDimitry Andric#  include <iosfwd>
1868bdd1243dSDimitry Andric#  include <new>
1869bdd1243dSDimitry Andric#  include <type_traits>
1870bdd1243dSDimitry Andric#  include <typeinfo>
1871bdd1243dSDimitry Andric#  include <utility>
1872bdd1243dSDimitry Andric#endif
1873bdd1243dSDimitry Andric
18740b57cec5SDimitry Andric#endif // _LIBCPP_TUPLE
1875