Skip to content

Commit 331ac8c

Browse files
committed
[libc++] Simplify the implementation of std::get for pairs
1 parent 8abca17 commit 331ac8c

File tree

2 files changed

+82
-39
lines changed

2 files changed

+82
-39
lines changed

libcxx/include/__utility/pair.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -629,42 +629,42 @@ get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
629629
#if _LIBCPP_STD_VER >= 14
630630
template <class _T1, class _T2>
631631
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
632-
return __get_pair<0>::get(__p);
632+
return __p.first;
633633
}
634634

635635
template <class _T1, class _T2>
636636
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
637-
return __get_pair<0>::get(__p);
637+
return __p.first;
638638
}
639639

640640
template <class _T1, class _T2>
641641
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
642-
return __get_pair<0>::get(std::move(__p));
642+
return std::forward<_T1&&>(__p.first);
643643
}
644644

645645
template <class _T1, class _T2>
646646
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
647-
return __get_pair<0>::get(std::move(__p));
647+
return std::forward<_T1 const&&>(__p.first);
648648
}
649649

650650
template <class _T1, class _T2>
651651
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
652-
return __get_pair<1>::get(__p);
652+
return __p.second;
653653
}
654654

655655
template <class _T1, class _T2>
656656
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
657-
return __get_pair<1>::get(__p);
657+
return __p.second;
658658
}
659659

660660
template <class _T1, class _T2>
661661
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT {
662-
return __get_pair<1>::get(std::move(__p));
662+
return std::forward<_T1&&>(__p.second);
663663
}
664664

665665
template <class _T1, class _T2>
666666
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT {
667-
return __get_pair<1>::get(std::move(__p));
667+
return std::forward<_T1 const&&>(__p.second);
668668
}
669669

670670
#endif // _LIBCPP_STD_VER >= 14

libcxx/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,81 +8,124 @@
88

99
// UNSUPPORTED: c++03, c++11
1010

11-
#include <utility>
12-
#include <string>
13-
#include <type_traits>
11+
#include <cassert>
1412
#include <complex>
1513
#include <memory>
16-
17-
#include <cassert>
14+
#include <type_traits>
15+
#include <utility>
1816

1917
#include "test_macros.h"
2018

