1 // Copyright (C) 2013-2020 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 { trackercons_move::tracker22 tracker(int value) : value(value) { ++count; } ~trackercons_move::tracker23 ~tracker() { --count; } 24 trackercons_move::tracker25 tracker(tracker const& other) : value(other.value) { ++count; } trackercons_move::tracker26 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; throwing_movecons_move::throwing_move47 throwing_move(throwing_move const&) { throw exception {}; } 48 }; 49 50 static void test()51test () 52 { 53 // [20.5.4.1] Constructors 54 55 { 56 gdb::optional<long> o; 57 auto moved_to = std::move(o); 58 VERIFY( !moved_to ); 59 VERIFY( !o ); 60 } 61 62 { 63 const long val = 0x1234ABCD; 64 gdb::optional<long> o { gdb::in_place, val}; 65 auto moved_to = std::move(o); 66 VERIFY( moved_to ); 67 VERIFY( *moved_to == val ); 68 VERIFY( o && *o == val ); 69 } 70 71 { 72 gdb::optional<tracker> o; 73 auto moved_to = std::move(o); 74 VERIFY( !moved_to ); 75 VERIFY( tracker::count == 0 ); 76 VERIFY( !o ); 77 } 78 79 { 80 gdb::optional<tracker> o { gdb::in_place, 333 }; 81 auto moved_to = std::move(o); 82 VERIFY( moved_to ); 83 VERIFY( moved_to->value == 333 ); 84 VERIFY( tracker::count == 2 ); 85 VERIFY( o && o->value == -1 ); 86 } 87 88 enum outcome { nothrow, caught, bad_catch }; 89 90 { 91 outcome result = nothrow; 92 gdb::optional<throwing_move> o; 93 94 try 95 { 96 auto moved_to = std::move(o); 97 } 98 catch(exception const&) 99 { result = caught; } 100 catch(...) 101 { result = bad_catch; } 102 103 VERIFY( result == nothrow ); 104 } 105 106 { 107 outcome result = nothrow; 108 gdb::optional<throwing_move> o { gdb::in_place }; 109 110 try 111 { 112 auto moved_to = std::move(o); 113 } 114 catch(exception const&) 115 { result = caught; } 116 catch(...) 117 { result = bad_catch; } 118 119 VERIFY( result == caught ); 120 } 121 122 VERIFY( tracker::count == 0 ); 123 } 124 125 } // namespace cons_move 126