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