diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index 1f596a87f7cc7..5828f978cdb34 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -629,42 +629,42 @@ get(const pair<_T1, _T2>&& __p) _NOEXCEPT { #if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT { - return __get_pair<0>::get(__p); + return __p.first; } template 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 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 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 -inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT { - return __get_pair<1>::get(__p); +template +inline _LIBCPP_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT { + return __p.second; } -template -inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT { - return __get_pair<1>::get(__p); +template +inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT { + return __p.second; } -template -inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT { - return __get_pair<1>::get(std::move(__p)); +template +inline _LIBCPP_HIDE_FROM_ABI constexpr _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { + return std::forward<_T2&&>(__p.second); } -template -inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT { - return __get_pair<1>::get(std::move(__p)); +template +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 diff --git a/libcxx/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp index f6940c468a81d..6d1dc9fd6494d 100644 --- a/libcxx/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp +++ b/libcxx/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp @@ -8,81 +8,126 @@ // UNSUPPORTED: c++03, c++11 -#include -#include -#include +#include #include #include - -#include +#include +#include #include "test_macros.h" -int main(int, char**) -{ - typedef std::complex cf; - { - auto t1 = std::make_pair ( 42, { 1,2 } ); - assert ( std::get(t1) == 42 ); - assert ( std::get(t1).real() == 1 ); - assert ( std::get(t1).imag() == 2 ); - } +TEST_CONSTEXPR_CXX14 bool test() { + { // Make sure that references work as expected + int i = 1; + int j = 2; { - const std::pair p1 { 1, 2 }; - const int &i1 = std::get(p1); - const int &i2 = std::get(p1); - assert ( i1 == 1 ); - assert ( i2 == 2 ); - } + std::pair p(i, std::move(j)); + assert(&std::get(p) == &i); + assert(&std::get(p) == &j); - { - typedef std::unique_ptr upint; - std::pair t(upint(new int(4)), 42); - upint p = std::get(std::move(t)); // get rvalue - assert(*p == 4); - assert(std::get(t) == nullptr); // has been moved from + assert(&std::get(std::move(p)) == &i); + assert(std::get(std::move(p)) == 2); + + const std::pair cp(i, std::move(j)); + assert(&std::get(cp) == &i); + assert(&std::get(cp) == &j); + + assert(&std::get(std::move(cp)) == &i); + assert(std::get(std::move(cp)) == 2); } { - typedef std::unique_ptr upint; - const std::pair t(upint(new int(4)), 42); - static_assert(std::is_same(std::move(t)))>::value, ""); - static_assert(noexcept(std::get(std::move(t))), ""); - static_assert(std::is_same(std::move(t)))>::value, ""); - static_assert(noexcept(std::get(std::move(t))), ""); - auto&& p = std::get(std::move(t)); // get const rvalue - auto&& i = std::get(std::move(t)); // get const rvalue - assert(*p == 4); - assert(i == 42); - assert(std::get(t) != nullptr); + std::pair p(std::move(i), j); + assert(&std::get(p) == &j); + assert(&std::get(p) == &i); + + assert(&std::get(std::move(p)) == &j); + assert(std::get(std::move(p)) == 1); + + const std::pair cp(std::move(i), j); + assert(&std::get(cp) == &j); + assert(&std::get(cp) == &i); + + assert(&std::get(std::move(cp)) == &j); + assert(std::get(std::move(cp)) == 1); } + } - { - int x = 42; + { + typedef std::complex cf; + auto t1 = std::make_pair(42, {1, 2}); + assert(std::get(t1) == 42); + assert(std::get(t1).real() == 1); + assert(std::get(t1).imag() == 2); + } + + { + const std::pair p1{1, 2}; + const int& i1 = std::get(p1); + const int& i2 = std::get(p1); + assert(i1 == 1); + assert(i2 == 2); + } + + { + int x = 42; int const y = 43; std::pair const p(x, y); static_assert(std::is_same(std::move(p)))>::value, ""); static_assert(noexcept(std::get(std::move(p))), ""); static_assert(std::is_same(std::move(p)))>::value, ""); static_assert(noexcept(std::get(std::move(p))), ""); - } + } - { - int x = 42; + { + int x = 42; int const y = 43; std::pair const p(std::move(x), std::move(y)); static_assert(std::is_same(std::move(p)))>::value, ""); static_assert(noexcept(std::get(std::move(p))), ""); static_assert(std::is_same(std::move(p)))>::value, ""); static_assert(noexcept(std::get(std::move(p))), ""); - } + } - { - constexpr const std::pair p { 1, 2 }; + { + constexpr const std::pair p{1, 2}; static_assert(std::get(std::move(p)) == 1, ""); static_assert(std::get(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 upint; + std::pair t(upint(new int(4)), 42); + upint p = std::get(std::move(t)); // get rvalue + assert(*p == 4); + assert(std::get(t) == nullptr); // has been moved from + } + + { + typedef std::unique_ptr upint; + const std::pair t(upint(new int(4)), 42); + static_assert(std::is_same(std::move(t)))>::value, ""); + static_assert(noexcept(std::get(std::move(t))), ""); + static_assert(std::is_same(std::move(t)))>::value, ""); + static_assert(noexcept(std::get(std::move(t))), ""); + auto&& p = std::get(std::move(t)); // get const rvalue + auto&& i = std::get(std::move(t)); // get const rvalue + assert(*p == 4); + assert(i == 42); + assert(std::get(t) != nullptr); + } return 0; }