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_value { 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_construction 45 { 46 explicit throwing_construction(bool propagate) : propagate(propagate) { } 47 48 throwing_construction(throwing_construction const& other) 49 : propagate(other.propagate) 50 { 51 if(propagate) 52 throw exception {}; 53 } 54 55 bool propagate; 56 }; 57 58 void test() 59 { 60 // [20.5.4.1] Constructors 61 62 { 63 auto i = 0x1234ABCD; 64 gdb::optional<long> o { i }; 65 VERIFY( o ); 66 VERIFY( *o == 0x1234ABCD ); 67 VERIFY( i == 0x1234ABCD ); 68 } 69 70 { 71 auto i = 0x1234ABCD; 72 gdb::optional<long> o = i; 73 VERIFY( o ); 74 VERIFY( *o == 0x1234ABCD ); 75 VERIFY( i == 0x1234ABCD ); 76 } 77 78 { 79 auto i = 0x1234ABCD; 80 gdb::optional<long> o = { i }; 81 VERIFY( o ); 82 VERIFY( *o == 0x1234ABCD ); 83 VERIFY( i == 0x1234ABCD ); 84 } 85 86 { 87 auto i = 0x1234ABCD; 88 gdb::optional<long> o { std::move(i) }; 89 VERIFY( o ); 90 VERIFY( *o == 0x1234ABCD ); 91 VERIFY( i == 0x1234ABCD ); 92 } 93 94 { 95 auto i = 0x1234ABCD; 96 gdb::optional<long> o = std::move(i); 97 VERIFY( o ); 98 VERIFY( *o == 0x1234ABCD ); 99 VERIFY( i == 0x1234ABCD ); 100 } 101 102 { 103 auto i = 0x1234ABCD; 104 gdb::optional<long> o = { std::move(i) }; 105 VERIFY( o ); 106 VERIFY( *o == 0x1234ABCD ); 107 VERIFY( i == 0x1234ABCD ); 108 } 109 110 #ifndef GDB_OPTIONAL 111 { 112 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 113 gdb::optional<std::vector<int>> o { v }; 114 VERIFY( !v.empty() ); 115 VERIFY( o->size() == 6 ); 116 } 117 #endif 118 119 { 120 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 121 gdb::optional<std::vector<int>> o = v; 122 VERIFY( !v.empty() ); 123 VERIFY( o->size() == 6 ); 124 } 125 126 { 127 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 128 gdb::optional<std::vector<int>> o { v }; 129 VERIFY( !v.empty() ); 130 VERIFY( o->size() == 6 ); 131 } 132 133 { 134 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 135 gdb::optional<std::vector<int>> o { std::move(v) }; 136 VERIFY( v.empty() ); 137 VERIFY( o->size() == 6 ); 138 } 139 140 { 141 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 142 gdb::optional<std::vector<int>> o = std::move(v); 143 VERIFY( v.empty() ); 144 VERIFY( o->size() == 6 ); 145 } 146 147 { 148 std::vector<int> v = { 0, 1, 2, 3, 4, 5 }; 149 gdb::optional<std::vector<int>> o { std::move(v) }; 150 VERIFY( v.empty() ); 151 VERIFY( o->size() == 6 ); 152 } 153 154 { 155 tracker t { 333 }; 156 gdb::optional<tracker> o = t; 157 VERIFY( o->value == 333 ); 158 VERIFY( tracker::count == 2 ); 159 VERIFY( t.value == 333 ); 160 } 161 162 { 163 tracker t { 333 }; 164 gdb::optional<tracker> o = std::move(t); 165 VERIFY( o->value == 333 ); 166 VERIFY( tracker::count == 2 ); 167 VERIFY( t.value == -1 ); 168 } 169 170 enum outcome { nothrow, caught, bad_catch }; 171 172 { 173 outcome result = nothrow; 174 throwing_construction t { false }; 175 176 try 177 { 178 gdb::optional<throwing_construction> o { t }; 179 } 180 catch(exception const&) 181 { result = caught; } 182 catch(...) 183 { result = bad_catch; } 184 185 VERIFY( result == nothrow ); 186 } 187 188 { 189 outcome result = nothrow; 190 throwing_construction t { true }; 191 192 try 193 { 194 gdb::optional<throwing_construction> o { t }; 195 } 196 catch(exception const&) 197 { result = caught; } 198 catch(...) 199 { result = bad_catch; } 200 201 VERIFY( result == caught ); 202 } 203 204 { 205 outcome result = nothrow; 206 throwing_construction t { false }; 207 208 try 209 { 210 gdb::optional<throwing_construction> o { std::move(t) }; 211 } 212 catch(exception const&) 213 { result = caught; } 214 catch(...) 215 { result = bad_catch; } 216 217 VERIFY( result == nothrow ); 218 } 219 220 { 221 outcome result = nothrow; 222 throwing_construction t { true }; 223 224 try 225 { 226 gdb::optional<throwing_construction> o { std::move(t) }; 227 } 228 catch(exception const&) 229 { result = caught; } 230 catch(...) 231 { result = bad_catch; } 232 233 VERIFY( result == caught ); 234 } 235 236 { 237 #ifndef GDB_OPTIONAL 238 gdb::optional<std::string> os = "foo"; 239 #endif 240 struct X 241 { 242 explicit X(int) {} 243 X& operator=(int) {return *this;} 244 }; 245 #ifndef GDB_OPTIONAL 246 gdb::optional<X> ox{42}; 247 #endif 248 gdb::optional<int> oi{42}; 249 #ifndef GDB_OPTIONAL 250 gdb::optional<X> ox2{oi}; 251 #endif 252 gdb::optional<std::string> os2; 253 os2 = "foo"; 254 #ifndef GDB_OPTIONAL 255 gdb::optional<X> ox3; 256 ox3 = 42; 257 gdb::optional<X> ox4; 258 ox4 = oi; 259 #endif 260 } 261 { 262 // no converting construction. 263 #ifndef GDB_OPTIONAL 264 gdb::optional<int> oi = gdb::optional<short>(); 265 VERIFY(!bool(oi)); 266 gdb::optional<std::string> os = gdb::optional<const char*>(); 267 VERIFY(!bool(os)); 268 #endif 269 gdb::optional<gdb::optional<int>> ooi = gdb::optional<int>(); 270 VERIFY(bool(ooi)); 271 ooi = gdb::optional<int>(); 272 VERIFY(bool(ooi)); 273 ooi = gdb::optional<int>(42); 274 VERIFY(bool(ooi)); 275 VERIFY(bool(*ooi)); 276 #ifndef GDB_OPTIONAL 277 gdb::optional<gdb::optional<int>> ooi2 = gdb::optional<short>(); 278 VERIFY(bool(ooi2)); 279 ooi2 = gdb::optional<short>(); 280 VERIFY(bool(ooi2)); 281 ooi2 = gdb::optional<short>(6); 282 VERIFY(bool(ooi2)); 283 VERIFY(bool(*ooi2)); 284 gdb::optional<gdb::optional<int>> ooi3 = gdb::optional<int>(42); 285 VERIFY(bool(ooi3)); 286 VERIFY(bool(*ooi3)); 287 gdb::optional<gdb::optional<int>> ooi4 = gdb::optional<short>(6); 288 VERIFY(bool(ooi4)); 289 VERIFY(bool(*ooi4)); 290 #endif 291 } 292 } 293 294 } // namespace cons_value 295