Skip to content

Commit 83ead2b

Browse files
committed
[libc++] implement "pair" section of P2321R2 zip
Differential Revision: https://reviews.llvm.org/D131495
1 parent 926ccfe commit 83ead2b

27 files changed

+962
-174
lines changed

libcxx/docs/Status/ZipProjects.csv

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
Section,Description,Dependencies,Assignee,Complete
22
| `[tuple.syn] <https://wg21.link/tuple.syn>`_, "`[tuple] basic_common_reference, common_type <https://reviews.llvm.org/D116538>`_", None, Nikolas Klauser, |Complete|
3-
| `[tuple.tuple] <https://wg21.link/tuple.tuple>`_, "`[tuple] constructor, assignment and swap overloads <https://reviews.llvm.org/D116621>`_", None, Nikolas Klauser, |In Progress|
3+
| `[tuple.tuple] <https://wg21.link/tuple.tuple>`_, "`[tuple] constructor, assignment and swap overloads <https://reviews.llvm.org/D116621>`_", None, Hui Xie, |Complete|
44
| `[utility.syn] <https://wg21.link/utility.syn>`_, "[pair] basic_common_reference, common_type", None, Nikolas Klauser, |Complete|
5-
| `[pairs.pair] <https://wg21.link/pairs.pair>`_, "[pair] constructor, assignment and swap overloads", None, Nikolas Klauser, |Not Started|
5+
| `[pairs.pair] <https://wg21.link/pairs.pair>`_, "`[pair] constructor, assignment and swap overloads <https://reviews.llvm.org/D131495>`_", None, Hui Xie, |Complete|
66
"| `[memory.syn] <https://wg21.link/memory.syn>`_
77
| `[allocator.uses.construction] <https://wg21.link/allocator.uses.construction>`_", "[pair] uses_allocator_construction_args overloads", None, Unassigned, |Not Started|
8-
| `[vector.bool] <https://wg21.link/vector.bool>`_, "[vector<bool>::reference] add const operator= overload", None, Nikolas Klauser, |Not Started|
9-
| `[iterator.concept.winc] <https://wg21.link/iterator.concept.winc>`_, "Update weakly_comparable", None, Unassigned, |Not Started|
8+
| `[vector.bool] <https://wg21.link/vector.bool>`_, "[vector<bool>::reference] add const operator= overload", None, Hui Xie, |Not Started|
9+
| `[iterator.concept.winc] <https://wg21.link/iterator.concept.winc>`_, "Update weakly_comparable", None, Hui Xie, |Not Started|
1010
| `[range.zip] <https://wg21.link/ranges.syn>`_, "`zip_view <https://reviews.llvm.org/D122806>`_", "| `zip_view::iterator`
1111
| `zip_view::sentinel`", Hui Xie, |Complete|
1212
| `[range.zip.iterator] <https://wg21.link/range.zip.iterator>`_, "`zip_view::iterator <https://reviews.llvm.org/D122806>`_", None, Hui Xie, |Complete|
1313
| `[range.zip.sentinel] <https://wg21.link/range.zip.sentinel>`_, "`zip_view::sentinel <https://reviews.llvm.org/D122806>`_", None, Hui Xie, |Complete|
1414
| `[range.zip.transform.view] <https://wg21.link/range.zip.transform.view>`_, "zip_transform_view", "| `zip_transform_view::iterator`
15-
| `zip_transform_view::sentinel`", Unassigned, |Not Started|
16-
| `[range.zip.transform.iterator] <https://wg21.link/range.zip.transform.iterator>`_, "zip_transform_view::iterator", None, Unassigned, |Not Started|
17-
| `[range.zip.transform.sentinel] <https://wg21.link/range.zip.transform.sentinel>`_, "zip_transform_view::sentinel", None, Unassigned, |Not Started|
15+
| `zip_transform_view::sentinel`", Hui Xie, |Not Started|
16+
| `[range.zip.transform.iterator] <https://wg21.link/range.zip.transform.iterator>`_, "zip_transform_view::iterator", None, Hui Xie, |Not Started|
17+
| `[range.zip.transform.sentinel] <https://wg21.link/range.zip.transform.sentinel>`_, "zip_transform_view::sentinel", None, Hui Xie, |Not Started|
1818
| `[range.adjacent.view] <https://wg21.link/range.adjacent.view>`_, "adjacent_view", "| `adjacent_view::iterator`
19-
| `adjacent_view::sentinel`", Unassigned, |Not Started|
20-
| `[range.adjacent.iterator] <https://wg21.link/range.adjacent.iterator>`_, "adjacent_view::iterator", None, Unassigned, |Not Started|
21-
| `[range.adjacent.sentinel] <https://wg21.link/range.adjacent.sentinel>`_, "adjacent_view::sentinel", None, Unassigned, |Not Started|
19+
| `adjacent_view::sentinel`", Hui Xie, |Not Started|
20+
| `[range.adjacent.iterator] <https://wg21.link/range.adjacent.iterator>`_, "adjacent_view::iterator", None, unassigned, |Not Started|
21+
| `[range.adjacent.sentinel] <https://wg21.link/range.adjacent.sentinel>`_, "adjacent_view::sentinel", None, unassigned, |Not Started|
2222
| `[range.adjacent.transform.view] <https://wg21.link/range.adjacent.transform.view>`_, "adjacent_transform_view", "| `adjacent_transform_view::iterator`,
23-
| `adjacent_transform_view::sentinel`", Unassigned, |Not Started|
24-
| `[range.adjacent.transform.iterator] <https://wg21.link/range.adjacent.transform.iterator>`_, "adjacent_transform_view::iterator", None, Unassigned, |Not Started|
25-
| `[range.adjacent.transform.sentinel] <https://wg21.link/range.adjacent.transform.sentinel>`_, "adjacent_transform_view::sentinel", None, Unassigned, |Not Started|
23+
| `adjacent_transform_view::sentinel`", Hui Xie, |Not Started|
24+
| `[range.adjacent.transform.iterator] <https://wg21.link/range.adjacent.transform.iterator>`_, "adjacent_transform_view::iterator", None, Hui Xie, |Not Started|
25+
| `[range.adjacent.transform.sentinel] <https://wg21.link/range.adjacent.transform.sentinel>`_, "adjacent_transform_view::sentinel", None, Hui Xie, |Not Started|
2626
| `[ranges.syn] <https://wg21.link/ranges.syn>`_, "enable_borrowed_range zip_view and adjacent_view", "| `zip_view`
27-
| `adjacent_view`", Unassigned, |Not Started|
27+
| `adjacent_view`", Hui Xie, |Not Started|