21-
int main(int, char**)
22-
{
23-
typedef std::complex<float> cf;
19+
TEST_CONSTEXPR_CXX14 bool test() {
20+
{ // Make sure that references work as expected
21+
int i = 1;
22+
int j = 2;
23+
2424
{
25-
auto t1 = std::make_pair<int, cf> ( 42, { 1,2 } );
26-
assert ( std::get<int>(t1) == 42 );
27-
assert ( std::get<cf>(t1).real() == 1 );
28-
assert ( std::get<cf>(t1).imag() == 2 );
25+
std::pair<int&, int&&> p(i, std::move(j));
26+
assert(&std::get<int&>(p) == &i);
27+
assert(&std::get<int&&>(p) == &j);
28+
29+
assert(&std::get<int&>(std::move(p)) == &i);
30+
assert(std::get<int&&>(std::move(p)) == 2);
31+
32+
const std::pair<int&, int&&> cp(i, std::move(j));
33+
assert(&std::get<int&>(cp) == &i);
34+
assert(&std::get<int&&>(cp) == &j);
35+
36+
assert(&std::get<int&>(std::move(cp)) == &i);
37+
assert(std::get<int&&>(std::move(cp)) == 2);
2938
}
3039

3140
{
32-
const std::pair<int, const int> p1 { 1, 2 };
33-
const int &i1 = std::get<int>(p1);
34-
const int &i2 = std::get<const int>(p1);
35-
assert ( i1 == 1 );
36-
assert ( i2 == 2 );
41+
std::pair<int&&, int&> p(std::move(i), j);
42+
assert(&std::get<int&>(p) == &j);
43+
assert(&std::get<int&&>(p) == &i);
44+
45+
assert(&std::get<int&>(std::move(p)) == &j);
46+
assert(std::get<int&&>(std::move(p)) == 1);
47+
48+
const std::pair<int&&, int&> cp(std::move(i), j);
49+
assert(&std::get<int&>(cp) == &j);
50+
assert(&std::get<int&&>(cp) == &i);
51+
52+
assert(&std::get<int&>(std::move(cp)) == &j);
53+
assert(std::get<int&&>(std::move(cp)) == 1);
3754
}
55+
}
3856

39-
{
57+
{
58+
typedef std::complex<float> cf;
59+
auto t1 = std::make_pair<int, cf>(42, {1, 2});
60+
assert(std::get<int>(t1) == 42);
61+
assert(std::get<cf>(t1).real() == 1);
62+
assert(std::get<cf>(t1).imag() == 2);
63+
}
64+
65+
{
66+
const std::pair<int, const int> p1{1, 2};
67+
const int& i1 = std::get<int>(p1);
68+
const int& i2 = std::get<const int>(p1);
69+
assert(i1 == 1);
70+
assert(i2 == 2);
71+
}
72+
73+
{
4074
typedef std::unique_ptr<int> upint;
4175
std::pair<upint, int> t(upint(new int(4)), 42);
4276
upint p = std::get<upint>(std::move(t)); // get rvalue
4377
assert(*p == 4);
4478
assert(std::get<upint>(t) == nullptr); // has been moved from
45-
}
79+
}
4680

47-
{
81+
{
4882
typedef std::unique_ptr<int> upint;
4983
const std::pair<upint, int> t(upint(new int(4)), 42);
5084
static_assert(std::is_same<const upint&&, decltype(std::get<upint>(std::move(t)))>::value, "");
5185
static_assert(noexcept(std::get<upint>(std::move(t))), "");
5286
static_assert(std::is_same<const int&&, decltype(std::get<int>(std::move(t)))>::value, "");
5387
static_assert(noexcept(std::get<int>(std::move(t))), "");
5488
auto&& p = std::get<upint>(std::move(t)); // get const rvalue
55-
auto&& i = std::get<int>(std::move(t)); // get const rvalue
89+
auto&& i = std::get<int>(std::move(t)); // get const rvalue
5690
assert(*p == 4);
5791
assert(i == 42);
5892
assert(std::get<upint>(t) != nullptr);
59-
}
93+
}
6094

61-
{
62-
int x = 42;
95+
{
96+
int x = 42;
6397
int const y = 43;
6498
std::pair<int&, int const&> const p(x, y);
6599
static_assert(std::is_same<int&, decltype(std::get<int&>(std::move(p)))>::value, "");
66100
static_assert(noexcept(std::get<int&>(std::move(p))), "");
67101
static_assert(std::is_same<int const&, decltype(std::get<int const&>(std::move(p)))>::value, "");
68102
static_assert(noexcept(std::get<int const&>(std::move(p))), "");
69-
}
103+
}
70104

71-
{
72-
int x = 42;
105+
{
106+
int x = 42;
73107
int const y = 43;
74108
std::pair<int&&, int const&&> const p(std::move(x), std::move(y));
75109
static_assert(std::is_same<int&&, decltype(std::get<int&&>(std::move(p)))>::value, "");
76110
static_assert(noexcept(std::get<int&&>(std::move(p))), "");
77111
static_assert(std::is_same<int const&&, decltype(std::get<int const&&>(std::move(p)))>::value, "");
78112
static_assert(noexcept(std::get<int const&&>(std::move(p))), "");
79-
}
113+
}
80114

81-
{
82-
constexpr const std::pair<int, const int> p { 1, 2 };
115+
{
116+
constexpr const std::pair<int, const int> p{1, 2};
83117
static_assert(std::get<int>(std::move(p)) == 1, "");
84118
static_assert(std::get<const int>(std::move(p)) == 2, "");
85-
}
119+
}
120+
121+
return true;
122+
}
123+
124+
int main(int, char**) {
125+
test();
126+
#if TEST_STD_VER >= 14
127+
static_assert(test(), "");
128+
#endif
86129

87130
return 0;
88131
}

0 commit comments

Comments
 (0)