diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index 99b0eb955b76..ab390aafa0d9 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -654,42 +654,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 f6940c468a81..6d1dc9fd6494 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,43 +8,114 @@ // UNSUPPORTED: c++03, c++11 -#include -#include -#include +#include #include #include - -#include +#include +#include #include "test_macros.h" -int main(int, char**) -{ +TEST_CONSTEXPR_CXX14 bool test() { + { // Make sure that references work as expected + int i = 1; + int j = 2; + + { + std::pair p(i, std::move(j)); + assert(&std::get(p) == &i); + assert(&std::get(p) == &j); + + 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); + } + + { + 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); + } + } + + { 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 ); - } + 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 ); - } + { + 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 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}; + 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, ""); @@ -52,37 +123,11 @@ int main(int, char**) 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 + auto&& i = std::get(std::move(t)); // get const rvalue assert(*p == 4); assert(i == 42); assert(std::get(t) != nullptr); - } - - { - 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 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 }; - static_assert(std::get(std::move(p)) == 1, ""); - static_assert(std::get(std::move(p)) == 2, ""); - } + } return 0; }