diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-10-24 16:22:11 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-10-24 16:22:11 +0300 |
commit | a3f6007cbc84242c088097e46602a65f9654a349 (patch) | |
tree | cdd80a119a6aa9e73779d62f044b7bced051e78d /libstdc++-v3/testsuite/experimental/any | |
parent | 292af537961e1f4ac5e1e7f0e727fb79b5196998 (diff) | |
download | gcc-a3f6007cbc84242c088097e46602a65f9654a349.zip gcc-a3f6007cbc84242c088097e46602a65f9654a349.tar.gz gcc-a3f6007cbc84242c088097e46602a65f9654a349.tar.bz2 |
Cross-port exception-safety and move fixes of std::any to std::experimental::any.
Cross-port exception-safety and move fixes of std::any to
std::experimental::any.
* include/experimental/any (operator=(const any&)):
Make strongly exception-safe.
(operator=(any&&)): clear() unconditionally in the case where
rhs has a value.
(_Manager_internal<_Tp>::_S_manage): Move in _Op_xfer, don't copy.
* testsuite/experimental/any/assign/2.cc: Adjust.
* testsuite/experimental/any/assign/exception.cc: New.
* testsuite/experimental/any/cons/2.cc: Adjust.
* testsuite/experimental/any/misc/any_cast_neg.cc: Ajust.
From-SVN: r241479
Diffstat (limited to 'libstdc++-v3/testsuite/experimental/any')
4 files changed, 167 insertions, 15 deletions
diff --git a/libstdc++-v3/testsuite/experimental/any/assign/2.cc b/libstdc++-v3/testsuite/experimental/any/assign/2.cc index 7022878..0232af6 100644 --- a/libstdc++-v3/testsuite/experimental/any/assign/2.cc +++ b/libstdc++-v3/testsuite/experimental/any/assign/2.cc @@ -23,28 +23,70 @@ using std::experimental::any; using std::experimental::any_cast; +bool moved = false; +bool copied = false; + + struct X { - bool moved = false; - bool moved_from = false; X() = default; - X(const X&) = default; - X(X&& x) : moved(true) { x.moved_from = true; } + X(const X&) { copied = true; } + X(X&& x) { moved = true; } +}; + +struct X2 +{ + X2() = default; + X2(const X2&) { copied = true; } + X2(X2&& x) noexcept { moved = true; } }; void test01() { + moved = false; X x; any a1; a1 = x; - VERIFY(x.moved_from == false); + VERIFY(moved == false); any a2; + copied = false; a2 = std::move(x); - VERIFY(x.moved_from == true); - VERIFY(any_cast<X&>(a2).moved == true ); + VERIFY(moved == true); + VERIFY(copied == false); } +void test02() +{ + moved = false; + X x; + any a1; + a1 = x; + VERIFY(moved == false); + any a2; + copied = false; + a2 = std::move(a1); + VERIFY(moved == false); + VERIFY(copied == false); +} + +void test03() +{ + moved = false; + X2 x; + any a1; + a1 = x; + VERIFY(copied && moved); + any a2; + moved = false; + copied = false; + a2 = std::move(a1); + VERIFY(moved == true); + VERIFY(copied == false); + } + int main() { test01(); + test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/experimental/any/assign/exception.cc b/libstdc++-v3/testsuite/experimental/any/assign/exception.cc new file mode 100644 index 0000000..f125213 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/any/assign/exception.cc @@ -0,0 +1,77 @@ +// { dg-do run { target c++14 } } + +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <experimental/any> +#include <testsuite_hooks.h> + +using std::experimental::any; +using std::experimental::any_cast; + +bool should_throw = false; +struct Bad +{ + Bad() = default; + Bad(const Bad&) {if (should_throw) throw 666;} +}; + +struct Bad2 +{ + Bad2() = default; + Bad2(const Bad2&) {if (should_throw) throw 666;} + Bad2(Bad2&&) noexcept {} +}; + +int del_count = 0; +struct Good +{ + Good() = default; + Good(const Good&) = default; + Good(Good&&) = default; + ~Good() {++del_count;} +}; + +int main() +{ + any a1 = Good(); + del_count = 0; + try { + Bad b; + any a2 = b; + should_throw = true; + a1 = a2; + } catch (...) { + auto x = any_cast<Good>(a1); + VERIFY( del_count == 0 ); + VERIFY( !a1.empty() ); + any_cast<Good>(a1); + } + any a3 = Good(); + del_count = 0; + try { + Bad2 b; + any a4 = b; + should_throw = true; + a3 = a4; + } catch (...) { + auto x = any_cast<Good>(a1); + VERIFY( del_count == 0 ); + VERIFY( !a1.empty() ); + any_cast<Good>(a1); + } +} diff --git a/libstdc++-v3/testsuite/experimental/any/cons/2.cc b/libstdc++-v3/testsuite/experimental/any/cons/2.cc index fef713d..c79573b 100644 --- a/libstdc++-v3/testsuite/experimental/any/cons/2.cc +++ b/libstdc++-v3/testsuite/experimental/any/cons/2.cc @@ -23,26 +23,59 @@ using std::experimental::any; using std::experimental::any_cast; +bool moved = false; +bool copied = false; + struct X { - bool moved = false; - bool moved_from = false; X() = default; - X(const X&) = default; - X(X&& x) : moved(true) { x.moved_from = true; } + X(const X&) { copied = true; } + X(X&& x) { moved = true; } +}; + +struct X2 +{ + X2() = default; + X2(const X2&) { copied = true; } + X2(X2&& x) noexcept { moved = true; } }; void test01() { + moved = false; X x; any a1(x); - VERIFY(x.moved_from == false); + VERIFY(moved == false); any a2(std::move(x)); - VERIFY(x.moved_from == true); - VERIFY(any_cast<X&>(a2).moved == true ); + VERIFY(moved == true); +} + +void test02() +{ + moved = false; + X x; + any a1(x); + VERIFY(moved == false); + copied = false; + any a2(std::move(a1)); + VERIFY(copied == false); +} + +void test03() +{ + moved = false; + X2 x; + any a1(x); + VERIFY(moved == false); + copied = false; + any a2(std::move(a1)); + VERIFY(copied == false); + VERIFY(moved == true); } 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 4310572..924e798 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc @@ -25,5 +25,5 @@ void test01() using std::experimental::any_cast; const any y(1); - any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 369 } + any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 359 } } |