| 1 | // Copyright (C) 2013-2019 Free Software Foundation, Inc. |
| 2 | // |
| 3 | // This file is part of the GNU ISO C++ Library. This library is free |
| 4 | // software; you can redistribute it and/or modify it under the |
| 5 | // terms of the GNU General Public License as published by the |
| 6 | // Free Software Foundation; either version 3, or (at your option) |
| 7 | // any later version. |
| 8 | |
| 9 | // This library is distributed in the hope that it will be useful, |
| 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | // GNU General Public License for more details. |
| 13 | |
| 14 | // You should have received a copy of the GNU General Public License along |
| 15 | // with this library; see the file COPYING3. If not see |
| 16 | // <http://www.gnu.org/licenses/>. |
| 17 | |
| 18 | namespace cons_move { |
| 19 | |
| 20 | struct tracker |
| 21 | { |
| 22 | tracker(int value) : value(value) { ++count; } |
| 23 | ~tracker() { --count; } |
| 24 | |
| 25 | tracker(tracker const& other) : value(other.value) { ++count; } |
| 26 | tracker(tracker&& other) : value(other.value) |
| 27 | { |
| 28 | other.value = -1; |
| 29 | ++count; |
| 30 | } |
| 31 | |
| 32 | tracker& operator=(tracker const&) = default; |
| 33 | tracker& operator=(tracker&&) = default; |
| 34 | |
| 35 | int value; |
| 36 | |
| 37 | static int count; |
| 38 | }; |
| 39 | |
| 40 | int tracker::count = 0; |
| 41 | |
| 42 | struct exception { }; |
| 43 | |
| 44 | struct throwing_move |
| 45 | { |
| 46 | throwing_move() = default; |
| 47 | throwing_move(throwing_move const&) { throw exception {}; } |
| 48 | }; |
| 49 | |
| 50 | void test() |
| 51 | { |
| 52 | // [20.5.4.1] Constructors |
| 53 | |
| 54 | { |
| 55 | gdb::optional<long> o; |
| 56 | auto moved_to = std::move(o); |
| 57 | VERIFY( !moved_to ); |
| 58 | VERIFY( !o ); |
| 59 | } |
| 60 | |
| 61 | { |
| 62 | const long val = 0x1234ABCD; |
| 63 | gdb::optional<long> o { gdb::in_place, val}; |
| 64 | auto moved_to = std::move(o); |
| 65 | VERIFY( moved_to ); |
| 66 | VERIFY( *moved_to == val ); |
| 67 | VERIFY( o && *o == val ); |
| 68 | } |
| 69 | |
| 70 | { |
| 71 | gdb::optional<tracker> o; |
| 72 | auto moved_to = std::move(o); |
| 73 | VERIFY( !moved_to ); |
| 74 | VERIFY( tracker::count == 0 ); |
| 75 | VERIFY( !o ); |
| 76 | } |
| 77 | |
| 78 | { |
| 79 | gdb::optional<tracker> o { gdb::in_place, 333 }; |
| 80 | auto moved_to = std::move(o); |
| 81 | VERIFY( moved_to ); |
| 82 | VERIFY( moved_to->value == 333 ); |
| 83 | VERIFY( tracker::count == 2 ); |
| 84 | VERIFY( o && o->value == -1 ); |
| 85 | } |
| 86 | |
| 87 | enum outcome { nothrow, caught, bad_catch }; |
| 88 | |
| 89 | { |
| 90 | outcome result = nothrow; |
| 91 | gdb::optional<throwing_move> o; |
| 92 | |
| 93 | try |
| 94 | { |
| 95 | auto moved_to = std::move(o); |
| 96 | } |
| 97 | catch(exception const&) |
| 98 | { result = caught; } |
| 99 | catch(...) |
| 100 | { result = bad_catch; } |
| 101 | |
| 102 | VERIFY( result == nothrow ); |
| 103 | } |
| 104 | |
| 105 | { |
| 106 | outcome result = nothrow; |
| 107 | gdb::optional<throwing_move> o { gdb::in_place }; |
| 108 | |
| 109 | try |
| 110 | { |
| 111 | auto moved_to = std::move(o); |
| 112 | } |
| 113 | catch(exception const&) |
| 114 | { result = caught; } |
| 115 | catch(...) |
| 116 | { result = bad_catch; } |
| 117 | |
| 118 | VERIFY( result == caught ); |
| 119 | } |
| 120 | |
| 121 | VERIFY( tracker::count == 0 ); |
| 122 | } |
| 123 | |
| 124 | } // namespace cons_move |