// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_TUPLE #define _LIBCPP_TUPLE /* tuple synopsis namespace std { template class tuple { public: explicit(see-below) constexpr tuple(); explicit(see-below) tuple(const T&...); // constexpr in C++14 template explicit(see-below) tuple(U&&...); // constexpr in C++14 tuple(const tuple&) = default; tuple(tuple&&) = default; template constexpr explicit(see-below) tuple(tuple&); // C++23 template explicit(see-below) tuple(const tuple&); // constexpr in C++14 template explicit(see-below) tuple(tuple&&); // constexpr in C++14 template constexpr explicit(see-below) tuple(const tuple&&); // C++23 template constexpr explicit(see-below) tuple(pair&); // iff sizeof...(Types) == 2 // C++23 template explicit(see-below) tuple(const pair&); // iff sizeof...(T) == 2 // constexpr in C++14 template explicit(see-below) tuple(pair&&); // iff sizeof...(T) == 2 // constexpr in C++14 template constexpr explicit(see-below) tuple(const pair&&); // iff sizeof...(Types) == 2 // C++23 // allocator-extended constructors template tuple(allocator_arg_t, const Alloc& a); template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20 template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20 template tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20 template tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20 template constexpr explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple&); // C++23 template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20 template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20 template constexpr explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple&&); // C++23 template constexpr explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair&); // C++23 template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair&); // constexpr in C++20 template explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair&&); // constexpr in C++20 template constexpr explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair&&); // C++23 tuple& operator=(const tuple&); // constexpr in C++20 constexpr const tuple& operator=(const tuple&) const; // C++23 tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v && ...); // constexpr in C++20 constexpr const tuple& operator=(tuple&&) const; // C++23 template tuple& operator=(const tuple&); // constexpr in C++20 template constexpr const tuple& operator=(const tuple&) const; // C++23 template tuple& operator=(tuple&&); // constexpr in C++20 template constexpr const tuple& operator=(tuple&&) const; // C++23 template tuple& operator=(const pair&); // iff sizeof...(T) == 2 // constexpr in C++20 template constexpr const tuple& operator=(const pair&) const; // iff sizeof...(Types) == 2 // C++23 template tuple& operator=(pair&&); // iff sizeof...(T) == 2 // constexpr in C++20 template constexpr const tuple& operator=(pair&&) const; // iff sizeof...(Types) == 2 // C++23 template tuple& operator=(array const&) // iff sizeof...(T) == N, EXTENSION template tuple& operator=(array&&) // iff sizeof...(T) == N, EXTENSION void swap(tuple&) noexcept(AND(swap(declval(), declval())...)); // constexpr in C++20 constexpr void swap(const tuple&) const noexcept(see-below); // C++23 }; template class TQual, template class UQual> // since C++23 requires requires { typename tuple, UQual>...>; } struct basic_common_reference, tuple, TQual, UQual> { using type = tuple, UQual>...>; }; template // since C++23 requires requires { typename tuple...>; } struct common_type, tuple> { using type = tuple...>; }; template tuple(T...) -> tuple; // since C++17 template tuple(pair) -> tuple; // since C++17 template tuple(allocator_arg_t, Alloc, T...) -> tuple; // since C++17 template tuple(allocator_arg_t, Alloc, pair) -> tuple; // since C++17 template tuple(allocator_arg_t, Alloc, tuple) -> tuple; // since C++17 inline constexpr unspecified ignore; template tuple make_tuple(T&&...); // constexpr in C++14 template tuple forward_as_tuple(T&&...) noexcept; // constexpr in C++14 template tuple tie(T&...) noexcept; // constexpr in C++14 template tuple tuple_cat(Tuples&&... tpls); // constexpr in C++14 // [tuple.apply], calling a function with a tuple of arguments: template constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 template constexpr T make_from_tuple(Tuple&& t); // C++17 // 20.4.1.4, tuple helper classes: template struct tuple_size; // undefined template struct tuple_size>; template inline constexpr size_t tuple_size_v = tuple_size::value; // C++17 template struct tuple_element; // undefined template struct tuple_element>; template using tuple_element_t = typename tuple_element ::type; // C++14 // 20.4.1.5, element access: template typename tuple_element>::type& get(tuple&) noexcept; // constexpr in C++14 template const typename tuple_element>::type& get(const tuple&) noexcept; // constexpr in C++14 template typename tuple_element>::type&& get(tuple&&) noexcept; // constexpr in C++14 template const typename tuple_element>::type&& get(const tuple&&) noexcept; // constexpr in C++14 template constexpr T1& get(tuple&) noexcept; // C++14 template constexpr const T1& get(const tuple&) noexcept; // C++14 template constexpr T1&& get(tuple&&) noexcept; // C++14 template constexpr const T1&& get(const tuple&&) noexcept; // C++14 // 20.4.1.6, relational operators: template bool operator==(const tuple&, const tuple&); // constexpr in C++14 template bool operator<(const tuple&, const tuple&); // constexpr in C++14, removed in C++20 template bool operator!=(const tuple&, const tuple&); // constexpr in C++14, removed in C++20 template bool operator>(const tuple&, const tuple&); // constexpr in C++14, removed in C++20 template bool operator<=(const tuple&, const tuple&); // constexpr in C++14, removed in C++20 template bool operator>=(const tuple&, const tuple&); // constexpr in C++14, removed in C++20 template constexpr common_comparison_category_t...> operator<=>(const tuple&, const tuple&); // since C++20 template struct uses_allocator, Alloc>; template void swap(tuple& x, tuple& y) noexcept(noexcept(x.swap(y))); template constexpr void swap(const tuple& x, const tuple& y) noexcept(see-below); // C++23 } // std */ #include <__assert> // all public C++ headers provide the assertion handler #include <__compare/common_comparison_category.h> #include <__compare/synth_three_way.h> #include <__config> #include <__functional/unwrap_ref.h> #include <__memory/allocator_arg_t.h> #include <__memory/uses_allocator.h> #include <__tuple> #include <__utility/forward.h> #include <__utility/integer_sequence.h> #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/piecewise_construct.h> #include <__utility/swap.h> #include #include #include #ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES # include # include # include # include # include #endif // standard-mandated includes #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_CXX03_LANG // __tuple_leaf template ::value && !__libcpp_is_final<_Hp>::value > class __tuple_leaf; template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) { swap(__x.get(), __y.get()); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y) _NOEXCEPT_(__is_nothrow_swappable::value) { swap(__x.get(), __y.get()); } template class __tuple_leaf { _Hp __value_; template static constexpr bool __can_bind_reference() { #if __has_keyword(__reference_binds_to_temporary) return !__reference_binds_to_temporary(_Hp, _Tp); #else return true; #endif } _LIBCPP_CONSTEXPR_AFTER_CXX11 __tuple_leaf& operator=(const __tuple_leaf&); public: _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf() _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_() {static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple");} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc&) : __value_() {static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple");} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc& __a) : __value_(allocator_arg_t(), __a) {static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple");} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc& __a) : __value_(__a) {static_assert(!is_reference<_Hp>::value, "Attempted to default construct a reference element in a tuple");} template , __tuple_leaf>, is_constructible<_Hp, _Tp> >::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) : __value_(_VSTD::forward<_Tp>(__t)) {static_assert(__can_bind_reference<_Tp&&>(), "Attempted construction of reference element binds to a temporary whose lifetime has ended");} template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(integral_constant, const _Alloc&, _Tp&& __t) : __value_(_VSTD::forward<_Tp>(__t)) {static_assert(__can_bind_reference<_Tp&&>(), "Attempted construction of reference element binds to a temporary whose lifetime has ended");} template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(integral_constant, const _Alloc& __a, _Tp&& __t) : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {static_assert(!is_reference<_Hp>::value, "Attempted to uses-allocator construct a reference element in a tuple");} template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(integral_constant, const _Alloc& __a, _Tp&& __t) : __value_(_VSTD::forward<_Tp>(__t), __a) {static_assert(!is_reference<_Hp>::value, "Attempted to uses-allocator construct a reference element in a tuple");} __tuple_leaf(const __tuple_leaf& __t) = default; __tuple_leaf(__tuple_leaf&& __t) = default; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) { _VSTD::swap(*this, __t); return 0; } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable::value) { _VSTD::swap(*this, __t); return 0; } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;} }; template class __tuple_leaf<_Ip, _Hp, true> : private _Hp { _LIBCPP_CONSTEXPR_AFTER_CXX11 __tuple_leaf& operator=(const __tuple_leaf&); public: _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf() _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc&) {} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc& __a) : _Hp(allocator_arg_t(), __a) {} template _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf(integral_constant, const _Alloc& __a) : _Hp(__a) {} template , __tuple_leaf>, is_constructible<_Hp, _Tp> >::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) : _Hp(_VSTD::forward<_Tp>(__t)) {} template _LIBCPP_INLINE_VISIBILITY constexpr explicit __tuple_leaf(integral_constant, const _Alloc&, _Tp&& __t) : _Hp(_VSTD::forward<_Tp>(__t)) {} template _LIBCPP_INLINE_VISIBILITY constexpr explicit __tuple_leaf(integral_constant, const _Alloc& __a, _Tp&& __t) : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} template _LIBCPP_INLINE_VISIBILITY constexpr explicit __tuple_leaf(integral_constant, const _Alloc& __a, _Tp&& __t) : _Hp(_VSTD::forward<_Tp>(__t), __a) {} __tuple_leaf(__tuple_leaf const &) = default; __tuple_leaf(__tuple_leaf &&) = default; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) { _VSTD::swap(*this, __t); return 0; } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable::value) { _VSTD::swap(*this, __rhs); return 0; } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return static_cast<_Hp&>(*this);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast(*this);} }; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void __swallow(_Tp&&...) _NOEXCEPT {} template struct __all_default_constructible; template struct __all_default_constructible<__tuple_types<_Tp...>> : __all::value...> { }; // __tuple_impl template struct __tuple_impl; template struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...> : public __tuple_leaf<_Indx, _Tp>... { _LIBCPP_INLINE_VISIBILITY constexpr __tuple_impl() _NOEXCEPT_(__all::value...>::value) {} template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>, __tuple_indices<_Ul...>, __tuple_types<_Tl...>, _Up&&... __u) _NOEXCEPT_((__all::value...>::value && __all::value...>::value)) : __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))..., __tuple_leaf<_Ul, _Tl>()... {} template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_impl(allocator_arg_t, const _Alloc& __a, __tuple_indices<_Uf...>, __tuple_types<_Tf...>, __tuple_indices<_Ul...>, __tuple_types<_Tl...>, _Up&&... __u) : __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, _VSTD::forward<_Up>(__u))..., __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... {} template >::value> > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all::type>::type>::value...>::value)) : __tuple_leaf<_Indx, _Tp>(_VSTD::forward::type>::type>(_VSTD::get<_Indx>(__t)))... {} template >::value> > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>(), __a, _VSTD::forward::type>::type>(_VSTD::get<_Indx>(__t)))... {} __tuple_impl(const __tuple_impl&) = default; __tuple_impl(__tuple_impl&&) = default; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void swap(__tuple_impl& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) { _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void swap(const __tuple_impl& __t) const _NOEXCEPT_(__all<__is_nothrow_swappable::value...>::value) { _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast&>(__t))...); } }; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) { _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...); } template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) { _VSTD::__swallow((( _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source)) ), void(), 0)...); } template class _LIBCPP_TEMPLATE_VIS tuple { typedef __tuple_impl::type, _Tp...> _BaseT; _BaseT __base_; template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT; public: // [tuple.cnstr] // tuple() constructors (including allocator_arg_t variants) template class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t< _And< _IsImpDefault<_Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(_And...>::value) { } template class _IsImpDefault = __is_implicitly_default_constructible, template class _IsDefault = is_default_constructible, __enable_if_t< _And< _IsDefault<_Tp>..., _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit tuple() _NOEXCEPT_(_And...>::value) { } template class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t< _And< _IsImpDefault<_Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, _Alloc const& __a) : __base_(allocator_arg_t(), __a, __tuple_indices<>(), __tuple_types<>(), typename __make_tuple_indices::type(), __tuple_types<_Tp...>()) {} template class _IsImpDefault = __is_implicitly_default_constructible, template class _IsDefault = is_default_constructible, __enable_if_t< _And< _IsDefault<_Tp>..., _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit tuple(allocator_arg_t, _Alloc const& __a) : __base_(allocator_arg_t(), __a, __tuple_indices<>(), __tuple_types<>(), typename __make_tuple_indices::type(), __tuple_types<_Tp...>()) {} // tuple(const T&...) constructors (including allocator_arg_t variants) template class _And = _And, __enable_if_t< _And< _BoolConstant= 1>, is_copy_constructible<_Tp>..., is_convertible... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 tuple(const _Tp& ... __t) _NOEXCEPT_(_And...>::value) : __base_(typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices<0>::type(), typename __make_tuple_types::type(), __t... ) {} template class _And = _And, __enable_if_t< _And< _BoolConstant= 1>, is_copy_constructible<_Tp>..., _Not<_Lazy<_And, is_convertible...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit tuple(const _Tp& ... __t) _NOEXCEPT_(_And...>::value) : __base_(typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices<0>::type(), typename __make_tuple_types::type(), __t... ) {} template class _And = _And, __enable_if_t< _And< _BoolConstant= 1>, is_copy_constructible<_Tp>..., is_convertible... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) : __base_(allocator_arg_t(), __a, typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices<0>::type(), typename __make_tuple_types::type(), __t... ) {} template class _And = _And, __enable_if_t< _And< _BoolConstant= 1>, is_copy_constructible<_Tp>..., _Not<_Lazy<_And, is_convertible...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) : __base_(allocator_arg_t(), __a, typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices<0>::type(), typename __make_tuple_types::type(), __t... ) {} // tuple(U&& ...) constructors (including allocator_arg_t variants) template struct _IsThisTuple : false_type { }; template struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { }; template struct _EnableUTypesCtor : _And< _BoolConstant= 1>, _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors is_constructible<_Tp, _Up>... > { }; template , _EnableUTypesCtor<_Up...>, is_convertible<_Up, _Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 tuple(_Up&&... __u) _NOEXCEPT_((_And...>::value)) : __base_(typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices::type(), typename __make_tuple_types::type(), _VSTD::forward<_Up>(__u)...) {} template , _EnableUTypesCtor<_Up...>, _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit tuple(_Up&&... __u) _NOEXCEPT_((_And...>::value)) : __base_(typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices::type(), typename __make_tuple_types::type(), _VSTD::forward<_Up>(__u)...) {} template , _EnableUTypesCtor<_Up...>, is_convertible<_Up, _Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) : __base_(allocator_arg_t(), __a, typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices::type(), typename __make_tuple_types::type(), _VSTD::forward<_Up>(__u)...) {} template , _EnableUTypesCtor<_Up...>, _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) : __base_(allocator_arg_t(), __a, typename __make_tuple_indices::type(), typename __make_tuple_types::type(), typename __make_tuple_indices::type(), typename __make_tuple_types::type(), _VSTD::forward<_Up>(__u)...) {} // Copy and move constructors (including the allocator_arg_t variants) tuple(const tuple&) = default; tuple(tuple&&) = default; template class _And = _And, __enable_if_t< _And...>::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t) : __base_(allocator_arg_t(), __alloc, __t) { } template class _And = _And, __enable_if_t< _And...>::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t) : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t)) { } // tuple(const tuple&) constructors (including allocator_arg_t variants) template , class = void> struct _EnableCtorFromUTypesTuple : false_type {}; template struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>, // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below __enable_if_t> : _And< // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work. // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE _Not >, _Not >, is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >..., _Lazy<_Or, _BoolConstant, // _Tp and _Up are 1-element packs - the pack expansions look // weird to avoid tripping up the type traits in degenerate cases _Lazy<_And, _Not >..., _Not >..., _Not >... > > > {}; template &>, is_convertible... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 tuple(const tuple<_Up...>& __t) _NOEXCEPT_((_And...>::value)) : __base_(__t) { } template &>, _Not<_Lazy<_And, is_convertible...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit tuple(const tuple<_Up...>& __t) _NOEXCEPT_((_And...>::value)) : __base_(__t) { } template &>, is_convertible... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t) : __base_(allocator_arg_t(), __a, __t) { } template &>, _Not<_Lazy<_And, is_convertible...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t) : __base_(allocator_arg_t(), __a, __t) { } #if _LIBCPP_STD_VER > 20 // tuple(tuple&) constructors (including allocator_arg_t variants) template &>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!(is_convertible_v<_Up&, _Tp> && ...)) tuple(tuple<_Up...>& __t) : __base_(__t) {} template &>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!(is_convertible_v<_Up&, _Tp> && ...)) tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {} #endif // _LIBCPP_STD_VER > 20 // tuple(tuple&&) constructors (including allocator_arg_t variants) template &&>, is_convertible<_Up, _Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 tuple(tuple<_Up...>&& __t) _NOEXCEPT_((_And...>::value)) : __base_(_VSTD::move(__t)) { } template &&>, _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit tuple(tuple<_Up...>&& __t) _NOEXCEPT_((_And...>::value)) : __base_(_VSTD::move(__t)) { } template &&>, is_convertible<_Up, _Tp>... // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t) : __base_(allocator_arg_t(), __a, _VSTD::move(__t)) { } template &&>, _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check >::value , int> = 0> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t) : __base_(allocator_arg_t(), __a, _VSTD::move(__t)) { } #if _LIBCPP_STD_VER > 20 // tuple(const tuple&&) constructors (including allocator_arg_t variants) template &&>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!(is_convertible_v && ...)) tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {} template &&>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!(is_convertible_v && ...)) tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t) : __base_(allocator_arg_t(), __alloc, std::move(__t)) {} #endif // _LIBCPP_STD_VER > 20 // tuple(const pair&) constructors (including allocator_arg_t variants) template