libcxx/include/__utility/pair.h

Lines changed: 105 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,26 @@ struct _LIBCPP_TEMPLATE_VIS pair
9090
}
9191

9292
template <class _U1, class _U2>
93-
static constexpr bool __enable_explicit() {
93+
static constexpr bool __is_pair_constructible() {
9494
return is_constructible<first_type, _U1>::value
95-
&& is_constructible<second_type, _U2>::value
96-
&& (!is_convertible<_U1, first_type>::value
97-
|| !is_convertible<_U2, second_type>::value);
95+
&& is_constructible<second_type, _U2>::value;
9896
}
9997

10098
template <class _U1, class _U2>
101-
static constexpr bool __enable_implicit() {
102-
return is_constructible<first_type, _U1>::value
103-
&& is_constructible<second_type, _U2>::value
104-
&& is_convertible<_U1, first_type>::value
99+
static constexpr bool __is_implicit() {
100+
return is_convertible<_U1, first_type>::value
105101
&& is_convertible<_U2, second_type>::value;
106102
}
103+
104+
template <class _U1, class _U2>
105+
static constexpr bool __enable_explicit() {
106+
return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
107+
}
108+
109+
template <class _U1, class _U2>
110+
static constexpr bool __enable_implicit() {
111+
return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
112+
}
107113
};
108114

109115
template <bool _MaybeEnable>
@@ -198,6 +204,17 @@ struct _LIBCPP_TEMPLATE_VIS pair
198204
is_nothrow_constructible<second_type, _U2>::value))
199205
: first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
200206

