Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions libcxx/include/__utility/pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,42 +629,42 @@ get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
#if _LIBCPP_STD_VER >= 14
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
return __get_pair<0>::get(__p);
return __p.first;
}

template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
return __get_pair<0>::get(__p);
return __p.first;
}

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

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

template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
return __get_pair<1>::get(__p);
template <class _T2, class _T1>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
return __p.second;
}

template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
return __get_pair<1>::get(__p);
template <class _T2, class _T1>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
return __p.second;
}

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

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

#endif // _LIBCPP_STD_VER >= 14
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,81 +8,126 @@

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

#include <utility>
#include <string>
#include <type_traits>
#include <cassert>
#include <complex>
#include <memory>

#include <cassert>
#include <type_traits>
#include <utility>

#include "test_macros.h"

int main(int, char**)
{
typedef std::complex<float> cf;
{
auto t1 = std::make_pair<int, cf> ( 42, { 1,2 } );
assert ( std::get<int>(t1) == 42 );
assert ( std::get<cf>(t1).real() == 1 );
assert ( std::get<cf>(t1).imag() == 2 );
}
TEST_CONSTEXPR_CXX14 bool test() {
{ // Make sure that references work as expected
int i = 1;
int j = 2;

{
const std::pair<int, const int> p1 { 1, 2 };
const int &i1 = std::get<int>(p1);
const int &i2 = std::get<const int>(p1);
assert ( i1 == 1 );
assert ( i2 == 2 );
}
std::pair<int&, int&&> p(i, std::move(j));
assert(&std::get<int&>(p) == &i);
assert(&std::get<int&&>(p) == &j);

{
typedef std::unique_ptr<int> upint;
std::pair<upint, int> t(upint(new int(4)), 42);
upint p = std::get<upint>(std::move(t)); // get rvalue
assert(*p == 4);
assert(std::get<upint>(t) == nullptr); // has been moved from
assert(&std::get<int&>(std::move(p)) == &i);
assert(std::get<int&&>(std::move(p)) == 2);

const std::pair<int&, int&&> cp(i, std::move(j));
assert(&std::get<int&>(cp) == &i);
assert(&std::get<int&&>(cp) == &j);

assert(&std::get<int&>(std::move(cp)) == &i);
assert(std::get<int&&>(std::move(cp)) == 2);
}

{
typedef std::unique_ptr<int> upint;
const std::pair<upint, int> t(upint(new int(4)), 42);
static_assert(std::is_same<const upint&&, decltype(std::get<upint>(std::move(t)))>::value, "");
static_assert(noexcept(std::get<upint>(std::move(t))), "");
static_assert(std::is_same<const int&&, decltype(std::get<int>(std::move(t)))>::value, "");
static_assert(noexcept(std::get<int>(std::move(t))), "");
auto&& p = std::get<upint>(std::move(t)); // get const rvalue
auto&& i = std::get<int>(std::move(t)); // get const rvalue
assert(*p == 4);
assert(i == 42);
assert(std::get<upint>(t) != nullptr);
std::pair<int&&, int&> p(std::move(i), j);
assert(&std::get<int&>(p) == &j);
assert(&std::get<int&&>(p) == &i);

assert(&std::get<int&>(std::move(p)) == &j);
assert(std::get<int&&>(std::move(p)) == 1);

const std::pair<int&&, int&> cp(std::move(i), j);
assert(&std::get<int&>(cp) == &j);
assert(&std::get<int&&>(cp) == &i);

assert(&std::get<int&>(std::move(cp)) == &j);
assert(std::get<int&&>(std::move(cp)) == 1);
}
}

{
int x = 42;
{
typedef std::complex<float> cf;
auto t1 = std::make_pair<int, cf>(42, {1, 2});
assert(std::get<int>(t1) == 42);
assert(std::get<cf>(t1).real() == 1);
assert(std::get<cf>(t1).imag() == 2);
}

{
const std::pair<int, const int> p1{1, 2};
const int& i1 = std::get<int>(p1);
const int& i2 = std::get<const int>(p1);
assert(i1 == 1);
assert(i2 == 2);
}

{
int x = 42;
int const y = 43;
std::pair<int&, int const&> const p(x, y);
static_assert(std::is_same<int&, decltype(std::get<int&>(std::move(p)))>::value, "");
static_assert(noexcept(std::get<int&>(std::move(p))), "");
static_assert(std::is_same<int const&, decltype(std::get<int const&>(std::move(p)))>::value, "");
static_assert(noexcept(std::get<int const&>(std::move(p))), "");
}
}

{
int x = 42;
{
int x = 42;
int const y = 43;
std::pair<int&&, int const&&> const p(std::move(x), std::move(y));
static_assert(std::is_same<int&&, decltype(std::get<int&&>(std::move(p)))>::value, "");
static_assert(noexcept(std::get<int&&>(std::move(p))), "");
static_assert(std::is_same<int const&&, decltype(std::get<int const&&>(std::move(p)))>::value, "");
static_assert(noexcept(std::get<int const&&>(std::move(p))), "");
}
}

{
constexpr const std::pair<int, const int> p { 1, 2 };
{
constexpr const std::pair<int, const int> p{1, 2};
static_assert(std::get<int>(std::move(p)) == 1, "");
static_assert(std::get<const int>(std::move(p)) == 2, "");
}
}

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 14
static_assert(test(), "");
#endif

// These tests use types which only work during constant evaluation in very recent standards

{
typedef std::unique_ptr<int> upint;
std::pair<upint, int> t(upint(new int(4)), 42);
upint p = std::get<upint>(std::move(t)); // get rvalue
assert(*p == 4);
assert(std::get<upint>(t) == nullptr); // has been moved from
}

{
typedef std::unique_ptr<int> upint;
const std::pair<upint, int> t(upint(new int(4)), 42);
static_assert(std::is_same<const upint&&, decltype(std::get<upint>(std::move(t)))>::value, "");
static_assert(noexcept(std::get<upint>(std::move(t))), "");
static_assert(std::is_same<const int&&, decltype(std::get<int>(std::move(t)))>::value, "");
static_assert(noexcept(std::get<int>(std::move(t))), "");
auto&& p = std::get<upint>(std::move(t)); // get const rvalue
auto&& i = std::get<int>(std::move(t)); // get const rvalue
assert(*p == 4);
assert(i == 42);
assert(std::get<upint>(t) != nullptr);
}

return 0;
}
Loading