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