diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-08-14 12:51:18 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-08-14 12:51:18 +0100 |
commit | 2548a4d6ba4d54393ae7947a7a8c9070d9c7e113 (patch) | |
tree | 632465c942818a2b37b76a4879f691df51e00467 | |
parent | 357c9f7edc4154418f9862652b53fa8321e91d22 (diff) | |
download | gcc-2548a4d6ba4d54393ae7947a7a8c9070d9c7e113.zip gcc-2548a4d6ba4d54393ae7947a7a8c9070d9c7e113.tar.gz gcc-2548a4d6ba4d54393ae7947a7a8c9070d9c7e113.tar.bz2 |
any (any::operator=(const any&)): Move check for self-assignment.
* include/experimental/any (any::operator=(const any&)): Move check
for self-assignment.
(any::operator=(any&&)): Add check for self-assignment.
(any::operator=(_ValueType&&)): Constrain template argument.
(any::swap(any&)): Add check for self-swap.
* testsuite/experimental/any/assign/self.cc: Test move and swap.
* testsuite/experimental/any/misc/any_cast_neg.cc: Update dg-error.
From-SVN: r226894
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/any | 59 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/any/assign/self.cc | 54 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc | 2 |
4 files changed, 94 insertions, 31 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 15fa9a2..0753951 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2015-08-14 Jonathan Wakely <jwakely@redhat.com> + * include/experimental/any (any::operator=(const any&)): Move check + for self-assignment. + (any::operator=(any&&)): Add check for self-assignment. + (any::operator=(_ValueType&&)): Constrain template argument. + (any::swap(any&)): Add check for self-swap. + * testsuite/experimental/any/assign/self.cc: Test move and swap. + * testsuite/experimental/any/misc/any_cast_neg.cc: Update dg-error. + +2015-08-14 Jonathan Wakely <jwakely@redhat.com> + * include/experimental/array: Add feature-test macro. * testsuite/experimental/array/neg.cc: Update dg-error. diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any index fbb70a7..dae82b5 100644 --- a/libstdc++-v3/include/experimental/any +++ b/libstdc++-v3/include/experimental/any @@ -175,12 +175,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Copy the state of another object. any& operator=(const any& __rhs) { - if (this == &__rhs) - return *this; - if (__rhs.empty()) clear(); - else + else if (this != &__rhs) { if (!empty()) _M_manager(_Op_destroy, this, nullptr); @@ -200,7 +197,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__rhs.empty()) clear(); - else + else if (this != &__rhs) { if (!empty()) _M_manager(_Op_destroy, this, nullptr); @@ -213,7 +210,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Store a copy of @p __rhs as the contained object. template<typename _ValueType> - any& operator=(_ValueType&& __rhs) + enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&> + operator=(_ValueType&& __rhs) { *this = any(std::forward<_ValueType>(__rhs)); return *this; @@ -233,30 +231,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Exchange state with another object. void swap(any& __rhs) noexcept - { - if (empty() && __rhs.empty()) - return; + { + if (empty() && __rhs.empty()) + return; - if (!empty() && !__rhs.empty()) - { - any __tmp; - _Arg __arg; - __arg._M_any = &__tmp; - __rhs._M_manager(_Op_xfer, &__rhs, &__arg); - __arg._M_any = &__rhs; - _M_manager(_Op_xfer, this, &__arg); - __arg._M_any = this; - __tmp._M_manager(_Op_xfer, &__tmp, &__arg); - } - else - { - any* __empty = empty() ? this : &__rhs; - any* __full = empty() ? &__rhs : this; - _Arg __arg; - __arg._M_any = __empty; - __full->_M_manager(_Op_xfer, __full, &__arg); - } - } + if (!empty() && !__rhs.empty()) + { + if (this == &__rhs) + return; + + any __tmp; + _Arg __arg; + __arg._M_any = &__tmp; + __rhs._M_manager(_Op_xfer, &__rhs, &__arg); + __arg._M_any = &__rhs; + _M_manager(_Op_xfer, this, &__arg); + __arg._M_any = this; + __tmp._M_manager(_Op_xfer, &__tmp, &__arg); + } + else + { + any* __empty = empty() ? this : &__rhs; + any* __full = empty() ? &__rhs : this; + _Arg __arg; + __arg._M_any = __empty; + __full->_M_manager(_Op_xfer, __full, &__arg); + } + } // observers diff --git a/libstdc++-v3/testsuite/experimental/any/assign/self.cc b/libstdc++-v3/testsuite/experimental/any/assign/self.cc index 0fb9566..79c6f0f 100644 --- a/libstdc++-v3/testsuite/experimental/any/assign/self.cc +++ b/libstdc++-v3/testsuite/experimental/any/assign/self.cc @@ -18,8 +18,17 @@ // { dg-options "-std=gnu++14" } #include <experimental/any> +#include <set> #include <testsuite_hooks.h> +std::set<const void*> live_objects; + +struct A { + A() { live_objects.insert(this); } + ~A() { live_objects.erase(this); } + A(const A& a) { VERIFY(live_objects.count(&a)); live_objects.insert(this); } +}; + void test01() { @@ -29,13 +38,56 @@ test01() a = a; VERIFY( a.empty() ); - a = 1; + a = A{}; a = a; VERIFY( !a.empty() ); + + a.clear(); + VERIFY( live_objects.empty() ); +} + +void +test02() +{ + using std::experimental::any; + + struct X { + any a; + }; + + X x; + std::swap(x, x); // results in "self-move-assignment" of X::a + VERIFY( x.a.empty() ); + + x.a = A{}; + std::swap(x, x); // results in "self-move-assignment" of X::a + VERIFY( !x.a.empty() ); + + x.a.clear(); + VERIFY( live_objects.empty() ); +} + +void +test03() +{ + using std::experimental::any; + + any a; + a.swap(a); + VERIFY( a.empty() ); + + a = A{}; + a.swap(a); + VERIFY( !a.empty() ); + + a.clear(); + VERIFY( live_objects.empty() ); } int main() { test01(); + test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc index b88592a..1d1180c 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc @@ -26,5 +26,5 @@ void test01() using std::experimental::any_cast; const any y(1); - any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 359 } + any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 360 } } |