blob: 9a58d6af7dad27caf88f744f1f8fb88a0497f682 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_TUPLE
11#define _LIBCPP_TUPLE
12
13/*
14 tuple synopsis
15
16namespace std
17{
18
19template <class... T>
20class tuple {
21public:
Louis Dionnea7a2beb2019-09-26 14:51:10 +000022 explicit(see-below) constexpr tuple();
Louis Dionne1afad1d2019-07-22 20:45:23 +000023 explicit(see-below) tuple(const T&...); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000024 template <class... U>
Louis Dionne1afad1d2019-07-22 20:45:23 +000025 explicit(see-below) tuple(U&&...); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000026 tuple(const tuple&) = default;
Howard Hinnant89ef1212011-05-27 19:08:18 +000027 tuple(tuple&&) = default;
Howard Hinnantc51e1022010-05-11 19:42:16 +000028 template <class... U>
Louis Dionne1afad1d2019-07-22 20:45:23 +000029 explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000030 template <class... U>
Louis Dionne1afad1d2019-07-22 20:45:23 +000031 explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000032 template <class U1, class U2>
Louis Dionne1afad1d2019-07-22 20:45:23 +000033 explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000034 template <class U1, class U2>
Louis Dionne1afad1d2019-07-22 20:45:23 +000035 explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000036
37 // allocator-extended constructors
38 template <class Alloc>
39 tuple(allocator_arg_t, const Alloc& a);
40 template <class Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050041 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000042 template <class Alloc, class... U>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050043 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000044 template <class Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050045 tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000046 template <class Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050047 tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000048 template <class Alloc, class... U>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050049 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000050 template <class Alloc, class... U>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050051 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000052 template <class Alloc, class U1, class U2>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050053 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000054 template <class Alloc, class U1, class U2>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050055 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000056
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050057 tuple& operator=(const tuple&); // constexpr in C++20
58 tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000059 template <class... U>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050060 tuple& operator=(const tuple<U...>&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000061 template <class... U>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050062 tuple& operator=(tuple<U...>&&); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000063 template <class U1, class U2>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050064 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 template <class U1, class U2>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050066 tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000067
Louis Dionne6c0d5342018-07-31 11:56:20 -040068 template<class U, size_t N>
69 tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70 template<class U, size_t N>
71 tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -050073 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000074};
75
Louis Dionne616da2a2019-08-12 18:30:31 +000076template <class ...T>
77tuple(T...) -> tuple<T...>; // since C++17
78template <class T1, class T2>
79tuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17
80template <class Alloc, class ...T>
81tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17
82template <class Alloc, class T1, class T2>
83tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17
84template <class Alloc, class ...T>
85tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17
86
Marshall Clowf1bf62f2018-01-02 17:17:01 +000087inline constexpr unspecified ignore;
Howard Hinnantc51e1022010-05-11 19:42:16 +000088
Marshall Clow2229cee2013-07-22 16:02:19 +000089template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14
Marshall Clowded420b2013-10-05 18:46:37 +000090template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
Marshall Clowa8892812014-02-25 16:11:46 +000091template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
Marshall Clow2229cee2013-07-22 16:02:19 +000092template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
Eric Fiselier8e892c52016-07-18 00:35:56 +000093
94// [tuple.apply], calling a function with a tuple of arguments:
95template <class F, class Tuple>
96 constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
97template <class T, class Tuple>
98 constexpr T make_from_tuple(Tuple&& t); // C++17
99
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100// 20.4.1.4, tuple helper classes:
Marshall Clowce62b4d2019-01-11 21:57:12 +0000101template <class T> struct tuple_size; // undefined
102template <class... T> struct tuple_size<tuple<T...>>;
Eric Fiselier8e892c52016-07-18 00:35:56 +0000103template <class T>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000104 inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
Louis Dionnee684aa62019-04-01 16:39:34 +0000105template <size_t I, class T> struct tuple_element; // undefined
106template <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
Marshall Clow36907512015-11-19 19:45:29 +0000107template <size_t I, class T>
108 using tuple_element_t = typename tuple_element <I, T>::type; // C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000109
110// 20.4.1.5, element access:
Marshall Clow36907512015-11-19 19:45:29 +0000111template <size_t I, class... T>
Howard Hinnant89ef1212011-05-27 19:08:18 +0000112 typename tuple_element<I, tuple<T...>>::type&
Marshall Clow0abb1042013-07-17 18:25:36 +0000113 get(tuple<T...>&) noexcept; // constexpr in C++14
Marshall Clow36907512015-11-19 19:45:29 +0000114template <size_t I, class... T>
115 const typename tuple_element<I, tuple<T...>>::type&
Marshall Clow0abb1042013-07-17 18:25:36 +0000116 get(const tuple<T...>&) noexcept; // constexpr in C++14
Marshall Clow36907512015-11-19 19:45:29 +0000117template <size_t I, class... T>
Howard Hinnant89ef1212011-05-27 19:08:18 +0000118 typename tuple_element<I, tuple<T...>>::type&&
Marshall Clow0abb1042013-07-17 18:25:36 +0000119 get(tuple<T...>&&) noexcept; // constexpr in C++14
Eric Fiselier6dea8092015-12-18 00:36:55 +0000120template <size_t I, class... T>
121 const typename tuple_element<I, tuple<T...>>::type&&
122 get(const tuple<T...>&&) noexcept; // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123
Marshall Clow15b02e02013-07-13 02:54:05 +0000124template <class T1, class... T>
125 constexpr T1& get(tuple<T...>&) noexcept; // C++14
126template <class T1, class... T>
Marshall Clow36907512015-11-19 19:45:29 +0000127 constexpr const T1& get(const tuple<T...>&) noexcept; // C++14
Marshall Clow15b02e02013-07-13 02:54:05 +0000128template <class T1, class... T>
129 constexpr T1&& get(tuple<T...>&&) noexcept; // C++14
Eric Fiselier6dea8092015-12-18 00:36:55 +0000130template <class T1, class... T>
131 constexpr const T1&& get(const tuple<T...>&&) noexcept; // C++14
Marshall Clow15b02e02013-07-13 02:54:05 +0000132
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133// 20.4.1.6, relational operators:
Marshall Clow2229cee2013-07-22 16:02:19 +0000134template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
135template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
136template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
137template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
138template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
139template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000140
141template <class... Types, class Alloc>
142 struct uses_allocator<tuple<Types...>, Alloc>;
143
144template <class... Types>
Howard Hinnant89ef1212011-05-27 19:08:18 +0000145 void
146 swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000147
Howard Hinnantc51e1022010-05-11 19:42:16 +0000148} // std
149
150*/
151
152#include <__config>
153#include <__tuple>
Arthur O'Dwyer7deec122021-03-24 18:19:12 -0400154#include <compare>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155#include <cstddef>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000156#include <type_traits>
Howard Hinnant83b1c052011-12-19 17:58:44 +0000157#include <__functional_base>
158#include <utility>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000159#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000161#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000162#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000163#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000164
165_LIBCPP_BEGIN_NAMESPACE_STD
166
Eric Fiselierffe4aba2017-04-19 01:23:39 +0000167#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +0000168
Marshall Clowf50d66f2014-03-03 06:18:11 +0000169
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170// __tuple_leaf
171
Eric Fiselierf7394302015-06-13 07:08:02 +0000172template <size_t _Ip, class _Hp,
173 bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
Howard Hinnantd0aabf82011-12-11 20:31:33 +0000174 >
Howard Hinnantc51e1022010-05-11 19:42:16 +0000175class __tuple_leaf;
176
177template <size_t _Ip, class _Hp, bool _Ep>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500178inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000179void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
Howard Hinnant89ef1212011-05-27 19:08:18 +0000180 _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181{
182 swap(__x.get(), __y.get());
183}
184
185template <size_t _Ip, class _Hp, bool>
186class __tuple_leaf
187{
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000188 _Hp __value_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000189
Eric Fiselierca8bba12016-07-20 02:57:39 +0000190 template <class _Tp>
191 static constexpr bool __can_bind_reference() {
Eric Fiselier869187d2018-01-24 22:14:01 +0000192#if __has_keyword(__reference_binds_to_temporary)
193 return !__reference_binds_to_temporary(_Hp, _Tp);
Eric Fiselier81c32cb2018-01-24 23:10:02 +0000194#else
195 return true;
Eric Fiselier869187d2018-01-24 22:14:01 +0000196#endif
Eric Fiselierca8bba12016-07-20 02:57:39 +0000197 }
198
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500199 _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000200 __tuple_leaf& operator=(const __tuple_leaf&);
201public:
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500202 _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000203 _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
Howard Hinnantc51e1022010-05-11 19:42:16 +0000204 {static_assert(!is_reference<_Hp>::value,
205 "Attempted to default construct a reference element in a tuple");}
206
207 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500208 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209 __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000210 : __value_()
Howard Hinnantc51e1022010-05-11 19:42:16 +0000211 {static_assert(!is_reference<_Hp>::value,
212 "Attempted to default construct a reference element in a tuple");}
213
214 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500215 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000216 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000217 : __value_(allocator_arg_t(), __a)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000218 {static_assert(!is_reference<_Hp>::value,
219 "Attempted to default construct a reference element in a tuple");}
220
221 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500222 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000223 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000224 : __value_(__a)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000225 {static_assert(!is_reference<_Hp>::value,
226 "Attempted to default construct a reference element in a tuple");}
227
Howard Hinnant693fc212010-09-27 17:54:17 +0000228 template <class _Tp,
Eric Fiselier3906a132019-06-23 20:28:29 +0000229 class = _EnableIf<
230 _And<
231 _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
232 is_constructible<_Hp, _Tp>
Eric Fiselier42fa85e2014-07-24 18:48:34 +0000233 >::value
Eric Fiselier3906a132019-06-23 20:28:29 +0000234 >
Eric Fiselier42fa85e2014-07-24 18:48:34 +0000235 >
Marshall Clow2229cee2013-07-22 16:02:19 +0000236 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant62751642012-07-06 21:53:48 +0000237 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000238 : __value_(_VSTD::forward<_Tp>(__t))
Eric Fiselier869187d2018-01-24 22:14:01 +0000239 {static_assert(__can_bind_reference<_Tp&&>(),
240 "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
242 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500243 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000244 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000245 : __value_(_VSTD::forward<_Tp>(__t))
Eric Fiselier869187d2018-01-24 22:14:01 +0000246 {static_assert(__can_bind_reference<_Tp&&>(),
247 "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000248
249 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500250 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000251 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000252 : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
Eric Fiselierca8bba12016-07-20 02:57:39 +0000253 {static_assert(!is_reference<_Hp>::value,
254 "Attempted to uses-allocator construct a reference element in a tuple");}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000255
256 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500257 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000258 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000259 : __value_(_VSTD::forward<_Tp>(__t), __a)
Eric Fiselierca8bba12016-07-20 02:57:39 +0000260 {static_assert(!is_reference<_Hp>::value,
261 "Attempted to uses-allocator construct a reference element in a tuple");}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262
Marshall Clow47fcee52014-04-21 23:48:09 +0000263 __tuple_leaf(const __tuple_leaf& __t) = default;
264 __tuple_leaf(__tuple_leaf&& __t) = default;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500266 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant89ef1212011-05-27 19:08:18 +0000267 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000269 _VSTD::swap(*this, __t);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000270 return 0;
271 }
272
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000273 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;}
274 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000275};
276
277template <size_t _Ip, class _Hp>
278class __tuple_leaf<_Ip, _Hp, true>
279 : private _Hp
280{
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500281 _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000282 __tuple_leaf& operator=(const __tuple_leaf&);
283public:
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500284 _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
Howard Hinnantaabb4202012-07-06 20:50:27 +0000285 _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000286
287 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500288 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
290
291 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500292 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000293 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
294 : _Hp(allocator_arg_t(), __a) {}
295
296 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500297 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000298 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
299 : _Hp(__a) {}
300
Howard Hinnant693fc212010-09-27 17:54:17 +0000301 template <class _Tp,
Eric Fiselier3906a132019-06-23 20:28:29 +0000302 class = _EnableIf<
303 _And<
304 _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
305 is_constructible<_Hp, _Tp>
306 >::value
307 >
Eric Fiselier42fa85e2014-07-24 18:48:34 +0000308 >
Marshall Clow2229cee2013-07-22 16:02:19 +0000309 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant62751642012-07-06 21:53:48 +0000310 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000311 : _Hp(_VSTD::forward<_Tp>(__t)) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312
313 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500314 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000315 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000316 : _Hp(_VSTD::forward<_Tp>(__t)) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317
318 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500319 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000321 : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000322
323 template <class _Tp, class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500324 _LIBCPP_INLINE_VISIBILITY constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000326 : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000327
Eric Fiselier42fa85e2014-07-24 18:48:34 +0000328 __tuple_leaf(__tuple_leaf const &) = default;
329 __tuple_leaf(__tuple_leaf &&) = default;
330
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500331 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant89ef1212011-05-27 19:08:18 +0000332 int
333 swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000334 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000335 _VSTD::swap(*this, __t);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000336 return 0;
337 }
338
Marshall Clow2229cee2013-07-22 16:02:19 +0000339 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return static_cast<_Hp&>(*this);}
340 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341};
342
Howard Hinnant1c265cd2010-09-23 18:58:28 +0000343template <class ..._Tp>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500344_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant62751642012-07-06 21:53:48 +0000345void __swallow(_Tp&&...) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000346
Marshall Clowc470eae2014-10-15 10:33:02 +0000347template <class _Tp>
348struct __all_default_constructible;
Howard Hinnant89ef1212011-05-27 19:08:18 +0000349
Marshall Clowc470eae2014-10-15 10:33:02 +0000350template <class ..._Tp>
351struct __all_default_constructible<__tuple_types<_Tp...>>
352 : __all<is_default_constructible<_Tp>::value...>
353{ };
Howard Hinnant89ef1212011-05-27 19:08:18 +0000354
Howard Hinnantc51e1022010-05-11 19:42:16 +0000355// __tuple_impl
356
357template<class _Indx, class ..._Tp> struct __tuple_impl;
358
359template<size_t ..._Indx, class ..._Tp>
Eric Fiseliere3cec5f2017-01-16 21:15:08 +0000360struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000361 : public __tuple_leaf<_Indx, _Tp>...
362{
Howard Hinnant38469632012-07-06 20:39:45 +0000363 _LIBCPP_INLINE_VISIBILITY
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500364 constexpr __tuple_impl()
Howard Hinnantaabb4202012-07-06 20:50:27 +0000365 _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
Howard Hinnant38469632012-07-06 20:39:45 +0000366
Howard Hinnantc51e1022010-05-11 19:42:16 +0000367 template <size_t ..._Uf, class ..._Tf,
368 size_t ..._Ul, class ..._Tl, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +0000369 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000370 explicit
371 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
372 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
Howard Hinnant62751642012-07-06 21:53:48 +0000373 _Up&&... __u)
374 _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
375 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000376 __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000377 __tuple_leaf<_Ul, _Tl>()...
378 {}
379
380 template <class _Alloc, size_t ..._Uf, class ..._Tf,
381 size_t ..._Ul, class ..._Tl, class ..._Up>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500382 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383 explicit
384 __tuple_impl(allocator_arg_t, const _Alloc& __a,
385 __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
386 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
387 _Up&&... __u) :
388 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000389 _VSTD::forward<_Up>(__u))...,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
391 {}
392
393 template <class _Tuple,
394 class = typename enable_if
395 <
Howard Hinnant6da16b82013-04-14 00:01:13 +0000396 __tuple_constructible<_Tuple, tuple<_Tp...> >::value
Howard Hinnantc51e1022010-05-11 19:42:16 +0000397 >::type
398 >
Marshall Clow2229cee2013-07-22 16:02:19 +0000399 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant62751642012-07-06 21:53:48 +0000400 __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
401 typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000402 : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
403 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
Howard Hinnantc51e1022010-05-11 19:42:16 +0000404 {}
405
406 template <class _Alloc, class _Tuple,
407 class = typename enable_if
408 <
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000409 __tuple_constructible<_Tuple, tuple<_Tp...> >::value
Howard Hinnantc51e1022010-05-11 19:42:16 +0000410 >::type
411 >
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500412 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000413 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
414 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000415 typename __make_tuple_types<_Tuple>::type>::type>(), __a,
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000416 _VSTD::forward<typename tuple_element<_Indx,
417 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
Howard Hinnantc51e1022010-05-11 19:42:16 +0000418 {}
419
Howard Hinnant0d032d12013-11-06 17:45:43 +0000420 __tuple_impl(const __tuple_impl&) = default;
421 __tuple_impl(__tuple_impl&&) = default;
422
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500423 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000424 void swap(__tuple_impl& __t)
Howard Hinnant89ef1212011-05-27 19:08:18 +0000425 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000426 {
Louis Dionne6c0d5342018-07-31 11:56:20 -0400427 _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000428 }
429};
430
Louis Dionne6c0d5342018-07-31 11:56:20 -0400431template<class _Dest, class _Source, size_t ..._Np>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500432_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Louis Dionne6c0d5342018-07-31 11:56:20 -0400433void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
434 _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
435}
Eric Fiselier264d04a2016-04-15 18:05:59 +0000436
Louis Dionne6c0d5342018-07-31 11:56:20 -0400437template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500438_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Louis Dionne6c0d5342018-07-31 11:56:20 -0400439void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
440 _VSTD::__swallow(((
Louis Dionne3b8af4d2021-02-24 14:53:21 -0500441 _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
Louis Dionne6c0d5342018-07-31 11:56:20 -0400442 ), void(), 0)...);
443}
Eric Fiselier264d04a2016-04-15 18:05:59 +0000444
Howard Hinnantc51e1022010-05-11 19:42:16 +0000445template <class ..._Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000446class _LIBCPP_TEMPLATE_VIS tuple
Howard Hinnantc51e1022010-05-11 19:42:16 +0000447{
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000448 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000449
Eric Fiselier3e0d4372017-06-01 02:14:21 +0000450 _BaseT __base_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000451
Marshall Clow0abb1042013-07-17 18:25:36 +0000452 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant28b24882011-12-01 20:21:04 +0000453 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
Marshall Clow0abb1042013-07-17 18:25:36 +0000454 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant28b24882011-12-01 20:21:04 +0000455 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
Marshall Clow0abb1042013-07-17 18:25:36 +0000456 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant28b24882011-12-01 20:21:04 +0000457 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
Eric Fiselier6dea8092015-12-18 00:36:55 +0000458 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
459 const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000460public:
Louis Dionne574e2e32021-02-10 16:19:50 -0500461 // [tuple.cnstr]
Howard Hinnantc51e1022010-05-11 19:42:16 +0000462
Louis Dionne574e2e32021-02-10 16:19:50 -0500463 // tuple() constructors (including allocator_arg_t variants)
464 template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
465 _And<
466 _IsImpDefault<_Tp>... // explicit check
467 >::value
468 , int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500469 _LIBCPP_INLINE_VISIBILITY constexpr
Louis Dionnea7a2beb2019-09-26 14:51:10 +0000470 tuple()
Louis Dionne574e2e32021-02-10 16:19:50 -0500471 _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
472 { }
Louis Dionnea7a2beb2019-09-26 14:51:10 +0000473
Louis Dionne574e2e32021-02-10 16:19:50 -0500474 template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
475 template<class...> class _IsDefault = is_default_constructible, _EnableIf<
476 _And<
477 _IsDefault<_Tp>...,
478 _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
479 >::value
480 , int> = 0>
481 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
482 explicit tuple()
483 _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
484 { }
Howard Hinnant38469632012-07-06 20:39:45 +0000485
Louis Dionne574e2e32021-02-10 16:19:50 -0500486 template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
487 _And<
488 _IsImpDefault<_Tp>... // explicit check
489 >::value
490 , int> = 0>
491 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
492 tuple(allocator_arg_t, _Alloc const& __a)
493 : __base_(allocator_arg_t(), __a,
494 __tuple_indices<>(), __tuple_types<>(),
495 typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
496 __tuple_types<_Tp...>()) {}
497
498 template <class _Alloc,
499 template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
500 template<class...> class _IsDefault = is_default_constructible, _EnableIf<
501 _And<
502 _IsDefault<_Tp>...,
503 _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
504 >::value
505 , int> = 0>
506 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
507 explicit tuple(allocator_arg_t, _Alloc const& __a)
508 : __base_(allocator_arg_t(), __a,
509 __tuple_indices<>(), __tuple_types<>(),
510 typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
511 __tuple_types<_Tp...>()) {}
512
513 // tuple(const T&...) constructors (including allocator_arg_t variants)
514 template <template<class...> class _And = _And, _EnableIf<
515 _And<
516 _BoolConstant<sizeof...(_Tp) >= 1>,
517 is_copy_constructible<_Tp>...,
518 is_convertible<const _Tp&, _Tp>... // explicit check
519 >::value
520 , int> = 0>
521 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
522 tuple(const _Tp& ... __t)
523 _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
524 : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
525 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
526 typename __make_tuple_indices<0>::type(),
527 typename __make_tuple_types<tuple, 0>::type(),
528 __t...
529 ) {}
530
531 template <template<class...> class _And = _And, _EnableIf<
532 _And<
533 _BoolConstant<sizeof...(_Tp) >= 1>,
534 is_copy_constructible<_Tp>...,
535 _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
536 >::value
537 , int> = 0>
538 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
539 explicit tuple(const _Tp& ... __t)
540 _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
541 : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
542 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
543 typename __make_tuple_indices<0>::type(),
544 typename __make_tuple_types<tuple, 0>::type(),
545 __t...
546 ) {}
547
548 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
549 _And<
550 _BoolConstant<sizeof...(_Tp) >= 1>,
551 is_copy_constructible<_Tp>...,
552 is_convertible<const _Tp&, _Tp>... // explicit check
553 >::value
554 , int> = 0>
555 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
556 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
557 : __base_(allocator_arg_t(), __a,
558 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
559 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
560 typename __make_tuple_indices<0>::type(),
561 typename __make_tuple_types<tuple, 0>::type(),
562 __t...
563 ) {}
564
565 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
566 _And<
567 _BoolConstant<sizeof...(_Tp) >= 1>,
568 is_copy_constructible<_Tp>...,
569 _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
570 >::value
571 , int> = 0>
572 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
573 explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
574 : __base_(allocator_arg_t(), __a,
575 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
576 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
577 typename __make_tuple_indices<0>::type(),
578 typename __make_tuple_types<tuple, 0>::type(),
579 __t...
580 ) {}
581
582 // tuple(U&& ...) constructors (including allocator_arg_t variants)
583 template <class ..._Up> struct _IsThisTuple : false_type { };
584 template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
585
586 template <class ..._Up>
587 struct _EnableUTypesCtor : _And<
588 _BoolConstant<sizeof...(_Tp) >= 1>,
589 _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
590 is_constructible<_Tp, _Up>...
591 > { };
592
593 template <class ..._Up, _EnableIf<
594 _And<
595 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
596 _EnableUTypesCtor<_Up...>,
597 is_convertible<_Up, _Tp>... // explicit check
598 >::value
599 , int> = 0>
600 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
601 tuple(_Up&&... __u)
602 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
603 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
604 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
605 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
606 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
607 _VSTD::forward<_Up>(__u)...) {}
608
609 template <class ..._Up, _EnableIf<
610 _And<
611 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
612 _EnableUTypesCtor<_Up...>,
613 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
614 >::value
615 , int> = 0>
616 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
617 explicit tuple(_Up&&... __u)
618 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
619 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
620 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
621 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
622 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
623 _VSTD::forward<_Up>(__u)...) {}
624
625 template <class _Alloc, class ..._Up, _EnableIf<
626 _And<
627 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
628 _EnableUTypesCtor<_Up...>,
629 is_convertible<_Up, _Tp>... // explicit check
630 >::value
631 , int> = 0>
632 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
633 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
634 : __base_(allocator_arg_t(), __a,
635 typename __make_tuple_indices<sizeof...(_Up)>::type(),
636 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
637 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
638 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
639 _VSTD::forward<_Up>(__u)...) {}
640
641 template <class _Alloc, class ..._Up, _EnableIf<
642 _And<
643 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
644 _EnableUTypesCtor<_Up...>,
645 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
646 >::value
647 , int> = 0>
648 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
649 explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
650 : __base_(allocator_arg_t(), __a,
651 typename __make_tuple_indices<sizeof...(_Up)>::type(),
652 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
653 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
654 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
655 _VSTD::forward<_Up>(__u)...) {}
656
657 // Copy and move constructors (including the allocator_arg_t variants)
658 tuple(const tuple&) = default;
Eric Fiselier737a16d2016-07-25 02:36:42 +0000659 tuple(tuple&&) = default;
660
Louis Dionne574e2e32021-02-10 16:19:50 -0500661 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
662 _And<is_copy_constructible<_Tp>...>::value
663 , int> = 0>
664 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
665 : __base_(allocator_arg_t(), __alloc, __t)
666 { }
667
668 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
669 _And<is_move_constructible<_Tp>...>::value
670 , int> = 0>
671 tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
672 : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
673 { }
674
675 // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
676 template <class ..._Up>
677 struct _EnableCopyFromOtherTuple : _And<
678 _Or<
679 _BoolConstant<sizeof...(_Tp) != 1>,
680 // _Tp and _Up are 1-element packs - the pack expansions look
681 // weird to avoid tripping up the type traits in degenerate cases
682 _Lazy<_And,
683 _Not<is_same<_Tp, _Up> >...,
684 _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
685 _Not<is_constructible<_Tp, const tuple<_Up>&> >...
686 >
687 >,
688 is_constructible<_Tp, const _Up&>...
689 > { };
690
691 template <class ..._Up, _EnableIf<
692 _And<
693 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
694 _EnableCopyFromOtherTuple<_Up...>,
695 is_convertible<const _Up&, _Tp>... // explicit check
696 >::value
697 , int> = 0>
698 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
699 tuple(const tuple<_Up...>& __t)
700 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
701 : __base_(__t)
702 { }
703
704 template <class ..._Up, _EnableIf<
705 _And<
706 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
707 _EnableCopyFromOtherTuple<_Up...>,
708 _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
709 >::value
710 , int> = 0>
711 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
712 explicit tuple(const tuple<_Up...>& __t)
713 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
714 : __base_(__t)
715 { }
716
717 template <class ..._Up, class _Alloc, _EnableIf<
718 _And<
719 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
720 _EnableCopyFromOtherTuple<_Up...>,
721 is_convertible<const _Up&, _Tp>... // explicit check
722 >::value
723 , int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500724 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne574e2e32021-02-10 16:19:50 -0500725 tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
726 : __base_(allocator_arg_t(), __a, __t)
727 { }
Eric Fiselierc170df52016-04-15 03:29:40 +0000728
Louis Dionne574e2e32021-02-10 16:19:50 -0500729 template <class ..._Up, class _Alloc, _EnableIf<
730 _And<
731 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
732 _EnableCopyFromOtherTuple<_Up...>,
733 _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
734 >::value
735 , int> = 0>
736 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
737 explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
738 : __base_(allocator_arg_t(), __a, __t)
739 { }
Louis Dionne668a50c2019-09-27 15:06:52 +0000740
Louis Dionne574e2e32021-02-10 16:19:50 -0500741 // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
742 template <class ..._Up>
743 struct _EnableMoveFromOtherTuple : _And<
744 _Or<
745 _BoolConstant<sizeof...(_Tp) != 1>,
746 // _Tp and _Up are 1-element packs - the pack expansions look
747 // weird to avoid tripping up the type traits in degenerate cases
748 _Lazy<_And,
749 _Not<is_same<_Tp, _Up> >...,
750 _Not<is_convertible<tuple<_Up>, _Tp> >...,
751 _Not<is_constructible<_Tp, tuple<_Up> > >...
752 >
753 >,
754 is_constructible<_Tp, _Up>...
755 > { };
756
757 template <class ..._Up, _EnableIf<
758 _And<
759 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
760 _EnableMoveFromOtherTuple<_Up...>,
761 is_convertible<_Up, _Tp>... // explicit check
762 >::value
763 , int> = 0>
Marshall Clow2229cee2013-07-22 16:02:19 +0000764 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Louis Dionne574e2e32021-02-10 16:19:50 -0500765 tuple(tuple<_Up...>&& __t)
766 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
767 : __base_(_VSTD::move(__t))
768 { }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000769
Louis Dionne574e2e32021-02-10 16:19:50 -0500770 template <class ..._Up, _EnableIf<
771 _And<
772 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
773 _EnableMoveFromOtherTuple<_Up...>,
774 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
775 >::value
776 , int> = 0>
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000777 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Louis Dionne574e2e32021-02-10 16:19:50 -0500778 explicit tuple(tuple<_Up...>&& __t)
779 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
780 : __base_(_VSTD::move(__t))
781 { }
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000782
Louis Dionne574e2e32021-02-10 16:19:50 -0500783 template <class _Alloc, class ..._Up, _EnableIf<
784 _And<
785 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
786 _EnableMoveFromOtherTuple<_Up...>,
787 is_convertible<_Up, _Tp>... // explicit check
788 >::value
789 , int> = 0>
790 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
791 tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
792 : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
793 { }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000794
Louis Dionne574e2e32021-02-10 16:19:50 -0500795 template <class _Alloc, class ..._Up, _EnableIf<
796 _And<
797 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
798 _EnableMoveFromOtherTuple<_Up...>,
799 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
800 >::value
801 , int> = 0>
802 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
803 explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
804 : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
805 { }
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000806
Louis Dionne574e2e32021-02-10 16:19:50 -0500807 // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
808 template <class _Up1, class _Up2, class ..._DependentTp>
809 struct _EnableImplicitCopyFromPair : _And<
810 is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
811 is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
812 is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
813 is_convertible<const _Up2&, _SecondType<_DependentTp...> >
814 > { };
Howard Hinnant65704d02012-04-01 23:10:42 +0000815
Louis Dionne574e2e32021-02-10 16:19:50 -0500816 template <class _Up1, class _Up2, class ..._DependentTp>
817 struct _EnableExplicitCopyFromPair : _And<
818 is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
819 is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
820 _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
821 _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
822 > { };
Howard Hinnantc51e1022010-05-11 19:42:16 +0000823
Louis Dionne574e2e32021-02-10 16:19:50 -0500824 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
825 _And<
826 _BoolConstant<sizeof...(_Tp) == 2>,
827 _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
828 >::value
829 , int> = 0>
830 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
831 tuple(const pair<_Up1, _Up2>& __p)
832 _NOEXCEPT_((_And<
833 is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
834 is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
835 >::value))
836 : __base_(__p)
837 { }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000838
Louis Dionne574e2e32021-02-10 16:19:50 -0500839 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
840 _And<
841 _BoolConstant<sizeof...(_Tp) == 2>,
842 _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
843 >::value
844 , int> = 0>
845 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
846 explicit tuple(const pair<_Up1, _Up2>& __p)
847 _NOEXCEPT_((_And<
848 is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
849 is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
850 >::value))
851 : __base_(__p)
852 { }
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000853
Louis Dionne574e2e32021-02-10 16:19:50 -0500854 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
855 _And<
856 _BoolConstant<sizeof...(_Tp) == 2>,
857 _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
858 >::value
859 , int> = 0>
860 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
861 tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
862 : __base_(allocator_arg_t(), __a, __p)
863 { }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000864
Louis Dionne574e2e32021-02-10 16:19:50 -0500865 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
866 _And<
867 _BoolConstant<sizeof...(_Tp) == 2>,
868 _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
869 >::value
870 , int> = 0>
871 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
872 explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
873 : __base_(allocator_arg_t(), __a, __p)
874 { }
Howard Hinnant65704d02012-04-01 23:10:42 +0000875
Louis Dionne574e2e32021-02-10 16:19:50 -0500876 // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
877 template <class _Up1, class _Up2, class ..._DependentTp>
878 struct _EnableImplicitMoveFromPair : _And<
879 is_constructible<_FirstType<_DependentTp...>, _Up1>,
880 is_constructible<_SecondType<_DependentTp...>, _Up2>,
881 is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
882 is_convertible<_Up2, _SecondType<_DependentTp...> >
883 > { };
Eric Fiselierec5a2102019-07-12 23:01:48 +0000884
Louis Dionne574e2e32021-02-10 16:19:50 -0500885 template <class _Up1, class _Up2, class ..._DependentTp>
886 struct _EnableExplicitMoveFromPair : _And<
887 is_constructible<_FirstType<_DependentTp...>, _Up1>,
888 is_constructible<_SecondType<_DependentTp...>, _Up2>,
889 _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
890 _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
891 > { };
Howard Hinnantc51e1022010-05-11 19:42:16 +0000892
Louis Dionne574e2e32021-02-10 16:19:50 -0500893 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
894 _And<
895 _BoolConstant<sizeof...(_Tp) == 2>,
896 _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
897 >::value
898 , int> = 0>
899 _LIBCPP_INLINE_VISIBILITY
900 tuple(pair<_Up1, _Up2>&& __p)
901 _NOEXCEPT_((_And<
902 is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
903 is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
904 >::value))
905 : __base_(_VSTD::move(__p))
906 { }
907
908 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
909 _And<
910 _BoolConstant<sizeof...(_Tp) == 2>,
911 _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
912 >::value
913 , int> = 0>
914 _LIBCPP_INLINE_VISIBILITY
915 explicit tuple(pair<_Up1, _Up2>&& __p)
916 _NOEXCEPT_((_And<
917 is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
918 is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
919 >::value))
920 : __base_(_VSTD::move(__p))
921 { }
922
923 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
924 _And<
925 _BoolConstant<sizeof...(_Tp) == 2>,
926 _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
927 >::value
928 , int> = 0>
929 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
930 tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
931 : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
932 { }
933
934 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
935 _And<
936 _BoolConstant<sizeof...(_Tp) == 2>,
937 _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
938 >::value
939 , int> = 0>
940 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
941 explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
942 : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
943 { }
Eric Fiselier8e6a5f02016-04-19 01:19:25 +0000944
Louis Dionne6c0d5342018-07-31 11:56:20 -0400945 // [tuple.assign]
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500946 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -0400947 tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
948 _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
Eric Fiselier737a16d2016-07-25 02:36:42 +0000949 {
Louis Dionne6c0d5342018-07-31 11:56:20 -0400950 _VSTD::__memberwise_copy_assign(*this, __tuple,
951 typename __make_tuple_indices<sizeof...(_Tp)>::type());
Eric Fiselier737a16d2016-07-25 02:36:42 +0000952 return *this;
953 }
954
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500955 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -0400956 tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
957 _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
Eric Fiselier737a16d2016-07-25 02:36:42 +0000958 {
Louis Dionne6c0d5342018-07-31 11:56:20 -0400959 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
960 __tuple_types<_Tp...>(),
961 typename __make_tuple_indices<sizeof...(_Tp)>::type());
Eric Fiselier737a16d2016-07-25 02:36:42 +0000962 return *this;
963 }
964
Louis Dionne6c0d5342018-07-31 11:56:20 -0400965 template<class... _Up, _EnableIf<
966 _And<
967 _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
968 is_assignable<_Tp&, _Up const&>...
969 >::value
970 ,int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500971 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -0400972 tuple& operator=(tuple<_Up...> const& __tuple)
973 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
974 {
975 _VSTD::__memberwise_copy_assign(*this, __tuple,
976 typename __make_tuple_indices<sizeof...(_Tp)>::type());
977 return *this;
978 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000979
Louis Dionne6c0d5342018-07-31 11:56:20 -0400980 template<class... _Up, _EnableIf<
981 _And<
982 _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
983 is_assignable<_Tp&, _Up>...
984 >::value
985 ,int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -0500986 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -0400987 tuple& operator=(tuple<_Up...>&& __tuple)
988 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
989 {
990 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
991 __tuple_types<_Up...>(),
992 typename __make_tuple_indices<sizeof...(_Tp)>::type());
993 return *this;
994 }
995
996 template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
997 _And<_Dep,
998 _BoolConstant<sizeof...(_Tp) == 2>,
999 is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1000 is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1001 >::value
1002 ,int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001003 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -04001004 tuple& operator=(pair<_Up1, _Up2> const& __pair)
1005 _NOEXCEPT_((_And<
1006 is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1007 is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1008 >::value))
1009 {
1010 _VSTD::get<0>(*this) = __pair.first;
1011 _VSTD::get<1>(*this) = __pair.second;
1012 return *this;
1013 }
1014
1015 template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1016 _And<_Dep,
1017 _BoolConstant<sizeof...(_Tp) == 2>,
1018 is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1019 is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1020 >::value
1021 ,int> = 0>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001022 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -04001023 tuple& operator=(pair<_Up1, _Up2>&& __pair)
1024 _NOEXCEPT_((_And<
1025 is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1026 is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1027 >::value))
1028 {
Louis Dionne3b8af4d2021-02-24 14:53:21 -05001029 _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1030 _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
Louis Dionne6c0d5342018-07-31 11:56:20 -04001031 return *this;
1032 }
1033
1034 // EXTENSION
1035 template<class _Up, size_t _Np, class = _EnableIf<
1036 _And<
1037 _BoolConstant<_Np == sizeof...(_Tp)>,
1038 is_assignable<_Tp&, _Up const&>...
1039 >::value
1040 > >
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001041 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -04001042 tuple& operator=(array<_Up, _Np> const& __array)
1043 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1044 {
1045 _VSTD::__memberwise_copy_assign(*this, __array,
1046 typename __make_tuple_indices<sizeof...(_Tp)>::type());
1047 return *this;
1048 }
1049
1050 // EXTENSION
1051 template<class _Up, size_t _Np, class = void, class = _EnableIf<
1052 _And<
1053 _BoolConstant<_Np == sizeof...(_Tp)>,
1054 is_assignable<_Tp&, _Up>...
1055 >::value
1056 > >
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001057 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Louis Dionne6c0d5342018-07-31 11:56:20 -04001058 tuple& operator=(array<_Up, _Np>&& __array)
1059 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1060 {
1061 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1062 __tuple_types<_If<true, _Up, _Tp>...>(),
1063 typename __make_tuple_indices<sizeof...(_Tp)>::type());
1064 return *this;
1065 }
1066
1067 // [tuple.swap]
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001068 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant89ef1212011-05-27 19:08:18 +00001069 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
Eric Fiselier3e0d4372017-06-01 02:14:21 +00001070 {__base_.swap(__t.__base_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001071};
1072
1073template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001074class _LIBCPP_TEMPLATE_VIS tuple<>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001075{
1076public:
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001077 _LIBCPP_INLINE_VISIBILITY constexpr
1078 tuple() _NOEXCEPT = default;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001079 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001080 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant62751642012-07-06 21:53:48 +00001081 tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001082 template <class _Alloc>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001083 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant62751642012-07-06 21:53:48 +00001084 tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001085 template <class _Up>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001086 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant62751642012-07-06 21:53:48 +00001087 tuple(array<_Up, 0>) _NOEXCEPT {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001088 template <class _Alloc, class _Up>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001089 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant62751642012-07-06 21:53:48 +00001090 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001091 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant89ef1212011-05-27 19:08:18 +00001092 void swap(tuple&) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093};
1094
Eric Fiselier8df4ac62017-10-04 00:04:26 +00001095#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
Louis Dionne616da2a2019-08-12 18:30:31 +00001096template <class ..._Tp>
1097tuple(_Tp...) -> tuple<_Tp...>;
1098template <class _Tp1, class _Tp2>
1099tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1100template <class _Alloc, class ..._Tp>
1101tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1102template <class _Alloc, class _Tp1, class _Tp2>
1103tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1104template <class _Alloc, class ..._Tp>
1105tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
Eric Fiselier9a5075c2017-06-08 07:18:17 +00001106#endif
1107
Howard Hinnantc51e1022010-05-11 19:42:16 +00001108template <class ..._Tp>
Arthur O'Dwyer20638cc2021-02-09 19:12:16 -05001109inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant44267242011-06-01 19:59:32 +00001110typename enable_if
1111<
1112 __all<__is_swappable<_Tp>::value...>::value,
1113 void
1114>::type
Howard Hinnant89ef1212011-05-27 19:08:18 +00001115swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
1116 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1117 {__t.swap(__u);}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001118
1119// get
1120
1121template <size_t _Ip, class ..._Tp>
Marshall Clow0abb1042013-07-17 18:25:36 +00001122inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant3a47c3d2011-01-24 16:07:25 +00001123typename tuple_element<_Ip, tuple<_Tp...> >::type&
Howard Hinnant28b24882011-12-01 20:21:04 +00001124get(tuple<_Tp...>& __t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001125{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001126 typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Eric Fiselier3e0d4372017-06-01 02:14:21 +00001127 return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001128}
1129
1130template <size_t _Ip, class ..._Tp>
Marshall Clow0abb1042013-07-17 18:25:36 +00001131inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant3a47c3d2011-01-24 16:07:25 +00001132const typename tuple_element<_Ip, tuple<_Tp...> >::type&
Howard Hinnant28b24882011-12-01 20:21:04 +00001133get(const tuple<_Tp...>& __t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001134{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001135 typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Eric Fiselier3e0d4372017-06-01 02:14:21 +00001136 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001137}
1138
Howard Hinnant22e97242010-11-17 19:52:17 +00001139template <size_t _Ip, class ..._Tp>
Marshall Clow0abb1042013-07-17 18:25:36 +00001140inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant3a47c3d2011-01-24 16:07:25 +00001141typename tuple_element<_Ip, tuple<_Tp...> >::type&&
Howard Hinnant28b24882011-12-01 20:21:04 +00001142get(tuple<_Tp...>&& __t) _NOEXCEPT
Howard Hinnant22e97242010-11-17 19:52:17 +00001143{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001144 typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Howard Hinnantb574f9a2011-01-25 16:31:30 +00001145 return static_cast<type&&>(
Eric Fiselier3e0d4372017-06-01 02:14:21 +00001146 static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
Howard Hinnant22e97242010-11-17 19:52:17 +00001147}
1148
Eric Fiselier6dea8092015-12-18 00:36:55 +00001149template <size_t _Ip, class ..._Tp>
1150inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1151const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1152get(const tuple<_Tp...>&& __t) _NOEXCEPT
1153{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001154 typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Eric Fiselier6dea8092015-12-18 00:36:55 +00001155 return static_cast<const type&&>(
Eric Fiselier3e0d4372017-06-01 02:14:21 +00001156 static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
Eric Fiselier6dea8092015-12-18 00:36:55 +00001157}
1158
Marshall Clow15b02e02013-07-13 02:54:05 +00001159#if _LIBCPP_STD_VER > 11
Marshall Clow15b02e02013-07-13 02:54:05 +00001160
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001161namespace __find_detail {
Marshall Clow15b02e02013-07-13 02:54:05 +00001162
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001163static constexpr size_t __not_found = -1;
1164static constexpr size_t __ambiguous = __not_found - 1;
Marshall Clow15b02e02013-07-13 02:54:05 +00001165
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001166inline _LIBCPP_INLINE_VISIBILITY
1167constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1168 return !__matches ? __res :
1169 (__res == __not_found ? __curr_i : __ambiguous);
1170}
Marshall Clow15b02e02013-07-13 02:54:05 +00001171
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001172template <size_t _Nx>
1173inline _LIBCPP_INLINE_VISIBILITY
1174constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1175 return __i == _Nx ? __not_found :
1176 __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1177}
1178
1179template <class _T1, class ..._Args>
1180struct __find_exactly_one_checked {
Casey Carter7b5a7482017-12-12 17:22:24 +00001181 static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001182 static constexpr size_t value = __find_detail::__find_idx(0, __matches);
Casey Carter7b5a7482017-12-12 17:22:24 +00001183 static_assert(value != __not_found, "type not found in type list" );
1184 static_assert(value != __ambiguous, "type occurs more than once in type list");
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001185};
1186
Eric Fiselier8087d302016-07-02 03:46:08 +00001187template <class _T1>
1188struct __find_exactly_one_checked<_T1> {
1189 static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
1190};
1191
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001192} // namespace __find_detail;
Marshall Clow15b02e02013-07-13 02:54:05 +00001193
1194template <typename _T1, typename... _Args>
Eric Fiselier2d0e2042016-07-02 03:18:30 +00001195struct __find_exactly_one_t
1196 : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1197};
Marshall Clow15b02e02013-07-13 02:54:05 +00001198
1199template <class _T1, class... _Args>
1200inline _LIBCPP_INLINE_VISIBILITY
1201constexpr _T1& get(tuple<_Args...>& __tup) noexcept
1202{
1203 return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1204}
1205
1206template <class _T1, class... _Args>
1207inline _LIBCPP_INLINE_VISIBILITY
1208constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1209{
1210 return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1211}
1212
1213template <class _T1, class... _Args>
1214inline _LIBCPP_INLINE_VISIBILITY
1215constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1216{
Marshall Clowfe9aa372013-07-15 20:46:11 +00001217 return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
Marshall Clow15b02e02013-07-13 02:54:05 +00001218}
1219
Eric Fiselier6dea8092015-12-18 00:36:55 +00001220template <class _T1, class... _Args>
1221inline _LIBCPP_INLINE_VISIBILITY
1222constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1223{
1224 return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1225}
1226
Marshall Clow15b02e02013-07-13 02:54:05 +00001227#endif
1228
Howard Hinnantc51e1022010-05-11 19:42:16 +00001229// tie
1230
1231template <class ..._Tp>
Marshall Clowa8892812014-02-25 16:11:46 +00001232inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001233tuple<_Tp&...>
Howard Hinnant62751642012-07-06 21:53:48 +00001234tie(_Tp&... __t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001235{
1236 return tuple<_Tp&...>(__t...);
1237}
1238
1239template <class _Up>
1240struct __ignore_t
1241{
Howard Hinnantc51e1022010-05-11 19:42:16 +00001242 template <class _Tp>
Eric Fiselier24e70262017-02-06 01:25:31 +00001243 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1244 const __ignore_t& operator=(_Tp&&) const {return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001245};
1246
Eric Fiselier24e70262017-02-06 01:25:31 +00001247namespace {
Marshall Clowf1bf62f2018-01-02 17:17:01 +00001248 _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
Eric Fiselier24e70262017-02-06 01:25:31 +00001249}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001250
Howard Hinnantc51e1022010-05-11 19:42:16 +00001251template <class... _Tp>
Marshall Clow2229cee2013-07-22 16:02:19 +00001252inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Louis Dionnedb1892a2018-12-03 14:03:27 +00001253tuple<typename __unwrap_ref_decay<_Tp>::type...>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001254make_tuple(_Tp&&... __t)
1255{
Louis Dionnedb1892a2018-12-03 14:03:27 +00001256 return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001257}
1258
Howard Hinnant3d203a32010-08-19 18:59:38 +00001259template <class... _Tp>
Marshall Clow2229cee2013-07-22 16:02:19 +00001260inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1261tuple<_Tp&&...>
Howard Hinnant62751642012-07-06 21:53:48 +00001262forward_as_tuple(_Tp&&... __t) _NOEXCEPT
Howard Hinnant3d203a32010-08-19 18:59:38 +00001263{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001264 return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
Howard Hinnant3d203a32010-08-19 18:59:38 +00001265}
1266
Howard Hinnantc834c512011-11-29 18:15:50 +00001267template <size_t _Ip>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001268struct __tuple_equal
1269{
1270 template <class _Tp, class _Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001271 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001272 bool operator()(const _Tp& __x, const _Up& __y)
1273 {
Marshall Clow60e4aa72014-06-24 00:46:19 +00001274 return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001275 }
1276};
1277
1278template <>
1279struct __tuple_equal<0>
1280{
1281 template <class _Tp, class _Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001282 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001283 bool operator()(const _Tp&, const _Up&)
1284 {
1285 return true;
1286 }
1287};
1288
1289template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001290inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001291bool
1292operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1293{
Marshall Clow8ee1ddd2019-02-07 19:03:48 +00001294 static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001295 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1296}
1297
1298template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001299inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001300bool
1301operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1302{
1303 return !(__x == __y);
1304}
1305
Howard Hinnantc834c512011-11-29 18:15:50 +00001306template <size_t _Ip>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001307struct __tuple_less
1308{
1309 template <class _Tp, class _Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001310 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001311 bool operator()(const _Tp& __x, const _Up& __y)
1312 {
Duncan P. N. Exon Smith6d3ec092015-01-21 02:51:17 +00001313 const size_t __idx = tuple_size<_Tp>::value - _Ip;
1314 if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
1315 return true;
1316 if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
1317 return false;
1318 return __tuple_less<_Ip-1>()(__x, __y);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001319 }
1320};
1321
1322template <>
1323struct __tuple_less<0>
1324{
1325 template <class _Tp, class _Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001326 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001327 bool operator()(const _Tp&, const _Up&)
1328 {
1329 return false;
1330 }
1331};
1332
1333template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001334inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001335bool
1336operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1337{
Marshall Clow8ee1ddd2019-02-07 19:03:48 +00001338 static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001339 return __tuple_less<sizeof...(_Tp)>()(__x, __y);
1340}
1341
1342template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001343inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001344bool
1345operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1346{
1347 return __y < __x;
1348}
1349
1350template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001351inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001352bool
1353operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1354{
1355 return !(__x < __y);
1356}
1357
1358template <class ..._Tp, class ..._Up>
Marshall Clow2229cee2013-07-22 16:02:19 +00001359inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001360bool
1361operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1362{
1363 return !(__y < __x);
1364}
1365
1366// tuple_cat
1367
Howard Hinnant6256ee72010-12-11 20:47:50 +00001368template <class _Tp, class _Up> struct __tuple_cat_type;
1369
1370template <class ..._Ttypes, class ..._Utypes>
Howard Hinnant3a47c3d2011-01-24 16:07:25 +00001371struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
Howard Hinnantc51e1022010-05-11 19:42:16 +00001372{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001373 typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type;
Howard Hinnant6256ee72010-12-11 20:47:50 +00001374};
1375
1376template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1377struct __tuple_cat_return_1
1378{
1379};
1380
1381template <class ..._Types, class _Tuple0>
1382struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1383{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001384 typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>,
Eric Fiselier0c8de4b2019-04-26 01:02:18 +00001385 typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
Howard Hinnant6256ee72010-12-11 20:47:50 +00001386 type;
1387};
1388
1389template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1390struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1391 : public __tuple_cat_return_1<
1392 typename __tuple_cat_type<
1393 tuple<_Types...>,
Eric Fiselier0c8de4b2019-04-26 01:02:18 +00001394 typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
Howard Hinnant6256ee72010-12-11 20:47:50 +00001395 >::type,
1396 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1397 _Tuple1, _Tuples...>
1398{
1399};
1400
1401template <class ..._Tuples> struct __tuple_cat_return;
1402
1403template <class _Tuple0, class ..._Tuples>
1404struct __tuple_cat_return<_Tuple0, _Tuples...>
1405 : public __tuple_cat_return_1<tuple<>,
1406 __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1407 _Tuples...>
1408{
1409};
1410
1411template <>
1412struct __tuple_cat_return<>
1413{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001414 typedef _LIBCPP_NODEBUG_TYPE tuple<> type;
Howard Hinnant6256ee72010-12-11 20:47:50 +00001415};
1416
Marshall Clow2229cee2013-07-22 16:02:19 +00001417inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant6256ee72010-12-11 20:47:50 +00001418tuple<>
1419tuple_cat()
1420{
1421 return tuple<>();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001422}
1423
Howard Hinnantc834c512011-11-29 18:15:50 +00001424template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
Howard Hinnant21376f62010-12-12 23:04:37 +00001425struct __tuple_cat_return_ref_imp;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001426
Howard Hinnant21376f62010-12-12 23:04:37 +00001427template <class ..._Types, size_t ..._I0, class _Tuple0>
1428struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001429{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001430 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
Howard Hinnant21376f62010-12-12 23:04:37 +00001431 typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1432 typename tuple_element<_I0, _T0>::type>::type&&...> type;
1433};
Howard Hinnantc51e1022010-05-11 19:42:16 +00001434
Howard Hinnant21376f62010-12-12 23:04:37 +00001435template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1436struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1437 _Tuple0, _Tuple1, _Tuples...>
1438 : public __tuple_cat_return_ref_imp<
1439 tuple<_Types..., typename __apply_cv<_Tuple0,
1440 typename tuple_element<_I0,
1441 typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1442 typename __make_tuple_indices<tuple_size<typename
1443 remove_reference<_Tuple1>::type>::value>::type,
1444 _Tuple1, _Tuples...>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001445{
Howard Hinnant21376f62010-12-12 23:04:37 +00001446};
1447
1448template <class _Tuple0, class ..._Tuples>
1449struct __tuple_cat_return_ref
1450 : public __tuple_cat_return_ref_imp<tuple<>,
1451 typename __make_tuple_indices<
1452 tuple_size<typename remove_reference<_Tuple0>::type>::value
1453 >::type, _Tuple0, _Tuples...>
1454{
1455};
1456
1457template <class _Types, class _I0, class _J0>
1458struct __tuple_cat;
1459
1460template <class ..._Types, size_t ..._I0, size_t ..._J0>
Howard Hinnant3a47c3d2011-01-24 16:07:25 +00001461struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
Howard Hinnant21376f62010-12-12 23:04:37 +00001462{
1463 template <class _Tuple0>
Marshall Clow2229cee2013-07-22 16:02:19 +00001464 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant21376f62010-12-12 23:04:37 +00001465 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1466 operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1467 {
David Blaikie699a5e22019-10-28 18:03:59 -07001468 return _VSTD::forward_as_tuple(
1469 _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1470 _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
Howard Hinnant21376f62010-12-12 23:04:37 +00001471 }
1472
1473 template <class _Tuple0, class _Tuple1, class ..._Tuples>
Marshall Clow2229cee2013-07-22 16:02:19 +00001474 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant21376f62010-12-12 23:04:37 +00001475 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1476 operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1477 {
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001478 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1479 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1;
Howard Hinnant21376f62010-12-12 23:04:37 +00001480 return __tuple_cat<
David Blaikie699a5e22019-10-28 18:03:59 -07001481 tuple<_Types...,
1482 typename __apply_cv<_Tuple0, typename tuple_element<
1483 _J0, _T0>::type>::type&&...>,
1484 typename __make_tuple_indices<sizeof...(_Types) +
1485 tuple_size<_T0>::value>::type,
1486 typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1487 _VSTD::forward_as_tuple(
1488 _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1489 _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1490 _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
Howard Hinnant21376f62010-12-12 23:04:37 +00001491 }
1492};
1493
1494template <class _Tuple0, class... _Tuples>
Marshall Clow2229cee2013-07-22 16:02:19 +00001495inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnant21376f62010-12-12 23:04:37 +00001496typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1497tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1498{
Eric Fiselier4fc82a22019-06-12 02:03:31 +00001499 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
Howard Hinnant21376f62010-12-12 23:04:37 +00001500 return __tuple_cat<tuple<>, __tuple_indices<>,
1501 typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001502 (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1503 _VSTD::forward<_Tuples>(__tpls)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001504}
1505
1506template <class ..._Tp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001507struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001508 : true_type {};
1509
Howard Hinnantc51e1022010-05-11 19:42:16 +00001510template <class _T1, class _T2>
1511template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
Michael Schellenberger Costad41ace62020-09-02 21:20:33 +02001512inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnantc51e1022010-05-11 19:42:16 +00001513pair<_T1, _T2>::pair(piecewise_construct_t,
1514 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1515 __tuple_indices<_I1...>, __tuple_indices<_I2...>)
Marshall Clow60e4aa72014-06-24 00:46:19 +00001516 : first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1517 second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001518{
1519}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001520
Eric Fiselier8e892c52016-07-18 00:35:56 +00001521#if _LIBCPP_STD_VER > 14
1522template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +00001523_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
Eric Fiselier8e892c52016-07-18 00:35:56 +00001524
1525#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
1526
1527template <class _Fn, class _Tuple, size_t ..._Id>
1528inline _LIBCPP_INLINE_VISIBILITY
1529constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
1530 __tuple_indices<_Id...>)
1531_LIBCPP_NOEXCEPT_RETURN(
1532 _VSTD::__invoke_constexpr(
1533 _VSTD::forward<_Fn>(__f),
1534 _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
1535)
1536
1537template <class _Fn, class _Tuple>
1538inline _LIBCPP_INLINE_VISIBILITY
1539constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
1540_LIBCPP_NOEXCEPT_RETURN(
1541 _VSTD::__apply_tuple_impl(
1542 _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
Marshall Clowd5bbc242018-02-06 20:56:55 +00001543 typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
Eric Fiselier8e892c52016-07-18 00:35:56 +00001544)
1545
1546template <class _Tp, class _Tuple, size_t... _Idx>
1547inline _LIBCPP_INLINE_VISIBILITY
1548constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1549_LIBCPP_NOEXCEPT_RETURN(
1550 _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
1551)
1552
1553template <class _Tp, class _Tuple>
1554inline _LIBCPP_INLINE_VISIBILITY
1555constexpr _Tp make_from_tuple(_Tuple&& __t)
1556_LIBCPP_NOEXCEPT_RETURN(
1557 _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
Marshall Clowd5bbc242018-02-06 20:56:55 +00001558 typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
Eric Fiselier8e892c52016-07-18 00:35:56 +00001559)
1560
1561#undef _LIBCPP_NOEXCEPT_RETURN
1562
1563#endif // _LIBCPP_STD_VER > 14
1564
Eric Fiselierffe4aba2017-04-19 01:23:39 +00001565#endif // !defined(_LIBCPP_CXX03_LANG)
1566
Howard Hinnantc51e1022010-05-11 19:42:16 +00001567_LIBCPP_END_NAMESPACE_STD
1568
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001569#endif // _LIBCPP_TUPLE