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 135f757f3fSDimitry Andric// clang-format off 145f757f3fSDimitry Andric 150b57cec5SDimitry Andric/* 160b57cec5SDimitry Andric tuple synopsis 170b57cec5SDimitry Andric 180b57cec5SDimitry Andricnamespace std 190b57cec5SDimitry Andric{ 200b57cec5SDimitry Andric 210b57cec5SDimitry Andrictemplate <class... T> 220b57cec5SDimitry Andricclass tuple { 230b57cec5SDimitry Andricpublic: 24e40139ffSDimitry Andric explicit(see-below) constexpr tuple(); 25e40139ffSDimitry Andric explicit(see-below) tuple(const T&...); // constexpr in C++14 260b57cec5SDimitry Andric template <class... U> 27e40139ffSDimitry Andric explicit(see-below) tuple(U&&...); // constexpr in C++14 280b57cec5SDimitry Andric tuple(const tuple&) = default; 290b57cec5SDimitry Andric tuple(tuple&&) = default; 3081ad6265SDimitry Andric 3181ad6265SDimitry Andric template<class... UTypes> 3281ad6265SDimitry Andric constexpr explicit(see-below) tuple(tuple<UTypes...>&); // C++23 330b57cec5SDimitry Andric template <class... U> 34e40139ffSDimitry Andric explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14 350b57cec5SDimitry Andric template <class... U> 36e40139ffSDimitry Andric explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14 3781ad6265SDimitry Andric template<class... UTypes> 3881ad6265SDimitry Andric constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23 3981ad6265SDimitry Andric 4081ad6265SDimitry Andric template<class U1, class U2> 4181ad6265SDimitry Andric constexpr explicit(see-below) tuple(pair<U1, U2>&); // iff sizeof...(Types) == 2 // C++23 420b57cec5SDimitry Andric template <class U1, class U2> 43e40139ffSDimitry Andric explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14 440b57cec5SDimitry Andric template <class U1, class U2> 45e40139ffSDimitry Andric explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14 4681ad6265SDimitry Andric template<class U1, class U2> 4781ad6265SDimitry Andric constexpr explicit(see-below) tuple(const pair<U1, U2>&&); // iff sizeof...(Types) == 2 // C++23 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // allocator-extended constructors 500b57cec5SDimitry Andric template <class Alloc> 510b57cec5SDimitry Andric tuple(allocator_arg_t, const Alloc& a); 520b57cec5SDimitry Andric template <class Alloc> 53fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20 540b57cec5SDimitry Andric template <class Alloc, class... U> 55fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20 560b57cec5SDimitry Andric template <class Alloc> 57fe6060f1SDimitry Andric tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20 580b57cec5SDimitry Andric template <class Alloc> 59fe6060f1SDimitry Andric tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20 6081ad6265SDimitry Andric template<class Alloc, class... UTypes> 6181ad6265SDimitry Andric constexpr explicit(see-below) 6281ad6265SDimitry Andric tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&); // C++23 630b57cec5SDimitry Andric template <class Alloc, class... U> 64fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20 650b57cec5SDimitry Andric template <class Alloc, class... U> 66fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20 6781ad6265SDimitry Andric template<class Alloc, class... UTypes> 6881ad6265SDimitry Andric constexpr explicit(see-below) 6981ad6265SDimitry Andric tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&); // C++23 7081ad6265SDimitry Andric template<class Alloc, class U1, class U2> 7181ad6265SDimitry Andric constexpr explicit(see-below) 7281ad6265SDimitry Andric tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); // C++23 730b57cec5SDimitry Andric template <class Alloc, class U1, class U2> 74fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20 750b57cec5SDimitry Andric template <class Alloc, class U1, class U2> 76fe6060f1SDimitry Andric explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20 7781ad6265SDimitry Andric template<class Alloc, class U1, class U2> 7881ad6265SDimitry Andric constexpr explicit(see-below) 7981ad6265SDimitry Andric tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&); // C++23 800b57cec5SDimitry Andric 81fe6060f1SDimitry Andric tuple& operator=(const tuple&); // constexpr in C++20 8281ad6265SDimitry Andric constexpr const tuple& operator=(const tuple&) const; // C++23 83fe6060f1SDimitry Andric tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20 8481ad6265SDimitry Andric constexpr const tuple& operator=(tuple&&) const; // C++23 850b57cec5SDimitry Andric template <class... U> 86fe6060f1SDimitry Andric tuple& operator=(const tuple<U...>&); // constexpr in C++20 8781ad6265SDimitry Andric template<class... UTypes> 8881ad6265SDimitry Andric constexpr const tuple& operator=(const tuple<UTypes...>&) const; // C++23 890b57cec5SDimitry Andric template <class... U> 90fe6060f1SDimitry Andric tuple& operator=(tuple<U...>&&); // constexpr in C++20 9181ad6265SDimitry Andric template<class... UTypes> 9281ad6265SDimitry Andric constexpr const tuple& operator=(tuple<UTypes...>&&) const; // C++23 930b57cec5SDimitry Andric template <class U1, class U2> 94fe6060f1SDimitry Andric tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20 950b57cec5SDimitry Andric template<class U1, class U2> 9681ad6265SDimitry Andric constexpr const tuple& operator=(const pair<U1, U2>&) const; // iff sizeof...(Types) == 2 // C++23 9781ad6265SDimitry Andric template <class U1, class U2> 98fe6060f1SDimitry Andric tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20 9981ad6265SDimitry Andric template<class U1, class U2> 10081ad6265SDimitry Andric constexpr const tuple& operator=(pair<U1, U2>&&) const; // iff sizeof...(Types) == 2 // C++23 1010b57cec5SDimitry Andric 102fe6060f1SDimitry Andric template<class U, size_t N> 103fe6060f1SDimitry Andric tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION 104fe6060f1SDimitry Andric template<class U, size_t N> 105fe6060f1SDimitry Andric tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION 106fe6060f1SDimitry Andric 107fe6060f1SDimitry Andric void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20 10881ad6265SDimitry Andric constexpr void swap(const tuple&) const noexcept(see-below); // C++23 1090b57cec5SDimitry Andric}; 1100b57cec5SDimitry Andric 11104eeddc0SDimitry Andric 11204eeddc0SDimitry Andrictemplate<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23 11304eeddc0SDimitry Andric requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; } 11404eeddc0SDimitry Andricstruct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> { 11504eeddc0SDimitry Andric using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; 11604eeddc0SDimitry Andric}; 11704eeddc0SDimitry Andric 11804eeddc0SDimitry Andrictemplate<class... TTypes, class... UTypes> // since C++23 11904eeddc0SDimitry Andric requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; } 12004eeddc0SDimitry Andricstruct common_type<tuple<TTypes...>, tuple<UTypes...>> { 12104eeddc0SDimitry Andric using type = tuple<common_type_t<TTypes, UTypes>...>; 12204eeddc0SDimitry Andric}; 12304eeddc0SDimitry Andric 124e40139ffSDimitry Andrictemplate <class ...T> 125e40139ffSDimitry Andrictuple(T...) -> tuple<T...>; // since C++17 126e40139ffSDimitry Andrictemplate <class T1, class T2> 127e40139ffSDimitry Andrictuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17 128e40139ffSDimitry Andrictemplate <class Alloc, class ...T> 129e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17 130e40139ffSDimitry Andrictemplate <class Alloc, class T1, class T2> 131e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17 132e40139ffSDimitry Andrictemplate <class Alloc, class ...T> 133e40139ffSDimitry Andrictuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17 134e40139ffSDimitry Andric 1350b57cec5SDimitry Andricinline constexpr unspecified ignore; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andrictemplate <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 1380b57cec5SDimitry Andrictemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 1390b57cec5SDimitry Andrictemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 1400b57cec5SDimitry Andrictemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric// [tuple.apply], calling a function with a tuple of arguments: 1430b57cec5SDimitry Andrictemplate <class F, class Tuple> 1440b57cec5SDimitry Andric constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 1450b57cec5SDimitry Andrictemplate <class T, class Tuple> 1460b57cec5SDimitry Andric constexpr T make_from_tuple(Tuple&& t); // C++17 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric// 20.4.1.4, tuple helper classes: 1490b57cec5SDimitry Andrictemplate <class T> struct tuple_size; // undefined 1500b57cec5SDimitry Andrictemplate <class... T> struct tuple_size<tuple<T...>>; 1510b57cec5SDimitry Andrictemplate <class T> 1520b57cec5SDimitry Andric inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 1530b57cec5SDimitry Andrictemplate <size_t I, class T> struct tuple_element; // undefined 1540b57cec5SDimitry Andrictemplate <size_t I, class... T> struct tuple_element<I, tuple<T...>>; 1550b57cec5SDimitry Andrictemplate <size_t I, class T> 1560b57cec5SDimitry Andric using tuple_element_t = typename tuple_element <I, T>::type; // C++14 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric// 20.4.1.5, element access: 1590b57cec5SDimitry Andrictemplate <size_t I, class... T> 1600b57cec5SDimitry Andric typename tuple_element<I, tuple<T...>>::type& 1610b57cec5SDimitry Andric get(tuple<T...>&) noexcept; // constexpr in C++14 1620b57cec5SDimitry Andrictemplate <size_t I, class... T> 1630b57cec5SDimitry Andric const typename tuple_element<I, tuple<T...>>::type& 1640b57cec5SDimitry Andric get(const tuple<T...>&) noexcept; // constexpr in C++14 1650b57cec5SDimitry Andrictemplate <size_t I, class... T> 1660b57cec5SDimitry Andric typename tuple_element<I, tuple<T...>>::type&& 1670b57cec5SDimitry Andric get(tuple<T...>&&) noexcept; // constexpr in C++14 1680b57cec5SDimitry Andrictemplate <size_t I, class... T> 1690b57cec5SDimitry Andric const typename tuple_element<I, tuple<T...>>::type&& 1700b57cec5SDimitry Andric get(const tuple<T...>&&) noexcept; // constexpr in C++14 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andrictemplate <class T1, class... T> 1730b57cec5SDimitry Andric constexpr T1& get(tuple<T...>&) noexcept; // C++14 1740b57cec5SDimitry Andrictemplate <class T1, class... T> 1750b57cec5SDimitry Andric constexpr const T1& get(const tuple<T...>&) noexcept; // C++14 1760b57cec5SDimitry Andrictemplate <class T1, class... T> 1770b57cec5SDimitry Andric constexpr T1&& get(tuple<T...>&&) noexcept; // C++14 1780b57cec5SDimitry Andrictemplate <class T1, class... T> 1790b57cec5SDimitry Andric constexpr const T1&& get(const tuple<T...>&&) noexcept; // C++14 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric// 20.4.1.6, relational operators: 1820b57cec5SDimitry Andrictemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 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> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 187349cc55cSDimitry Andrictemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 188349cc55cSDimitry Andrictemplate<class... T, class... U> 189349cc55cSDimitry Andric constexpr common_comparison_category_t<synth-three-way-result<T, U>...> 190349cc55cSDimitry Andric operator<=>(const tuple<T...>&, const tuple<U...>&); // since C++20 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andrictemplate <class... Types, class Alloc> 1930b57cec5SDimitry Andric struct uses_allocator<tuple<Types...>, Alloc>; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andrictemplate <class... Types> 1960b57cec5SDimitry Andric void 1970b57cec5SDimitry Andric swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y))); 1980b57cec5SDimitry Andric 19981ad6265SDimitry Andrictemplate <class... Types> 20081ad6265SDimitry Andric constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below); // C++23 20181ad6265SDimitry Andric 2020b57cec5SDimitry Andric} // std 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric*/ 2050b57cec5SDimitry Andric 2065f757f3fSDimitry Andric// clang-format on 2075f757f3fSDimitry Andric 20881ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 209349cc55cSDimitry Andric#include <__compare/common_comparison_category.h> 210349cc55cSDimitry Andric#include <__compare/synth_three_way.h> 2110b57cec5SDimitry Andric#include <__config> 212bdd1243dSDimitry Andric#include <__functional/invoke.h> 213bdd1243dSDimitry Andric#include <__fwd/array.h> 21406c3fb27SDimitry Andric#include <__fwd/get.h> 21506c3fb27SDimitry Andric#include <__fwd/tuple.h> 216fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h> 217fe6060f1SDimitry Andric#include <__memory/uses_allocator.h> 21806c3fb27SDimitry Andric#include <__tuple/make_tuple_types.h> 21906c3fb27SDimitry Andric#include <__tuple/sfinae_helpers.h> 22006c3fb27SDimitry Andric#include <__tuple/tuple_element.h> 22106c3fb27SDimitry Andric#include <__tuple/tuple_indices.h> 22206c3fb27SDimitry Andric#include <__tuple/tuple_like_ext.h> 22306c3fb27SDimitry Andric#include <__tuple/tuple_size.h> 22406c3fb27SDimitry Andric#include <__tuple/tuple_types.h> 225bdd1243dSDimitry Andric#include <__type_traits/apply_cv.h> 226bdd1243dSDimitry Andric#include <__type_traits/common_reference.h> 227bdd1243dSDimitry Andric#include <__type_traits/common_type.h> 228bdd1243dSDimitry Andric#include <__type_traits/conditional.h> 229bdd1243dSDimitry Andric#include <__type_traits/conjunction.h> 230bdd1243dSDimitry Andric#include <__type_traits/copy_cvref.h> 231bdd1243dSDimitry Andric#include <__type_traits/disjunction.h> 232bdd1243dSDimitry Andric#include <__type_traits/is_arithmetic.h> 233bdd1243dSDimitry Andric#include <__type_traits/is_assignable.h> 234bdd1243dSDimitry Andric#include <__type_traits/is_constructible.h> 235bdd1243dSDimitry Andric#include <__type_traits/is_convertible.h> 236bdd1243dSDimitry Andric#include <__type_traits/is_copy_assignable.h> 237bdd1243dSDimitry Andric#include <__type_traits/is_copy_constructible.h> 238bdd1243dSDimitry Andric#include <__type_traits/is_default_constructible.h> 239bdd1243dSDimitry Andric#include <__type_traits/is_empty.h> 240bdd1243dSDimitry Andric#include <__type_traits/is_final.h> 241bdd1243dSDimitry Andric#include <__type_traits/is_implicitly_default_constructible.h> 242bdd1243dSDimitry Andric#include <__type_traits/is_move_assignable.h> 243bdd1243dSDimitry Andric#include <__type_traits/is_move_constructible.h> 244bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_assignable.h> 245bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_constructible.h> 246bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_assignable.h> 247bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_copy_constructible.h> 248bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_default_constructible.h> 249bdd1243dSDimitry Andric#include <__type_traits/is_nothrow_move_assignable.h> 250bdd1243dSDimitry Andric#include <__type_traits/is_reference.h> 251bdd1243dSDimitry Andric#include <__type_traits/is_same.h> 252bdd1243dSDimitry Andric#include <__type_traits/is_swappable.h> 253bdd1243dSDimitry Andric#include <__type_traits/lazy.h> 254bdd1243dSDimitry Andric#include <__type_traits/maybe_const.h> 255bdd1243dSDimitry Andric#include <__type_traits/nat.h> 256bdd1243dSDimitry Andric#include <__type_traits/negation.h> 257bdd1243dSDimitry Andric#include <__type_traits/remove_cvref.h> 258bdd1243dSDimitry Andric#include <__type_traits/remove_reference.h> 25906c3fb27SDimitry Andric#include <__type_traits/unwrap_ref.h> 260fe6060f1SDimitry Andric#include <__utility/forward.h> 261349cc55cSDimitry Andric#include <__utility/integer_sequence.h> 262fe6060f1SDimitry Andric#include <__utility/move.h> 26381ad6265SDimitry Andric#include <__utility/pair.h> 26481ad6265SDimitry Andric#include <__utility/piecewise_construct.h> 26581ad6265SDimitry Andric#include <__utility/swap.h> 2660b57cec5SDimitry Andric#include <cstddef> 2670b57cec5SDimitry Andric#include <version> 2680b57cec5SDimitry Andric 26981ad6265SDimitry Andric// standard-mandated includes 270bdd1243dSDimitry Andric 271bdd1243dSDimitry Andric// [tuple.syn] 27281ad6265SDimitry Andric#include <compare> 27381ad6265SDimitry Andric 2740b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2750b57cec5SDimitry Andric# pragma GCC system_header 2760b57cec5SDimitry Andric#endif 2770b57cec5SDimitry Andric 27806c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS 27906c3fb27SDimitry Andric#include <__undef_macros> 28006c3fb27SDimitry Andric 2810b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric// __tuple_leaf 2860b57cec5SDimitry Andric 287cb14a3feSDimitry Andrictemplate <size_t _Ip, class _Hp, bool = is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value > 2880b57cec5SDimitry Andricclass __tuple_leaf; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep> 291cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void 292cb14a3feSDimitry Andricswap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) 293cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) { 2940b57cec5SDimitry Andric swap(__x.get(), __y.get()); 2950b57cec5SDimitry Andric} 2960b57cec5SDimitry Andric 29781ad6265SDimitry Andrictemplate <size_t _Ip, class _Hp, bool _Ep> 298cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void 299cb14a3feSDimitry Andricswap(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> 305cb14a3feSDimitry Andricclass __tuple_leaf { 3060b57cec5SDimitry Andric _Hp __value_; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric template <class _Tp> 30906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { 3100b57cec5SDimitry Andric# if __has_keyword(__reference_binds_to_temporary) 3110b57cec5SDimitry Andric return !__reference_binds_to_temporary(_Hp, _Tp); 3120b57cec5SDimitry Andric# else 3130b57cec5SDimitry Andric return true; 3140b57cec5SDimitry Andric# endif 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 317cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_leaf& operator=(const __tuple_leaf&); 318cb14a3feSDimitry Andric 3190b57cec5SDimitry Andricpublic: 320cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf() _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_() { 321cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple"); 322cb14a3feSDimitry Andric } 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric template <class _Alloc> 325cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 0>, const _Alloc&) : __value_() { 326cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple"); 327cb14a3feSDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric template <class _Alloc> 330cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 331cb14a3feSDimitry Andric : __value_(allocator_arg_t(), __a) { 332cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple"); 333cb14a3feSDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric template <class _Alloc> 336cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) : __value_(__a) { 337cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple"); 338cb14a3feSDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric template <class _Tp, 341349cc55cSDimitry Andric class = __enable_if_t< 342cb14a3feSDimitry Andric _And< _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>, is_constructible<_Hp, _Tp> >::value > > 343cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_leaf(_Tp&& __t) 344cb14a3feSDimitry Andric _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) 345cb14a3feSDimitry Andric : __value_(std::forward<_Tp>(__t)) { 346cb14a3feSDimitry Andric static_assert(__can_bind_reference<_Tp&&>(), 347cb14a3feSDimitry Andric "Attempted construction of reference element binds to a temporary whose lifetime has ended"); 348cb14a3feSDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric template <class _Tp, class _Alloc> 351cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_leaf( 352cb14a3feSDimitry Andric integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 353cb14a3feSDimitry Andric : __value_(std::forward<_Tp>(__t)) { 354cb14a3feSDimitry Andric static_assert(__can_bind_reference<_Tp&&>(), 355cb14a3feSDimitry Andric "Attempted construction of reference element binds to a temporary whose lifetime has ended"); 356cb14a3feSDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric template <class _Tp, class _Alloc> 359cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_leaf( 360cb14a3feSDimitry Andric integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 361cb14a3feSDimitry Andric : __value_(allocator_arg_t(), __a, std::forward<_Tp>(__t)) { 362cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to uses-allocator construct a reference element in a tuple"); 363cb14a3feSDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric template <class _Tp, class _Alloc> 366cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_leaf( 367cb14a3feSDimitry Andric integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 368cb14a3feSDimitry Andric : __value_(std::forward<_Tp>(__t), __a) { 369cb14a3feSDimitry Andric static_assert(!is_reference<_Hp>::value, "Attempted to uses-allocator construct a reference element in a tuple"); 370cb14a3feSDimitry Andric } 3710b57cec5SDimitry Andric 37206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default; 37306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default; 3740b57cec5SDimitry Andric 375cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int swap(__tuple_leaf& __t) 376cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) { 3775f757f3fSDimitry Andric std::swap(*this, __t); 3780b57cec5SDimitry Andric return 0; 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 381cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int swap(const __tuple_leaf& __t) const 382cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) { 3835f757f3fSDimitry Andric std::swap(*this, __t); 38481ad6265SDimitry Andric return 0; 38581ad6265SDimitry Andric } 38681ad6265SDimitry Andric 3875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Hp& get() _NOEXCEPT { return __value_; } 3885f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT { return __value_; } 3890b57cec5SDimitry Andric}; 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andrictemplate <size_t _Ip, class _Hp> 392cb14a3feSDimitry Andricclass __tuple_leaf<_Ip, _Hp, true> : private _Hp { 393cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_leaf& operator=(const __tuple_leaf&); 394cb14a3feSDimitry Andric 3950b57cec5SDimitry Andricpublic: 396cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf() _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {} 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric template <class _Alloc> 399cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric template <class _Alloc> 402cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 4030b57cec5SDimitry Andric : _Hp(allocator_arg_t(), __a) {} 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric template <class _Alloc> 406cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) : _Hp(__a) {} 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric template <class _Tp, 409349cc55cSDimitry Andric class = __enable_if_t< 410cb14a3feSDimitry Andric _And< _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>, is_constructible<_Hp, _Tp> >::value > > 411cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_leaf(_Tp&& __t) 412cb14a3feSDimitry Andric _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) 4135f757f3fSDimitry Andric : _Hp(std::forward<_Tp>(__t)) {} 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric template <class _Tp, class _Alloc> 416cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 4175f757f3fSDimitry Andric : _Hp(std::forward<_Tp>(__t)) {} 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric template <class _Tp, class _Alloc> 420cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 4215f757f3fSDimitry Andric : _Hp(allocator_arg_t(), __a, std::forward<_Tp>(__t)) {} 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric template <class _Tp, class _Alloc> 424cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 4255f757f3fSDimitry Andric : _Hp(std::forward<_Tp>(__t), __a) {} 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric __tuple_leaf(__tuple_leaf const&) = default; 4280b57cec5SDimitry Andric __tuple_leaf(__tuple_leaf&&) = default; 4290b57cec5SDimitry Andric 430cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int swap(__tuple_leaf& __t) 431cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) { 4325f757f3fSDimitry Andric std::swap(*this, __t); 4330b57cec5SDimitry Andric return 0; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 436cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int swap(const __tuple_leaf& __rhs) const 437cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) { 4385f757f3fSDimitry Andric std::swap(*this, __rhs); 43981ad6265SDimitry Andric return 0; 44081ad6265SDimitry Andric } 44181ad6265SDimitry Andric 4425f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Hp& get() _NOEXCEPT { return static_cast<_Hp&>(*this); } 443cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT { 444cb14a3feSDimitry Andric return static_cast<const _Hp&>(*this); 445cb14a3feSDimitry Andric } 4460b57cec5SDimitry Andric}; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andrictemplate <class... _Tp> 449cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swallow(_Tp&&...) _NOEXCEPT {} 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andrictemplate <class _Tp> 4520b57cec5SDimitry Andricstruct __all_default_constructible; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andrictemplate <class... _Tp> 455cb14a3feSDimitry Andricstruct __all_default_constructible<__tuple_types<_Tp...>> : __all<is_default_constructible<_Tp>::value...> {}; 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric// __tuple_impl 4580b57cec5SDimitry Andric 459cb14a3feSDimitry Andrictemplate <class _Indx, class... _Tp> 460cb14a3feSDimitry Andricstruct __tuple_impl; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andrictemplate <size_t... _Indx, class... _Tp> 4630b57cec5SDimitry Andricstruct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...> 464cb14a3feSDimitry Andric : public __tuple_leaf<_Indx, _Tp>... { 465cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __tuple_impl() 4660b57cec5SDimitry Andric _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} 4670b57cec5SDimitry Andric 468cb14a3feSDimitry Andric template <size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up> 469cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl( 470cb14a3feSDimitry Andric __tuple_indices<_Uf...>, __tuple_types<_Tf...>, __tuple_indices<_Ul...>, __tuple_types<_Tl...>, _Up&&... __u) 4710b57cec5SDimitry Andric _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value && 472cb14a3feSDimitry Andric __all<is_nothrow_default_constructible<_Tl>::value...>::value)) 473cb14a3feSDimitry Andric : __tuple_leaf<_Uf, _Tf>(std::forward<_Up>(__u))..., __tuple_leaf<_Ul, _Tl>()... {} 4740b57cec5SDimitry Andric 475cb14a3feSDimitry Andric template <class _Alloc, size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up> 476cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl( 477cb14a3feSDimitry Andric allocator_arg_t, 478cb14a3feSDimitry Andric const _Alloc& __a, 479cb14a3feSDimitry Andric __tuple_indices<_Uf...>, 480cb14a3feSDimitry Andric __tuple_types<_Tf...>, 481cb14a3feSDimitry Andric __tuple_indices<_Ul...>, 482cb14a3feSDimitry Andric __tuple_types<_Tl...>, 483cb14a3feSDimitry Andric _Up&&... __u) 484cb14a3feSDimitry Andric : __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, std::forward<_Up>(__u))..., 485cb14a3feSDimitry Andric __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... {} 4860b57cec5SDimitry Andric 487cb14a3feSDimitry Andric template <class _Tuple, class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value> > 488cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(_Tuple&& __t) _NOEXCEPT_( 489cb14a3feSDimitry Andric (__all<is_nothrow_constructible< 490cb14a3feSDimitry Andric _Tp, 491cb14a3feSDimitry Andric typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>::value...>::value)) 492cb14a3feSDimitry Andric : __tuple_leaf<_Indx, _Tp>( 493cb14a3feSDimitry Andric std::forward<typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>( 494cb14a3feSDimitry Andric std::get<_Indx>(__t)))... {} 4950b57cec5SDimitry Andric 496cb14a3feSDimitry Andric template <class _Alloc, class _Tuple, class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value> > 497cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) 498cb14a3feSDimitry Andric : __tuple_leaf<_Indx, _Tp>( 499cb14a3feSDimitry Andric __uses_alloc_ctor<_Tp, 500cb14a3feSDimitry Andric _Alloc, 501cb14a3feSDimitry Andric typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>(), 502cb14a3feSDimitry Andric __a, 503cb14a3feSDimitry Andric std::forward<typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>( 504cb14a3feSDimitry Andric std::get<_Indx>(__t)))... {} 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric __tuple_impl(const __tuple_impl&) = default; 5070b57cec5SDimitry Andric __tuple_impl(__tuple_impl&&) = default; 5080b57cec5SDimitry Andric 509cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void swap(__tuple_impl& __t) 510cb14a3feSDimitry Andric _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) { 5115f757f3fSDimitry Andric std::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); 5120b57cec5SDimitry Andric } 51381ad6265SDimitry Andric 514cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void swap(const __tuple_impl& __t) const 515cb14a3feSDimitry Andric _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value) { 5165f757f3fSDimitry Andric std::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...); 51781ad6265SDimitry Andric } 5180b57cec5SDimitry Andric}; 5190b57cec5SDimitry Andric 520fe6060f1SDimitry Andrictemplate <class _Dest, class _Source, size_t... _Np> 521cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void 522cb14a3feSDimitry Andric__memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) { 5235f757f3fSDimitry Andric std::__swallow(((std::get<_Np>(__dest) = std::get<_Np>(__source)), void(), 0)...); 524fe6060f1SDimitry Andric} 5250b57cec5SDimitry Andric 526fe6060f1SDimitry Andrictemplate <class _Dest, class _Source, class... _Up, size_t... _Np> 527cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void 528cb14a3feSDimitry Andric__memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) { 529cb14a3feSDimitry Andric std::__swallow(((std::get<_Np>(__dest) = std::forward<_Up>(std::get<_Np>(__source))), void(), 0)...); 530fe6060f1SDimitry Andric} 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andrictemplate <class... _Tp> 533cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple { 5340b57cec5SDimitry Andric typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT; 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric _BaseT __base_; 5370b57cec5SDimitry Andric 538cb14a3feSDimitry Andric template <size_t _Jp, class... _Up> 539cb14a3feSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; 540cb14a3feSDimitry Andric template <size_t _Jp, class... _Up> 541cb14a3feSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Jp, tuple<_Up...> >::type& 542cb14a3feSDimitry Andric get(const tuple<_Up...>&) _NOEXCEPT; 543cb14a3feSDimitry Andric template <size_t _Jp, class... _Up> 544cb14a3feSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Jp, tuple<_Up...> >::type&& 545cb14a3feSDimitry Andric get(tuple<_Up...>&&) _NOEXCEPT; 546cb14a3feSDimitry Andric template <size_t _Jp, class... _Up> 547cb14a3feSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Jp, tuple<_Up...> >::type&& 548cb14a3feSDimitry Andric get(const tuple<_Up...>&&) _NOEXCEPT; 549cb14a3feSDimitry Andric 5500b57cec5SDimitry Andricpublic: 551fe6060f1SDimitry Andric // [tuple.cnstr] 5520b57cec5SDimitry Andric 5535f757f3fSDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 5545f757f3fSDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions") 5555f757f3fSDimitry Andric _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions") 556e40139ffSDimitry Andric 5575f757f3fSDimitry Andric // tuple() constructors (including allocator_arg_t variants) 558fe6060f1SDimitry Andric template <template <class...> class _IsImpDefault = __is_implicitly_default_constructible, 559cb14a3feSDimitry Andric template <class...> class _IsDefault = is_default_constructible, 560cb14a3feSDimitry Andric __enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0> 561cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value) tuple() 562cb14a3feSDimitry Andric _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value) {} 5630b57cec5SDimitry Andric 564fe6060f1SDimitry Andric template <class _Alloc, 565fe6060f1SDimitry Andric template <class...> class _IsImpDefault = __is_implicitly_default_constructible, 566cb14a3feSDimitry Andric template <class...> class _IsDefault = is_default_constructible, 567cb14a3feSDimitry Andric __enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0> 568cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value) 569cb14a3feSDimitry Andric tuple(allocator_arg_t, _Alloc const& __a) 570cb14a3feSDimitry Andric : __base_(allocator_arg_t(), 571cb14a3feSDimitry Andric __a, 572cb14a3feSDimitry Andric __tuple_indices<>(), 573cb14a3feSDimitry Andric __tuple_types<>(), 574fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), 575fe6060f1SDimitry Andric __tuple_types<_Tp...>()) {} 576fe6060f1SDimitry Andric 577fe6060f1SDimitry Andric // tuple(const T&...) constructors (including allocator_arg_t variants) 578cb14a3feSDimitry Andric template <template <class...> class _And = _And, 579cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Tp) >= 1>, is_copy_constructible<_Tp>... >::value, int> = 0> 580cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit( 581cb14a3feSDimitry Andric _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) tuple(const _Tp&... __t) 582fe6060f1SDimitry Andric _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value) 583fe6060f1SDimitry Andric : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), 584fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 585fe6060f1SDimitry Andric typename __make_tuple_indices<0>::type(), 586fe6060f1SDimitry Andric typename __make_tuple_types<tuple, 0>::type(), 587cb14a3feSDimitry Andric __t...) {} 588fe6060f1SDimitry Andric 589cb14a3feSDimitry Andric template <class _Alloc, 590cb14a3feSDimitry Andric template <class...> class _And = _And, 591cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Tp) >= 1>, is_copy_constructible<_Tp>... >::value, int> = 0> 592cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit( 593cb14a3feSDimitry Andric _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) 594cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, const _Tp&... __t) 595cb14a3feSDimitry Andric : __base_(allocator_arg_t(), 596cb14a3feSDimitry Andric __a, 597fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Tp)>::type(), 598fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 599fe6060f1SDimitry Andric typename __make_tuple_indices<0>::type(), 600fe6060f1SDimitry Andric typename __make_tuple_types<tuple, 0>::type(), 601cb14a3feSDimitry Andric __t...) {} 602fe6060f1SDimitry Andric 603fe6060f1SDimitry Andric // tuple(U&& ...) constructors (including allocator_arg_t variants) 604cb14a3feSDimitry Andric template <class... _Up> 605cb14a3feSDimitry Andric struct _IsThisTuple : false_type {}; 606cb14a3feSDimitry Andric template <class _Up> 607cb14a3feSDimitry Andric struct _IsThisTuple<_Up> : is_same<__remove_cvref_t<_Up>, tuple> {}; 608fe6060f1SDimitry Andric 609fe6060f1SDimitry Andric template <class... _Up> 610cb14a3feSDimitry Andric struct _EnableUTypesCtor 611cb14a3feSDimitry Andric : _And< _BoolConstant<sizeof...(_Tp) >= 1>, 612fe6060f1SDimitry Andric _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors 613cb14a3feSDimitry Andric is_constructible<_Tp, _Up>... > {}; 614fe6060f1SDimitry Andric 615cb14a3feSDimitry Andric template <class... _Up, 616cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value, 617cb14a3feSDimitry Andric int> = 0> 618cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) 619cb14a3feSDimitry Andric tuple(_Up&&... __u) _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) 620fe6060f1SDimitry Andric : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), 621fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 622fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 623fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 6245f757f3fSDimitry Andric std::forward<_Up>(__u)...) {} 625fe6060f1SDimitry Andric 626cb14a3feSDimitry Andric template <class _Alloc, 627cb14a3feSDimitry Andric class... _Up, 628cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value, 629cb14a3feSDimitry Andric int> = 0> 630cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) 631cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) 632cb14a3feSDimitry Andric : __base_(allocator_arg_t(), 633cb14a3feSDimitry Andric __a, 634fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Up)>::type(), 635fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 636fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 637fe6060f1SDimitry Andric typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 6385f757f3fSDimitry Andric std::forward<_Up>(__u)...) {} 639fe6060f1SDimitry Andric 640fe6060f1SDimitry Andric // Copy and move constructors (including the allocator_arg_t variants) 641fe6060f1SDimitry Andric tuple(const tuple&) = default; 6420b57cec5SDimitry Andric tuple(tuple&&) = default; 6430b57cec5SDimitry Andric 644cb14a3feSDimitry Andric template <class _Alloc, 645cb14a3feSDimitry Andric template <class...> class _And = _And, 646cb14a3feSDimitry Andric __enable_if_t< _And<is_copy_constructible<_Tp>...>::value, int> = 0> 647cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t) 648cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __alloc, __t) {} 6490b57cec5SDimitry Andric 650cb14a3feSDimitry Andric template <class _Alloc, 651cb14a3feSDimitry Andric template <class...> class _And = _And, 652cb14a3feSDimitry Andric __enable_if_t< _And<is_move_constructible<_Tp>...>::value, int> = 0> 653cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t) 654cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __alloc, std::move(__t)) {} 655e40139ffSDimitry Andric 656fe6060f1SDimitry Andric // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants) 65781ad6265SDimitry Andric 658bdd1243dSDimitry Andric template <class _OtherTuple, class _DecayedOtherTuple = __remove_cvref_t<_OtherTuple>, class = void> 65981ad6265SDimitry Andric struct _EnableCtorFromUTypesTuple : false_type {}; 66081ad6265SDimitry Andric 66181ad6265SDimitry Andric template <class _OtherTuple, class... _Up> 662cb14a3feSDimitry Andric struct _EnableCtorFromUTypesTuple< 663cb14a3feSDimitry Andric _OtherTuple, 664cb14a3feSDimitry Andric tuple<_Up...>, 66581ad6265SDimitry Andric // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below 666cb14a3feSDimitry Andric __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> 667cb14a3feSDimitry Andric : _And< 668cb14a3feSDimitry Andric // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor 669cb14a3feSDimitry Andric // can work. Otherwise, is_constructible can trigger hard error in those cases 670cb14a3feSDimitry Andric // https://godbolt.org/z/M94cGdKcE 67181ad6265SDimitry Andric _Not<is_same<_OtherTuple, const tuple&> >, 67281ad6265SDimitry Andric _Not<is_same<_OtherTuple, tuple&&> >, 67381ad6265SDimitry Andric is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >..., 674cb14a3feSDimitry Andric _Lazy<_Or, 675cb14a3feSDimitry Andric _BoolConstant<sizeof...(_Tp) != 1>, 676fe6060f1SDimitry Andric // _Tp and _Up are 1-element packs - the pack expansions look 677fe6060f1SDimitry Andric // weird to avoid tripping up the type traits in degenerate cases 678fe6060f1SDimitry Andric _Lazy<_And, 67981ad6265SDimitry Andric _Not<is_same<_Tp, _Up> >..., 68081ad6265SDimitry Andric _Not<is_convertible<_OtherTuple, _Tp> >..., 681cb14a3feSDimitry Andric _Not<is_constructible<_Tp, _OtherTuple> >... > > > {}; 6820b57cec5SDimitry Andric 683cb14a3feSDimitry Andric template <class... _Up, __enable_if_t< _And< _EnableCtorFromUTypesTuple<const tuple<_Up...>&> >::value, int> = 0> 684cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit( 685cb14a3feSDimitry Andric _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value) tuple(const tuple<_Up...>& __t) 686fe6060f1SDimitry Andric _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value)) 687cb14a3feSDimitry Andric : __base_(__t) {} 6880b57cec5SDimitry Andric 689cb14a3feSDimitry Andric template <class... _Up, 690cb14a3feSDimitry Andric class _Alloc, 691cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromUTypesTuple<const tuple<_Up...>&> >::value, int> = 0> 692cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit( 693cb14a3feSDimitry Andric _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value) 694cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t) 695cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __a, __t) {} 6960b57cec5SDimitry Andric 69706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 69881ad6265SDimitry Andric // tuple(tuple<U...>&) constructors (including allocator_arg_t variants) 69981ad6265SDimitry Andric 700cb14a3feSDimitry Andric template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr> 701cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value) tuple(tuple<_Up...>& __t) 702cb14a3feSDimitry Andric : __base_(__t) {} 70381ad6265SDimitry Andric 704cb14a3feSDimitry Andric template <class _Alloc, class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr> 705cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value) 706cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) 707cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __alloc, __t) {} 70806c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 70981ad6265SDimitry Andric 710fe6060f1SDimitry Andric // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants) 711cb14a3feSDimitry Andric template <class... _Up, __enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0> 712cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) 713cb14a3feSDimitry Andric tuple(tuple<_Up...>&& __t) _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) 714cb14a3feSDimitry Andric : __base_(std::move(__t)) {} 7150b57cec5SDimitry Andric 716cb14a3feSDimitry Andric template <class _Alloc, 717cb14a3feSDimitry Andric class... _Up, 718cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0> 719cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) 720cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t) 721cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __a, std::move(__t)) {} 722fe6060f1SDimitry Andric 72306c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 72481ad6265SDimitry Andric // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants) 72581ad6265SDimitry Andric 726cb14a3feSDimitry Andric template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr> 727cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value) 728cb14a3feSDimitry Andric tuple(const tuple<_Up...>&& __t) 729cb14a3feSDimitry Andric : __base_(std::move(__t)) {} 73081ad6265SDimitry Andric 731cb14a3feSDimitry Andric template <class _Alloc, 732cb14a3feSDimitry Andric class... _Up, 733cb14a3feSDimitry Andric enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr> 734cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value) 73581ad6265SDimitry Andric tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t) 73681ad6265SDimitry Andric : __base_(allocator_arg_t(), __alloc, std::move(__t)) {} 73706c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 73881ad6265SDimitry Andric 739fe6060f1SDimitry Andric // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants) 74081ad6265SDimitry Andric 741cb14a3feSDimitry Andric template <template <class...> class _Pred, 742cb14a3feSDimitry Andric class _Pair, 743cb14a3feSDimitry Andric class _DecayedPair = __remove_cvref_t<_Pair>, 744cb14a3feSDimitry Andric class _Tuple = tuple> 74581ad6265SDimitry Andric struct _CtorPredicateFromPair : false_type {}; 74681ad6265SDimitry Andric 74706c3fb27SDimitry Andric template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> 748cb14a3feSDimitry Andric struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > 749cb14a3feSDimitry Andric : _And< _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >, _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> > > {}; 750fe6060f1SDimitry Andric 75181ad6265SDimitry Andric template <class _Pair> 75281ad6265SDimitry Andric struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair> {}; 75381ad6265SDimitry Andric 75481ad6265SDimitry Andric template <class _Pair> 75581ad6265SDimitry Andric struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair> {}; 75681ad6265SDimitry Andric 757bdd1243dSDimitry Andric template <class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple> 75881ad6265SDimitry Andric struct _BothImplicitlyConvertible : false_type {}; 75981ad6265SDimitry Andric 76081ad6265SDimitry Andric template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> 761cb14a3feSDimitry Andric struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > 762cb14a3feSDimitry Andric : _And< is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>, is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2> > {}; 763fe6060f1SDimitry Andric 764cb14a3feSDimitry Andric template <class _Up1, 765cb14a3feSDimitry Andric class _Up2, 766cb14a3feSDimitry Andric template <class...> class _And = _And, 767cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromPair<const pair<_Up1, _Up2>&> >::value, int> = 0> 768cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit( 769cb14a3feSDimitry Andric _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value) tuple(const pair<_Up1, _Up2>& __p) 77081ad6265SDimitry Andric _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value)) 771cb14a3feSDimitry Andric : __base_(__p) {} 772fe6060f1SDimitry Andric 773cb14a3feSDimitry Andric template <class _Alloc, 774cb14a3feSDimitry Andric class _Up1, 775cb14a3feSDimitry Andric class _Up2, 776cb14a3feSDimitry Andric template <class...> class _And = _And, 777cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromPair<const pair<_Up1, _Up2>&> >::value, int> = 0> 778cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit( 779cb14a3feSDimitry Andric _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value) 780cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p) 781cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __a, __p) {} 782fe6060f1SDimitry Andric 78306c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 78481ad6265SDimitry Andric // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants) 785fe6060f1SDimitry Andric 786cb14a3feSDimitry Andric template <class _U1, class _U2, enable_if_t< _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr> 787cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value) 788cb14a3feSDimitry Andric tuple(pair<_U1, _U2>& __p) 789cb14a3feSDimitry Andric : __base_(__p) {} 79081ad6265SDimitry Andric 791cb14a3feSDimitry Andric template <class _Alloc, 792cb14a3feSDimitry Andric class _U1, 793cb14a3feSDimitry Andric class _U2, 794cb14a3feSDimitry Andric enable_if_t< _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr> 795cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value) 796cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) 797cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __alloc, __p) {} 79881ad6265SDimitry Andric# endif 79981ad6265SDimitry Andric 80081ad6265SDimitry Andric // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants) 801fe6060f1SDimitry Andric 802cb14a3feSDimitry Andric template <class _Up1, 803cb14a3feSDimitry Andric class _Up2, 804cb14a3feSDimitry Andric template <class...> class _And = _And, 805cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromPair<pair<_Up1, _Up2>&&> >::value, int> = 0> 806cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit( 807cb14a3feSDimitry Andric _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value) tuple(pair<_Up1, _Up2>&& __p) 80881ad6265SDimitry Andric _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value)) 809cb14a3feSDimitry Andric : __base_(std::move(__p)) {} 810fe6060f1SDimitry Andric 811cb14a3feSDimitry Andric template <class _Alloc, 812cb14a3feSDimitry Andric class _Up1, 813cb14a3feSDimitry Andric class _Up2, 814cb14a3feSDimitry Andric template <class...> class _And = _And, 815cb14a3feSDimitry Andric __enable_if_t< _And< _EnableCtorFromPair<pair<_Up1, _Up2>&&> >::value, int> = 0> 816cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit( 817cb14a3feSDimitry Andric _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value) 818cb14a3feSDimitry Andric tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p) 819cb14a3feSDimitry Andric : __base_(allocator_arg_t(), __a, std::move(__p)) {} 820fe6060f1SDimitry Andric 82106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 82281ad6265SDimitry Andric // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants) 82381ad6265SDimitry Andric 824cb14a3feSDimitry Andric template <class _U1, class _U2, enable_if_t< _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr> 825cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value) 826cb14a3feSDimitry Andric tuple(const pair<_U1, _U2>&& __p) 827cb14a3feSDimitry Andric : __base_(std::move(__p)) {} 82881ad6265SDimitry Andric 829cb14a3feSDimitry Andric template <class _Alloc, 830cb14a3feSDimitry Andric class _U1, 831cb14a3feSDimitry Andric class _U2, 832cb14a3feSDimitry Andric enable_if_t< _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr> 833cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value) 83481ad6265SDimitry Andric tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p) 83581ad6265SDimitry Andric : __base_(allocator_arg_t(), __alloc, std::move(__p)) {} 83606c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 83781ad6265SDimitry Andric 8385f757f3fSDimitry Andric _LIBCPP_DIAGNOSTIC_POP 8395f757f3fSDimitry Andric 840fe6060f1SDimitry Andric // [tuple.assign] 841cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& 842cb14a3feSDimitry Andric operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) 843cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value)) { 84481ad6265SDimitry Andric std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type()); 84581ad6265SDimitry Andric return *this; 84681ad6265SDimitry Andric } 84781ad6265SDimitry Andric 848cb14a3feSDimitry Andric# if _LIBCPP_STD_VER >= 23 849cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple const& __tuple) const 850cb14a3feSDimitry Andric requires(_And<is_copy_assignable<const _Tp>...>::value) 851cb14a3feSDimitry Andric { 852cb14a3feSDimitry Andric std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type()); 853cb14a3feSDimitry Andric return *this; 854cb14a3feSDimitry Andric } 855cb14a3feSDimitry Andric 856cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple&& __tuple) const 857cb14a3feSDimitry Andric requires(_And<is_assignable<const _Tp&, _Tp>...>::value) 858cb14a3feSDimitry Andric { 859cb14a3feSDimitry Andric std::__memberwise_forward_assign( 860cb14a3feSDimitry Andric *this, std::move(__tuple), __tuple_types<_Tp...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type()); 86181ad6265SDimitry Andric return *this; 86281ad6265SDimitry Andric } 86306c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 86481ad6265SDimitry Andric 865cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& 866cb14a3feSDimitry Andric operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) 867cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value)) { 868cb14a3feSDimitry Andric std::__memberwise_forward_assign( 869cb14a3feSDimitry Andric *this, std::move(__tuple), __tuple_types<_Tp...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type()); 8700b57cec5SDimitry Andric return *this; 8710b57cec5SDimitry Andric } 8720b57cec5SDimitry Andric 873cb14a3feSDimitry Andric template < 874cb14a3feSDimitry Andric class... _Up, 875cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>, is_assignable<_Tp&, _Up const&>... >::value, 876cb14a3feSDimitry Andric int> = 0> 877cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(tuple<_Up...> const& __tuple) 878cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) { 879cb14a3feSDimitry Andric std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type()); 8800b57cec5SDimitry Andric return *this; 8810b57cec5SDimitry Andric } 8820b57cec5SDimitry Andric 883cb14a3feSDimitry Andric template <class... _Up, 884cb14a3feSDimitry Andric __enable_if_t< _And< _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>, is_assignable<_Tp&, _Up>... >::value, 885cb14a3feSDimitry Andric int> = 0> 886cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(tuple<_Up...>&& __tuple) 887cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) { 888cb14a3feSDimitry Andric std::__memberwise_forward_assign( 889cb14a3feSDimitry Andric *this, std::move(__tuple), __tuple_types<_Up...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type()); 890fe6060f1SDimitry Andric return *this; 891fe6060f1SDimitry Andric } 892fe6060f1SDimitry Andric 89306c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 894cb14a3feSDimitry Andric template <class... _UTypes, 895cb14a3feSDimitry Andric enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, 89681ad6265SDimitry Andric is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr> 897cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(const tuple<_UTypes...>& __u) const { 898cb14a3feSDimitry Andric std::__memberwise_copy_assign(*this, __u, typename __make_tuple_indices<sizeof...(_Tp)>::type()); 89981ad6265SDimitry Andric return *this; 90081ad6265SDimitry Andric } 90181ad6265SDimitry Andric 902cb14a3feSDimitry Andric template <class... _UTypes, 903cb14a3feSDimitry Andric enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, 90481ad6265SDimitry Andric is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr> 905cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple<_UTypes...>&& __u) const { 906cb14a3feSDimitry Andric std::__memberwise_forward_assign( 907cb14a3feSDimitry Andric *this, __u, __tuple_types<_UTypes...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type()); 90881ad6265SDimitry Andric return *this; 90981ad6265SDimitry Andric } 91006c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 91181ad6265SDimitry Andric 912cb14a3feSDimitry Andric template <template <class...> class _Pred, 913cb14a3feSDimitry Andric bool _Const, 914cb14a3feSDimitry Andric class _Pair, 915cb14a3feSDimitry Andric class _DecayedPair = __remove_cvref_t<_Pair>, 916cb14a3feSDimitry Andric class _Tuple = tuple> 91781ad6265SDimitry Andric struct _AssignPredicateFromPair : false_type {}; 91881ad6265SDimitry Andric 919cb14a3feSDimitry Andric template <template <class...> class _Pred, bool _Const, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> 920cb14a3feSDimitry Andric struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > 921cb14a3feSDimitry Andric : _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >, 922cb14a3feSDimitry Andric _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> > > {}; 92381ad6265SDimitry Andric 92481ad6265SDimitry Andric template <bool _Const, class _Pair> 92581ad6265SDimitry Andric struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {}; 92681ad6265SDimitry Andric 92781ad6265SDimitry Andric template <bool _Const, class _Pair> 92881ad6265SDimitry Andric struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {}; 92981ad6265SDimitry Andric 93006c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 931cb14a3feSDimitry Andric template <class _U1, class _U2, enable_if_t< _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr> 932cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(const pair<_U1, _U2>& __pair) const 93381ad6265SDimitry Andric noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) { 93481ad6265SDimitry Andric std::get<0>(*this) = __pair.first; 93581ad6265SDimitry Andric std::get<1>(*this) = __pair.second; 93681ad6265SDimitry Andric return *this; 93781ad6265SDimitry Andric } 93881ad6265SDimitry Andric 939cb14a3feSDimitry Andric template <class _U1, class _U2, enable_if_t< _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr> 940cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(pair<_U1, _U2>&& __pair) const 94181ad6265SDimitry Andric noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) { 94281ad6265SDimitry Andric std::get<0>(*this) = std::move(__pair.first); 94381ad6265SDimitry Andric std::get<1>(*this) = std::move(__pair.second); 94481ad6265SDimitry Andric return *this; 94581ad6265SDimitry Andric } 94606c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 94781ad6265SDimitry Andric 948cb14a3feSDimitry Andric template <class _Up1, 949cb14a3feSDimitry Andric class _Up2, 950cb14a3feSDimitry Andric __enable_if_t< _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value, int> = 0> 951cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(pair<_Up1, _Up2> const& __pair) 952cb14a3feSDimitry Andric _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value)) { 9535f757f3fSDimitry Andric std::get<0>(*this) = __pair.first; 9545f757f3fSDimitry Andric std::get<1>(*this) = __pair.second; 955fe6060f1SDimitry Andric return *this; 956fe6060f1SDimitry Andric } 957fe6060f1SDimitry Andric 958cb14a3feSDimitry Andric template <class _Up1, class _Up2, __enable_if_t< _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value, int> = 0> 959cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(pair<_Up1, _Up2>&& __pair) 960cb14a3feSDimitry Andric _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value)) { 9615f757f3fSDimitry Andric std::get<0>(*this) = std::forward<_Up1>(__pair.first); 9625f757f3fSDimitry Andric std::get<1>(*this) = std::forward<_Up2>(__pair.second); 963fe6060f1SDimitry Andric return *this; 964fe6060f1SDimitry Andric } 965fe6060f1SDimitry Andric 966fe6060f1SDimitry Andric // EXTENSION 967cb14a3feSDimitry Andric template < 968cb14a3feSDimitry Andric class _Up, 969cb14a3feSDimitry Andric size_t _Np, 970cb14a3feSDimitry Andric class = __enable_if_t< _And< _BoolConstant<_Np == sizeof...(_Tp)>, is_assignable<_Tp&, _Up const&>... >::value > > 971cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(array<_Up, _Np> const& __array) 972cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) { 973cb14a3feSDimitry Andric std::__memberwise_copy_assign(*this, __array, typename __make_tuple_indices<sizeof...(_Tp)>::type()); 974fe6060f1SDimitry Andric return *this; 975fe6060f1SDimitry Andric } 976fe6060f1SDimitry Andric 977fe6060f1SDimitry Andric // EXTENSION 978cb14a3feSDimitry Andric template <class _Up, 979cb14a3feSDimitry Andric size_t _Np, 980cb14a3feSDimitry Andric class = void, 981cb14a3feSDimitry Andric class = __enable_if_t< _And< _BoolConstant<_Np == sizeof...(_Tp)>, is_assignable<_Tp&, _Up>... >::value > > 982cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(array<_Up, _Np>&& __array) 983cb14a3feSDimitry Andric _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) { 984cb14a3feSDimitry Andric std::__memberwise_forward_assign( 985cb14a3feSDimitry Andric *this, 986cb14a3feSDimitry Andric std::move(__array), 987fe6060f1SDimitry Andric __tuple_types<_If<true, _Up, _Tp>...>(), 988fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Tp)>::type()); 989fe6060f1SDimitry Andric return *this; 990fe6060f1SDimitry Andric } 991fe6060f1SDimitry Andric 992fe6060f1SDimitry Andric // [tuple.swap] 993cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple& __t) 994cb14a3feSDimitry Andric _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) { 995cb14a3feSDimitry Andric __base_.swap(__t.__base_); 996cb14a3feSDimitry Andric } 99781ad6265SDimitry Andric 99806c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 999cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple& __t) const 1000cb14a3feSDimitry Andric noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) { 100181ad6265SDimitry Andric __base_.swap(__t.__base_); 100281ad6265SDimitry Andric } 100306c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 10040b57cec5SDimitry Andric}; 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andrictemplate <> 1007cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS tuple<> { 10080b57cec5SDimitry Andricpublic: 100906c3fb27SDimitry Andric constexpr tuple() _NOEXCEPT = default; 10100b57cec5SDimitry Andric template <class _Alloc> 1011cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 10120b57cec5SDimitry Andric template <class _Alloc> 1013cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {} 10140b57cec5SDimitry Andric template <class _Up> 1015cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(array<_Up, 0>) _NOEXCEPT {} 10160b57cec5SDimitry Andric template <class _Alloc, class _Up> 1017cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {} 1018cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple&) _NOEXCEPT {} 101906c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 102081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {} 102181ad6265SDimitry Andric# endif 10220b57cec5SDimitry Andric}; 10230b57cec5SDimitry Andric 102406c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 102504eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes, template <class> class _TQual, template <class> class _UQual> 102604eeddc0SDimitry Andric requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } 102704eeddc0SDimitry Andricstruct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> { 102804eeddc0SDimitry Andric using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; 102904eeddc0SDimitry Andric}; 103004eeddc0SDimitry Andric 103104eeddc0SDimitry Andrictemplate <class... _TTypes, class... _UTypes> 103204eeddc0SDimitry Andric requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; } 103304eeddc0SDimitry Andricstruct common_type<tuple<_TTypes...>, tuple<_UTypes...>> { 103404eeddc0SDimitry Andric using type = tuple<common_type_t<_TTypes, _UTypes>...>; 103504eeddc0SDimitry Andric}; 103606c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 23 103704eeddc0SDimitry Andric 103806c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1039e40139ffSDimitry Andrictemplate <class... _Tp> 1040e40139ffSDimitry Andrictuple(_Tp...) -> tuple<_Tp...>; 1041e40139ffSDimitry Andrictemplate <class _Tp1, class _Tp2> 1042e40139ffSDimitry Andrictuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; 1043e40139ffSDimitry Andrictemplate <class _Alloc, class... _Tp> 1044e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>; 1045e40139ffSDimitry Andrictemplate <class _Alloc, class _Tp1, class _Tp2> 1046e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; 1047e40139ffSDimitry Andrictemplate <class _Alloc, class... _Tp> 1048e40139ffSDimitry Andrictuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>; 10490b57cec5SDimitry Andric# endif 10500b57cec5SDimitry Andric 10515f757f3fSDimitry Andrictemplate <class... _Tp, __enable_if_t<__all<__is_swappable<_Tp>::value...>::value, int> = 0> 1052cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) 1053cb14a3feSDimitry Andric _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) { 1054cb14a3feSDimitry Andric __t.swap(__u); 1055cb14a3feSDimitry Andric} 10560b57cec5SDimitry Andric 105706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 105881ad6265SDimitry Andrictemplate <class... _Tp> 1059cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void> 1060cb14a3feSDimitry Andricswap(const tuple<_Tp...>& __lhs, 1061cb14a3feSDimitry Andric const tuple<_Tp...>& __rhs) noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) { 106281ad6265SDimitry Andric __lhs.swap(__rhs); 106381ad6265SDimitry Andric} 106481ad6265SDimitry Andric# endif 106581ad6265SDimitry Andric 10660b57cec5SDimitry Andric// get 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andrictemplate <size_t _Ip, class... _Tp> 1069cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type& 1070cb14a3feSDimitry Andricget(tuple<_Tp...>& __t) _NOEXCEPT { 1071349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; 10720b57cec5SDimitry Andric return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get(); 10730b57cec5SDimitry Andric} 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andrictemplate <size_t _Ip, class... _Tp> 1076cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type& 1077cb14a3feSDimitry Andricget(const tuple<_Tp...>& __t) _NOEXCEPT { 1078349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; 10790b57cec5SDimitry Andric return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get(); 10800b57cec5SDimitry Andric} 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andrictemplate <size_t _Ip, class... _Tp> 1083cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&& 1084cb14a3feSDimitry Andricget(tuple<_Tp...>&& __t) _NOEXCEPT { 1085349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; 1086cb14a3feSDimitry Andric return static_cast<type&&>(static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get()); 10870b57cec5SDimitry Andric} 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andrictemplate <size_t _Ip, class... _Tp> 1090cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&& 1091cb14a3feSDimitry Andricget(const tuple<_Tp...>&& __t) _NOEXCEPT { 1092349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; 1093cb14a3feSDimitry Andric return static_cast<const type&&>(static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get()); 10940b57cec5SDimitry Andric} 10950b57cec5SDimitry Andric 109606c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 14 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andricnamespace __find_detail { 10990b57cec5SDimitry Andric 1100fe6060f1SDimitry Andricstatic constexpr size_t __not_found = static_cast<size_t>(-1); 11010b57cec5SDimitry Andricstatic constexpr size_t __ambiguous = __not_found - 1; 11020b57cec5SDimitry Andric 1103cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { 1104cb14a3feSDimitry Andric return !__matches ? __res : (__res == __not_found ? __curr_i : __ambiguous); 11050b57cec5SDimitry Andric} 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andrictemplate <size_t _Nx> 1108cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { 1109cb14a3feSDimitry Andric return __i == _Nx 1110cb14a3feSDimitry Andric ? __not_found 1111cb14a3feSDimitry Andric : __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]); 11120b57cec5SDimitry Andric} 11130b57cec5SDimitry Andric 11140b57cec5SDimitry Andrictemplate <class _T1, class... _Args> 11150b57cec5SDimitry Andricstruct __find_exactly_one_checked { 11160b57cec5SDimitry Andric static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...}; 11170b57cec5SDimitry Andric static constexpr size_t value = __find_detail::__find_idx(0, __matches); 11180b57cec5SDimitry Andric static_assert(value != __not_found, "type not found in type list"); 11190b57cec5SDimitry Andric static_assert(value != __ambiguous, "type occurs more than once in type list"); 11200b57cec5SDimitry Andric}; 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andrictemplate <class _T1> 11230b57cec5SDimitry Andricstruct __find_exactly_one_checked<_T1> { 11240b57cec5SDimitry Andric static_assert(!is_same<_T1, _T1>::value, "type not in empty type list"); 11250b57cec5SDimitry Andric}; 11260b57cec5SDimitry Andric 11270eae32dcSDimitry Andric} // namespace __find_detail 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andrictemplate <typename _T1, typename... _Args> 1130cb14a3feSDimitry Andricstruct __find_exactly_one_t : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {}; 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andrictemplate <class _T1, class... _Args> 1133cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept { 11345f757f3fSDimitry Andric return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); 11350b57cec5SDimitry Andric} 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andrictemplate <class _T1, class... _Args> 1138cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept { 11395f757f3fSDimitry Andric return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); 11400b57cec5SDimitry Andric} 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andrictemplate <class _T1, class... _Args> 1143cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept { 11445f757f3fSDimitry Andric return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup)); 11450b57cec5SDimitry Andric} 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andrictemplate <class _T1, class... _Args> 1148cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept { 11495f757f3fSDimitry Andric return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup)); 11500b57cec5SDimitry Andric} 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric# endif 11530b57cec5SDimitry Andric 11540b57cec5SDimitry Andric// tie 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andrictemplate <class... _Tp> 1157cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_Tp&... __t) _NOEXCEPT { 11580b57cec5SDimitry Andric return tuple<_Tp&...>(__t...); 11590b57cec5SDimitry Andric} 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andrictemplate <class _Up> 1162cb14a3feSDimitry Andricstruct __ignore_t { 11630b57cec5SDimitry Andric template <class _Tp> 1164cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const __ignore_t& operator=(_Tp&&) const { 1165cb14a3feSDimitry Andric return *this; 1166cb14a3feSDimitry Andric } 11670b57cec5SDimitry Andric}; 11680b57cec5SDimitry Andric 116906c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 117006c3fb27SDimitry Andricinline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); 117106c3fb27SDimitry Andric# else 11720b57cec5SDimitry Andricnamespace { 1173349cc55cSDimitry Andricconstexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); 11740eae32dcSDimitry Andric} // namespace 117506c3fb27SDimitry Andric# endif 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andrictemplate <class... _Tp> 1178cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<typename __unwrap_ref_decay<_Tp>::type...> 1179cb14a3feSDimitry Andricmake_tuple(_Tp&&... __t) { 11805f757f3fSDimitry Andric return tuple<typename __unwrap_ref_decay<_Tp>::type...>(std::forward<_Tp>(__t)...); 11810b57cec5SDimitry Andric} 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andrictemplate <class... _Tp> 1184cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...> forward_as_tuple(_Tp&&... __t) _NOEXCEPT { 11855f757f3fSDimitry Andric return tuple<_Tp&&...>(std::forward<_Tp>(__t)...); 11860b57cec5SDimitry Andric} 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andrictemplate <size_t _Ip> 1189cb14a3feSDimitry Andricstruct __tuple_equal { 11900b57cec5SDimitry Andric template <class _Tp, class _Up> 1191cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) { 11925f757f3fSDimitry Andric return __tuple_equal<_Ip - 1>()(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y); 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric}; 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andrictemplate <> 1197cb14a3feSDimitry Andricstruct __tuple_equal<0> { 11980b57cec5SDimitry Andric template <class _Tp, class _Up> 1199cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp&, const _Up&) { 12000b57cec5SDimitry Andric return true; 12010b57cec5SDimitry Andric } 12020b57cec5SDimitry Andric}; 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1205cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1206cb14a3feSDimitry Andricoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12070b57cec5SDimitry Andric static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes"); 12080b57cec5SDimitry Andric return __tuple_equal<sizeof...(_Tp)>()(__x, __y); 12090b57cec5SDimitry Andric} 12100b57cec5SDimitry Andric 121106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 20 1212349cc55cSDimitry Andric 1213349cc55cSDimitry Andric// operator<=> 1214349cc55cSDimitry Andric 1215349cc55cSDimitry Andrictemplate <class... _Tp, class... _Up, size_t... _Is> 1216cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto 1217349cc55cSDimitry Andric__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) { 1218349cc55cSDimitry Andric common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal; 1219cb14a3feSDimitry Andric static_cast<void>( 1220cb14a3feSDimitry Andric ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...)); 1221349cc55cSDimitry Andric return __result; 1222349cc55cSDimitry Andric} 1223349cc55cSDimitry Andric 1224349cc55cSDimitry Andrictemplate <class... _Tp, class... _Up> 1225349cc55cSDimitry Andric requires(sizeof...(_Tp) == sizeof...(_Up)) 1226cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> 1227cb14a3feSDimitry Andricoperator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12285f757f3fSDimitry Andric return std::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{}); 1229349cc55cSDimitry Andric} 1230349cc55cSDimitry Andric 123106c3fb27SDimitry Andric# else // _LIBCPP_STD_VER >= 20 1232349cc55cSDimitry Andric 12330b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1234cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1235cb14a3feSDimitry Andricoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12360b57cec5SDimitry Andric return !(__x == __y); 12370b57cec5SDimitry Andric} 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andrictemplate <size_t _Ip> 1240cb14a3feSDimitry Andricstruct __tuple_less { 12410b57cec5SDimitry Andric template <class _Tp, class _Up> 1242cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) { 12430b57cec5SDimitry Andric const size_t __idx = tuple_size<_Tp>::value - _Ip; 12445f757f3fSDimitry Andric if (std::get<__idx>(__x) < std::get<__idx>(__y)) 12450b57cec5SDimitry Andric return true; 12465f757f3fSDimitry Andric if (std::get<__idx>(__y) < std::get<__idx>(__x)) 12470b57cec5SDimitry Andric return false; 12480b57cec5SDimitry Andric return __tuple_less<_Ip - 1>()(__x, __y); 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric}; 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andrictemplate <> 1253cb14a3feSDimitry Andricstruct __tuple_less<0> { 12540b57cec5SDimitry Andric template <class _Tp, class _Up> 1255cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp&, const _Up&) { 12560b57cec5SDimitry Andric return false; 12570b57cec5SDimitry Andric } 12580b57cec5SDimitry Andric}; 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1261cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1262cb14a3feSDimitry Andricoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12630b57cec5SDimitry Andric static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes"); 12640b57cec5SDimitry Andric return __tuple_less<sizeof...(_Tp)>()(__x, __y); 12650b57cec5SDimitry Andric} 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1268cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1269cb14a3feSDimitry Andricoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12700b57cec5SDimitry Andric return __y < __x; 12710b57cec5SDimitry Andric} 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1274cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1275cb14a3feSDimitry Andricoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12760b57cec5SDimitry Andric return !(__x < __y); 12770b57cec5SDimitry Andric} 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andrictemplate <class... _Tp, class... _Up> 1280cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 1281cb14a3feSDimitry Andricoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { 12820b57cec5SDimitry Andric return !(__y < __x); 12830b57cec5SDimitry Andric} 12840b57cec5SDimitry Andric 128506c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 20 1286349cc55cSDimitry Andric 12870b57cec5SDimitry Andric// tuple_cat 12880b57cec5SDimitry Andric 1289cb14a3feSDimitry Andrictemplate <class _Tp, class _Up> 1290cb14a3feSDimitry Andricstruct __tuple_cat_type; 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andrictemplate <class... _Ttypes, class... _Utypes> 1293cb14a3feSDimitry Andricstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > { 1294349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type; 12950b57cec5SDimitry Andric}; 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andrictemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class... _Tuples> 1298cb14a3feSDimitry Andricstruct __tuple_cat_return_1 {}; 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andrictemplate <class... _Types, class _Tuple0> 1301cb14a3feSDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> { 1302cb14a3feSDimitry Andric using type _LIBCPP_NODEBUG = 1303cb14a3feSDimitry Andric typename __tuple_cat_type< tuple<_Types...>, 1304cb14a3feSDimitry Andric typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type >::type; 13050b57cec5SDimitry Andric}; 13060b57cec5SDimitry Andric 13070b57cec5SDimitry Andrictemplate <class... _Types, class _Tuple0, class _Tuple1, class... _Tuples> 13080b57cec5SDimitry Andricstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...> 13090b57cec5SDimitry Andric : public __tuple_cat_return_1< 1310cb14a3feSDimitry Andric typename __tuple_cat_type< tuple<_Types...>, 1311cb14a3feSDimitry Andric typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type >::type, 1312bdd1243dSDimitry Andric __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value, 1313cb14a3feSDimitry Andric _Tuple1, 1314cb14a3feSDimitry Andric _Tuples...> {}; 13150b57cec5SDimitry Andric 1316cb14a3feSDimitry Andrictemplate <class... _Tuples> 1317cb14a3feSDimitry Andricstruct __tuple_cat_return; 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples> 13200b57cec5SDimitry Andricstruct __tuple_cat_return<_Tuple0, _Tuples...> 13210b57cec5SDimitry Andric : public __tuple_cat_return_1<tuple<>, 1322cb14a3feSDimitry Andric __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value, 1323cb14a3feSDimitry Andric _Tuple0, 1324cb14a3feSDimitry Andric _Tuples...> {}; 13250b57cec5SDimitry Andric 13260b57cec5SDimitry Andrictemplate <> 1327cb14a3feSDimitry Andricstruct __tuple_cat_return<> { 1328349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG tuple<> type; 13290b57cec5SDimitry Andric}; 13300b57cec5SDimitry Andric 1331cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<> tuple_cat() { return tuple<>(); } 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andrictemplate <class _Rp, class _Indices, class _Tuple0, class... _Tuples> 13340b57cec5SDimitry Andricstruct __tuple_cat_return_ref_imp; 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andrictemplate <class... _Types, size_t... _I0, class _Tuple0> 1337cb14a3feSDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> { 1338bdd1243dSDimitry Andric typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0; 133906c3fb27SDimitry Andric typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type; 13400b57cec5SDimitry Andric}; 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andrictemplate <class... _Types, size_t... _I0, class _Tuple0, class _Tuple1, class... _Tuples> 1343cb14a3feSDimitry Andricstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0, _Tuple1, _Tuples...> 13440b57cec5SDimitry Andric : public __tuple_cat_return_ref_imp< 1345cb14a3feSDimitry Andric tuple<_Types..., 1346cb14a3feSDimitry Andric __apply_cv_t<_Tuple0, typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>, 1347bdd1243dSDimitry Andric typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type, 1348cb14a3feSDimitry Andric _Tuple1, 1349cb14a3feSDimitry Andric _Tuples...> {}; 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples> 13520b57cec5SDimitry Andricstruct __tuple_cat_return_ref 1353cb14a3feSDimitry Andric : public __tuple_cat_return_ref_imp< 1354cb14a3feSDimitry Andric tuple<>, 1355cb14a3feSDimitry Andric typename __make_tuple_indices< tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value >::type, 1356cb14a3feSDimitry Andric _Tuple0, 1357cb14a3feSDimitry Andric _Tuples...> {}; 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andrictemplate <class _Types, class _I0, class _J0> 13600b57cec5SDimitry Andricstruct __tuple_cat; 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andrictemplate <class... _Types, size_t... _I0, size_t... _J0> 1363cb14a3feSDimitry Andricstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > { 13640b57cec5SDimitry Andric template <class _Tuple0> 13655f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 13660b57cec5SDimitry Andric typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type 1367cb14a3feSDimitry Andric operator()(tuple<_Types...> __t, _Tuple0&& __t0) { 136881ad6265SDimitry Andric (void)__t; // avoid unused parameter warning on GCC when _I0 is empty 13695f757f3fSDimitry Andric return std::forward_as_tuple( 1370cb14a3feSDimitry Andric std::forward<_Types>(std::get<_I0>(__t))..., std::get<_J0>(std::forward<_Tuple0>(__t0))...); 13710b57cec5SDimitry Andric } 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric template <class _Tuple0, class _Tuple1, class... _Tuples> 13745f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 13750b57cec5SDimitry Andric typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type 1376cb14a3feSDimitry Andric operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&&... __tpls) { 137781ad6265SDimitry Andric (void)__t; // avoid unused parameter warning on GCC when _I0 is empty 1378bdd1243dSDimitry Andric typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0; 1379bdd1243dSDimitry Andric typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1; 138006c3fb27SDimitry Andric return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>, 138106c3fb27SDimitry Andric typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type, 1382480093f4SDimitry Andric typename __make_tuple_indices<tuple_size<_T1>::value>::type>()( 13835f757f3fSDimitry Andric std::forward_as_tuple( 1384cb14a3feSDimitry Andric std::forward<_Types>(std::get<_I0>(__t))..., std::get<_J0>(std::forward<_Tuple0>(__t0))...), 1385cb14a3feSDimitry Andric std::forward<_Tuple1>(__t1), 1386cb14a3feSDimitry Andric std::forward<_Tuples>(__tpls)...); 13870b57cec5SDimitry Andric } 13880b57cec5SDimitry Andric}; 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andrictemplate <class _Tuple0, class... _Tuples> 1391cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __tuple_cat_return<_Tuple0, _Tuples...>::type 1392cb14a3feSDimitry Andrictuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) { 1393bdd1243dSDimitry Andric typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0; 1394cb14a3feSDimitry Andric return __tuple_cat<tuple<>, __tuple_indices<>, typename __make_tuple_indices<tuple_size<_T0>::value>::type>()( 1395cb14a3feSDimitry Andric tuple<>(), std::forward<_Tuple0>(__t0), std::forward<_Tuples>(__tpls)...); 13960b57cec5SDimitry Andric} 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andrictemplate <class... _Tp, class _Alloc> 1399cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc> : true_type {}; 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andrictemplate <class _T1, class _T2> 14020b57cec5SDimitry Andrictemplate <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 1403cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_T1, _T2>::pair( 1404cb14a3feSDimitry Andric piecewise_construct_t, 1405cb14a3feSDimitry Andric tuple<_Args1...>& __first_args, 1406cb14a3feSDimitry Andric tuple<_Args2...>& __second_args, 1407cb14a3feSDimitry Andric __tuple_indices<_I1...>, 1408cb14a3feSDimitry Andric __tuple_indices<_I2...>) 14095f757f3fSDimitry Andric : first(std::forward<_Args1>(std::get<_I1>(__first_args))...), 1410cb14a3feSDimitry Andric second(std::forward<_Args2>(std::get<_I2>(__second_args))...) {} 14110b57cec5SDimitry Andric 141206c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 14130b57cec5SDimitry Andrictemplate <class _Tp> 1414349cc55cSDimitry Andricinline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; 14150b57cec5SDimitry Andric 1416cb14a3feSDimitry Andric# define _LIBCPP_NOEXCEPT_RETURN(...) \ 1417cb14a3feSDimitry Andric noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } 14180b57cec5SDimitry Andric 1419*1db9f3b2SDimitry Andric// The _LIBCPP_NOEXCEPT_RETURN macro breaks formatting. 1420*1db9f3b2SDimitry Andric// clang-format off 14210b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple, size_t... _Id> 1422cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) 1423cb14a3feSDimitry Andric__apply_tuple_impl(_Fn&& __f, _Tuple&& __t, __tuple_indices<_Id...>) 1424cb14a3feSDimitry Andric _LIBCPP_NOEXCEPT_RETURN(std::__invoke(std::forward<_Fn>(__f), std::get<_Id>(std::forward<_Tuple>(__t))...)) 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andrictemplate <class _Fn, class _Tuple> 1427*1db9f3b2SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) apply(_Fn&& __f, _Tuple&& __t) 1428*1db9f3b2SDimitry Andric _LIBCPP_NOEXCEPT_RETURN(std::__apply_tuple_impl( 1429*1db9f3b2SDimitry Andric std::forward<_Fn>(__f), 1430cb14a3feSDimitry Andric std::forward<_Tuple>(__t), 1431cb14a3feSDimitry Andric typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})) 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple, size_t... _Idx> 1434*1db9f3b2SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) 1435cb14a3feSDimitry Andric _LIBCPP_NOEXCEPT_RETURN(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...)) 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andrictemplate <class _Tp, class _Tuple> 1438*1db9f3b2SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t) 1439*1db9f3b2SDimitry Andric _LIBCPP_NOEXCEPT_RETURN(std::__make_from_tuple_impl<_Tp>( 1440cb14a3feSDimitry Andric std::forward<_Tuple>(__t), typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})) 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric# undef _LIBCPP_NOEXCEPT_RETURN 14430b57cec5SDimitry Andric 144406c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 17 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 14490b57cec5SDimitry Andric 145006c3fb27SDimitry Andric_LIBCPP_POP_MACROS 145106c3fb27SDimitry Andric 1452*1db9f3b2SDimitry Andric// clang-format on 1453*1db9f3b2SDimitry Andric 1454bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1455bdd1243dSDimitry Andric# include <exception> 1456bdd1243dSDimitry Andric# include <iosfwd> 1457bdd1243dSDimitry Andric# include <new> 1458bdd1243dSDimitry Andric# include <type_traits> 1459bdd1243dSDimitry Andric# include <typeinfo> 1460bdd1243dSDimitry Andric# include <utility> 1461bdd1243dSDimitry Andric#endif 1462bdd1243dSDimitry Andric 14630b57cec5SDimitry Andric#endif // _LIBCPP_TUPLE 1464