diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 48af2b02ef9..85aad838860 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -528,6 +528,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef pair<__ds_type1, __ds_type2> __pair_type; return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y)); } + + template + struct __move_if_noexcept_cond> + : public __and_>, + __not_<__and_< + __or_, is_nothrow_move_constructible<_T1>>, + __or_, is_nothrow_move_constructible<_T2>>>>>::type + { }; #else template inline pair<_T1, _T2> diff --git a/libstdc++-v3/testsuite/20_util/move_if_noexcept/1.cc b/libstdc++-v3/testsuite/20_util/move_if_noexcept/1.cc index 078ccb83d36..b6f01097e40 100644 --- a/libstdc++-v3/testsuite/20_util/move_if_noexcept/1.cc +++ b/libstdc++-v3/testsuite/20_util/move_if_noexcept/1.cc @@ -33,7 +33,7 @@ struct noexcept_move_copy noexcept_move_copy(const noexcept_move_copy&) = default; - operator bool() { return status; } + operator bool() const { return status; } private: bool status; @@ -50,7 +50,7 @@ struct noexcept_move_no_copy noexcept_move_no_copy(const noexcept_move_no_copy&) = delete; - operator bool() { return status; } + operator bool() const { return status; } private: bool status; @@ -67,7 +67,7 @@ struct except_move_copy except_move_copy(const except_move_copy&) = default; - operator bool() { return status; } + operator bool() const { return status; } private: bool status; @@ -84,7 +84,7 @@ struct except_move_no_copy except_move_no_copy(const except_move_no_copy&) = delete; - operator bool() { return status; } + operator bool() const { return status; } private: bool status; @@ -110,8 +110,38 @@ test01() VERIFY( emnc1 == false ); } +void +test02() +{ + std::pair nemc1; + auto nemc2 __attribute__((unused)) = std::move_if_noexcept(nemc1); + VERIFY( nemc1.first == false ); + VERIFY( nemc1.second == false ); + + std::pair emc1; + auto emc2 __attribute__((unused)) = std::move_if_noexcept(emc1); + VERIFY( emc1.first == true ); + VERIFY( emc1.second == true ); + + std::pair emnc1; + auto emnc2 __attribute__((unused)) = std::move_if_noexcept(emnc1); + VERIFY( emnc1.first == false ); + VERIFY( emnc1.second == false ); + + std::pair cemc1; + auto cemc2 __attribute__((unused)) = std::move_if_noexcept(cemc1); + VERIFY( cemc1.first == true ); + VERIFY( cemc1.second == false ); + + std::pair nemnc1; + auto nemnc2 __attribute__((unused)) = std::move_if_noexcept(nemnc1); + VERIFY( nemnc1.first == false ); + VERIFY( nemnc1.second == false ); +} + int main() { test01(); + test02(); return 0; } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc index b27269e607a..d1be3adaae5 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc @@ -21,6 +21,7 @@ #include #include #include +#include using __gnu_test::propagating_allocator; using __gnu_test::counter_type; @@ -49,8 +50,10 @@ void test01() VERIFY( 1 == v1.get_allocator().get_personality() ); VERIFY( 2 == v2.get_allocator().get_personality() ); - // No move because key is const. - VERIFY( counter_type::move_assign_count == 0 ); + // Key copied, value moved. + VERIFY( counter_type::copy_count == 1 ); + VERIFY( counter_type::move_count == 1 ); + VERIFY( counter_type::destructor_count == 4 ); } void test02() @@ -79,15 +82,41 @@ void test02() VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality()); - VERIFY( counter_type::move_assign_count == 0 ); + VERIFY( counter_type::copy_count == 0 ); + VERIFY( counter_type::move_count == 0 ); VERIFY( counter_type::destructor_count == 2 ); VERIFY( it == v2.begin() ); } +void test03() +{ + using __gnu_test::rvalstruct; + + typedef std::pair value_type; + typedef propagating_allocator alloc_type; + typedef std::unordered_map, + std::equal_to, + alloc_type> test_type; + + test_type v1(alloc_type(1)); + v1.emplace(std::piecewise_construct, + std::make_tuple(1), std::make_tuple(1)); + + test_type v2(alloc_type(2)); + v2.emplace(std::piecewise_construct, + std::make_tuple(2), std::make_tuple(2)); + + v2 = std::move(v1); + + VERIFY( 1 == v1.get_allocator().get_personality() ); + VERIFY( 2 == v2.get_allocator().get_personality() ); +} + int main() { test01(); test02(); + test03(); return 0; }