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 24#include <vector> 25 26struct tracker 27{ 28 tracker(int value) : value(value) { ++count; } 29 ~tracker() { --count; } 30 31 tracker(tracker const& other) : value(other.value) { ++count; } 32 tracker(tracker&& other) : value(other.value) 33 { 34 other.value = -1; 35 ++count; 36 } 37 38 tracker& operator=(tracker const&) = default; 39 tracker& operator=(tracker&&) = default; 40 41 int value; 42 43 static int count; 44}; 45 46int tracker::count = 0; 47 48struct exception { }; 49 50struct throwing_construction 51{ 52 explicit throwing_construction(bool propagate) : propagate(propagate) { } 53 54 throwing_construction(throwing_construction const& other) 55 : propagate(other.propagate) 56 { 57 if(propagate) 58 throw exception {}; 59 } 60 61 bool propagate; 62}; 63 64int main() 65{ 66 // [20.5.4.1] Constructors 67 68 { 69 auto i = 0x1234ABCD; 70 std::experimental::optional<long> o { i }; 71 VERIFY( o ); 72 VERIFY( *o == 0x1234ABCD ); 73 VERIFY( i == 0x1234ABCD ); 74 } 75 76 { 77 auto i = 0x1234ABCD; 78 std::experimental::optional<long> o = i; 79 VERIFY( o ); 80 VERIFY( *o == 0x1234ABCD ); 81 VERIFY( i == 0x1234ABCD ); 82 } 83 84 { 85 auto i = 0x1234ABCD; 86 std::experimental::optional<long> o = { i }; 87 VERIFY( o ); 88 VERIFY( *o == 0x1234ABCD ); 89 VERIFY( i == 0x1234ABCD ); 90 } 91 92 { 93 auto i = 0x1234ABCD; 94 std::experimental::optional<long> o { std::move(i) }; 95 VERIFY( o ); 96 VERIFY( *o == 0x1234ABCD ); 97 VERIFY( i == 0x1234ABCD ); 98 } 99 100 { 101 auto i = 0x1234ABCD; 102 std::experimental::optional<long> o = std::move(i); 103 VERIFY( o ); 104 VERIFY( *o == 0x1234ABCD ); 105 VERIFY( i == 0x1234ABCD ); 106 } 107 108 { 109 auto i = 0x1234ABCD; 110 std::experimental::optional<long> o = { std::move(i) }; 111 VERIFY( o ); 112 VERIFY( *o == 0x1234ABCD ); 113 VERIFY( i == 0x1234ABCD ); 114 } 115 116 { 117 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 118 std::experimental::optional<std::vector<int>> o { v }; 119 VERIFY( !v.empty() ); 120 VERIFY( o->size() == 6 ); 121 } 122 123 { 124 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 125 std::experimental::optional<std::vector<int>> o = v; 126 VERIFY( !v.empty() ); 127 VERIFY( o->size() == 6 ); 128 } 129 130 { 131 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 132 std::experimental::optional<std::vector<int>> o { v }; 133 VERIFY( !v.empty() ); 134 VERIFY( o->size() == 6 ); 135 } 136 137 { 138 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 139 std::experimental::optional<std::vector<int>> o { std::move(v) }; 140 VERIFY( v.empty() ); 141 VERIFY( o->size() == 6 ); 142 } 143 144 { 145 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 146 std::experimental::optional<std::vector<int>> o = std::move(v); 147 VERIFY( v.empty() ); 148 VERIFY( o->size() == 6 ); 149 } 150 151 { 152 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 153 std::experimental::optional<std::vector<int>> o { std::move(v) }; 154 VERIFY( v.empty() ); 155 VERIFY( o->size() == 6 ); 156 } 157 158 { 159 tracker t { 333 }; 160 std::experimental::optional<tracker> o = t; 161 VERIFY( o->value == 333 ); 162 VERIFY( tracker::count == 2 ); 163 VERIFY( t.value == 333 ); 164 } 165 166 { 167 tracker t { 333 }; 168 std::experimental::optional<tracker> o = std::move(t); 169 VERIFY( o->value == 333 ); 170 VERIFY( tracker::count == 2 ); 171 VERIFY( t.value == -1 ); 172 } 173 174 enum outcome { nothrow, caught, bad_catch }; 175 176 { 177 outcome result = nothrow; 178 throwing_construction t { false }; 179 180 try 181 { 182 std::experimental::optional<throwing_construction> o { t }; 183 } 184 catch(exception const&) 185 { result = caught; } 186 catch(...) 187 { result = bad_catch; } 188 189 VERIFY( result == nothrow ); 190 } 191 192 { 193 outcome result = nothrow; 194 throwing_construction t { true }; 195 196 try 197 { 198 std::experimental::optional<throwing_construction> o { t }; 199 } 200 catch(exception const&) 201 { result = caught; } 202 catch(...) 203 { result = bad_catch; } 204 205 VERIFY( result == caught ); 206 } 207 208 { 209 outcome result = nothrow; 210 throwing_construction t { false }; 211 212 try 213 { 214 std::experimental::optional<throwing_construction> o { std::move(t) }; 215 } 216 catch(exception const&) 217 { result = caught; } 218 catch(...) 219 { result = bad_catch; } 220 221 VERIFY( result == nothrow ); 222 } 223 224 { 225 outcome result = nothrow; 226 throwing_construction t { true }; 227 228 try 229 { 230 std::experimental::optional<throwing_construction> o { std::move(t) }; 231 } 232 catch(exception const&) 233 { result = caught; } 234 catch(...) 235 { result = bad_catch; } 236 237 VERIFY( result == caught ); 238 } 239} 240