207+
#if _LIBCPP_STD_VER > 20
208+
template<class _U1, class _U2, __enable_if_t<
209+
_CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
210+
>* = nullptr>
211+
_LIBCPP_HIDE_FROM_ABI constexpr
212+
explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p)
213+
noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
214+
is_nothrow_constructible<second_type, _U2&>::value))
215+
: first(__p.first), second(__p.second) {}
216+
#endif
217+
201218
template<class _U1, class _U2, typename enable_if<
202219
_CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
203220
>::type* = nullptr>
@@ -234,6 +251,18 @@ struct _LIBCPP_TEMPLATE_VIS pair
234251
is_nothrow_constructible<second_type, _U2&&>::value))
235252
: first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
236253

254+
#if _LIBCPP_STD_VER > 20
255+
template<class _U1, class _U2, __enable_if_t<
256+
_CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
257+
>* = nullptr>
258+
_LIBCPP_HIDE_FROM_ABI constexpr
259+
explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
260+
pair(const pair<_U1, _U2>&& __p)
261+
noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
262+
is_nothrow_constructible<second_type, const _U2&&>::value)
263+
: first(std::move(__p.first)), second(std::move(__p.second)) {}
264+
#endif
265+
237266
template<class _Tuple, typename enable_if<
238267
_CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
239268
>::type* = nullptr>
@@ -286,6 +315,50 @@ struct _LIBCPP_TEMPLATE_VIS pair
286315
return *this;
287316
}
288317

318+
#if _LIBCPP_STD_VER > 20
319+
_LIBCPP_HIDE_FROM_ABI constexpr
320+
const pair& operator=(pair const& __p) const
321+
noexcept(is_nothrow_copy_assignable_v<const first_type> &&
322+
is_nothrow_copy_assignable_v<const second_type>)
323+
requires(is_copy_assignable_v<const first_type> &&
324+
is_copy_assignable_v<const second_type>) {
325+
first = __p.first;
326+
second = __p.second;
327+
return *this;
328+
}
329+
330+
_LIBCPP_HIDE_FROM_ABI constexpr
331+
const pair& operator=(pair&& __p) const
332+
noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
333+
is_nothrow_assignable_v<const second_type&, second_type>)
334+
requires(is_assignable_v<const first_type&, first_type> &&
335+
is_assignable_v<const second_type&, second_type>) {
336+
first = std::forward<first_type>(__p.first);
337+
second = std::forward<second_type>(__p.second);
338+
return *this;
339+
}
340+
341+
template<class _U1, class _U2>
342+
_LIBCPP_HIDE_FROM_ABI constexpr
343+
const pair& operator=(const pair<_U1, _U2>& __p) const
344+
requires(is_assignable_v<const first_type&, const _U1&> &&
345+
is_assignable_v<const second_type&, const _U2&>) {
346+
first = __p.first;
347+
second = __p.second;
348+
return *this;
349+
}
350+
351+
template<class _U1, class _U2>
352+
_LIBCPP_HIDE_FROM_ABI constexpr
353+
const pair& operator=(pair<_U1, _U2>&& __p) const
354+
requires(is_assignable_v<const first_type&, _U1> &&
355+
is_assignable_v<const second_type&, _U2>) {
356+
first = std::forward<_U1>(__p.first);
357+
second = std::forward<_U2>(__p.second);
358+
return *this;
359+
}
360+
#endif // _LIBCPP_STD_VER > 20
361+
289362
template <class _Tuple, typename enable_if<
290363
_CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
291364
>::type* = nullptr>
@@ -306,6 +379,18 @@ struct _LIBCPP_TEMPLATE_VIS pair
306379
swap(first, __p.first);
307380
swap(second, __p.second);
308381
}
382+
383+
#if _LIBCPP_STD_VER > 20
384+
_LIBCPP_HIDE_FROM_ABI constexpr
385+
void swap(const pair& __p) const
386+
noexcept(__is_nothrow_swappable<const first_type>::value &&
387+
__is_nothrow_swappable<const second_type>::value)
388+
{
389+
using std::swap;
390+
swap(first, __p.first);
391+
swap(second, __p.second);
392+
}
393+
#endif
309394
private:
310395

311396
#ifndef _LIBCPP_CXX03_LANG
@@ -422,6 +507,18 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
422507
__x.swap(__y);
423508
}
424509

510+
#if _LIBCPP_STD_VER > 20
511+
template <class _T1, class _T2>
512+
requires (__is_swappable<const _T1>::value &&
513+
__is_swappable<const _T2>::value)
514+
_LIBCPP_HIDE_FROM_ABI constexpr
515+
void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
516+
noexcept(noexcept(__x.swap(__y)))
517+
{
518+
__x.swap(__y);
519+
}
520+
#endif
521+
425522
template <class _T1, class _T2>
426523
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
427524
pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>

libcxx/include/utility

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,29 @@ struct pair
8484
explicit(see-below) constexpr pair();
8585
explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14
8686
template <class U = T1, class V = T2> explicit(see-below) pair(U&&, V&&); // constexpr in C++14
87+
template <class U, class V> constexpr explicit(see below) pair(pair<U, V>&); // since C++23
8788
template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14
8889
template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14
90+
template <class U, class V>
91+
constexpr explicit(see below) pair(const pair<U, V>&&); // since C++23
8992
template <class... Args1, class... Args2>
9093
pair(piecewise_construct_t, tuple<Args1...> first_args,
9194
tuple<Args2...> second_args); // constexpr in C++20
9295
96+
constexpr const pair& operator=(const pair& p) const; // since C++23
9397
template <class U, class V> pair& operator=(const pair<U, V>& p); // constexpr in C++20
98+
template <class U, class V>
99+
constexpr const pair& operator=(const pair<U, V>& p) const; // since C++23
94100
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
95101
is_nothrow_move_assignable<T2>::value); // constexpr in C++20
102+
constexpr const pair& operator=(pair&& p) const; // since C++23
96103
template <class U, class V> pair& operator=(pair<U, V>&& p); // constexpr in C++20
104+
template <class U, class V>
105+
constexpr const pair& operator=(pair<U, V>&& p) const; // since C++23
97106
98107
void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
99108
is_nothrow_swappable_v<T2>); // constexpr in C++20
109+
constexpr void swap(const pair& p) const noexcept(see below); // since C++23
100110
};
101111
102112
template<class T1, class T2, class U1, class U2, template<class> class TQual, template<class> class UQual>
@@ -123,6 +133,9 @@ template <class T1, class T2>
123133
void
124134
swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
125135
136+
template<class T1, class T2>
137+
constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // since C++23
138+
126139
struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
127140
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
128141

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_convert_copy.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <type_traits>
2323

2424
#include "test_macros.h"
25-
#include "types.h"
25+
#include "copy_move_types.h"
2626

2727
// test constraints
2828

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_convert_move.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <type_traits>
2323

2424
#include "test_macros.h"
25-
#include "types.h"
25+
#include "copy_move_types.h"
2626

2727
// test constraints
2828

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_copy.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <type_traits>
2222

2323
#include "test_macros.h"
24-
#include "types.h"
24+
#include "copy_move_types.h"
2525

2626
static_assert(!std::is_assignable_v<const std::tuple<int>&, const std::tuple<int>&>);
2727
static_assert(std::is_assignable_v<const std::tuple<int&>&, const std::tuple<int&>&>);

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_move.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <type_traits>
2222

2323
#include "test_macros.h"
24-
#include "types.h"
24+
#include "copy_move_types.h"
2525

2626
static_assert(!std::is_assignable_v<const std::tuple<int>&, std::tuple<int>&&>);
2727
static_assert(std::is_assignable_v<const std::tuple<int&>&, std::tuple<int&>&&>);

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair_copy.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <utility>
2424

2525
#include "test_macros.h"
26-
#include "types.h"
26+
#include "copy_move_types.h"
2727

2828
// test constraints
2929

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair_move.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <utility>
2424

2525
#include "test_macros.h"
26-
#include "types.h"
26+
#include "copy_move_types.h"
2727

2828
// test constraints
2929

0 commit comments

Comments
 (0)