1 // { dg-do run { target c++17 } }
3 // Copyright (C) 2013-2024 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
21 #include <testsuite_hooks.h>
28 tracker(int value
) : value(value
) { ++count
; }
29 ~tracker() { --count
; }
31 tracker(tracker
const& other
) : value(other
.value
) { ++count
; }
32 tracker(tracker
&& other
) : value(other
.value
)
38 tracker
& operator=(tracker
const&) = default;
39 tracker
& operator=(tracker
&&) = default;
46 int tracker::count
= 0;
50 struct throwing_construction
52 explicit throwing_construction(bool propagate
) : propagate(propagate
) { }
54 throwing_construction(throwing_construction
const& other
)
55 : propagate(other
.propagate
)
66 // [20.5.4.1] Constructors
70 std::optional
<long> o
{ i
};
72 VERIFY( *o
== 0x1234ABCD );
73 VERIFY( i
== 0x1234ABCD );
78 std::optional
<long> o
= i
;
80 VERIFY( *o
== 0x1234ABCD );
81 VERIFY( i
== 0x1234ABCD );
86 std::optional
<long> o
= { i
};
88 VERIFY( *o
== 0x1234ABCD );
89 VERIFY( i
== 0x1234ABCD );
94 std::optional
<long> o
{ std::move(i
) };
96 VERIFY( *o
== 0x1234ABCD );
97 VERIFY( i
== 0x1234ABCD );
102 std::optional
<long> o
= std::move(i
);
104 VERIFY( *o
== 0x1234ABCD );
105 VERIFY( i
== 0x1234ABCD );
110 std::optional
<long> o
= { std::move(i
) };
112 VERIFY( *o
== 0x1234ABCD );
113 VERIFY( i
== 0x1234ABCD );
117 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
118 std::optional
<std::vector
<int>> o
{ v
};
119 VERIFY( !v
.empty() );
120 VERIFY( o
->size() == 6 );
124 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
125 std::optional
<std::vector
<int>> o
= v
;
126 VERIFY( !v
.empty() );
127 VERIFY( o
->size() == 6 );
131 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
132 std::optional
<std::vector
<int>> o
{ v
};
133 VERIFY( !v
.empty() );
134 VERIFY( o
->size() == 6 );
138 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
139 std::optional
<std::vector
<int>> o
{ std::move(v
) };
141 VERIFY( o
->size() == 6 );
145 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
146 std::optional
<std::vector
<int>> o
= std::move(v
);
148 VERIFY( o
->size() == 6 );
152 std::vector
<int> v
= { 0, 1, 2, 3, 4, 5 };
153 std::optional
<std::vector
<int>> o
{ std::move(v
) };
155 VERIFY( o
->size() == 6 );
160 std::optional
<tracker
> o
= t
;
161 VERIFY( o
->value
== 333 );
162 VERIFY( tracker::count
== 2 );
163 VERIFY( t
.value
== 333 );
168 std::optional
<tracker
> o
= std::move(t
);
169 VERIFY( o
->value
== 333 );
170 VERIFY( tracker::count
== 2 );
171 VERIFY( t
.value
== -1 );
174 enum outcome
{ nothrow
, caught
, bad_catch
};
177 outcome result
= nothrow
;
178 throwing_construction t
{ false };
182 std::optional
<throwing_construction
> o
{ t
};
184 catch(exception
const&)
187 { result
= bad_catch
; }
189 VERIFY( result
== nothrow
);
193 outcome result
= nothrow
;
194 throwing_construction t
{ true };
198 std::optional
<throwing_construction
> o
{ t
};
200 catch(exception
const&)
203 { result
= bad_catch
; }
205 VERIFY( result
== caught
);
209 outcome result
= nothrow
;
210 throwing_construction t
{ false };
214 std::optional
<throwing_construction
> o
{ std::move(t
) };
216 catch(exception
const&)
219 { result
= bad_catch
; }
221 VERIFY( result
== nothrow
);
225 outcome result
= nothrow
;
226 throwing_construction t
{ true };
230 std::optional
<throwing_construction
> o
{ std::move(t
) };
232 catch(exception
const&)
235 { result
= bad_catch
; }
237 VERIFY( result
== caught
);
241 std::optional
<std::string
> os
= "foo";
245 X
& operator=(int) {return *this;}
247 std::optional
<X
> ox
{42};
248 std::optional
<int> oi
{42};
249 std::optional
<X
> ox2
{oi
};
250 std::optional
<std::string
> os2
;
252 std::optional
<X
> ox3
;
254 std::optional
<X
> ox4
;
258 std::optional
<int> oi
= std::optional
<short>();
260 std::optional
<std::string
> os
= std::optional
<const char*>();
262 std::optional
<std::optional
<int>> ooi
= std::optional
<int>();
264 ooi
= std::optional
<int>();
266 ooi
= std::optional
<int>(42);
269 std::optional
<std::optional
<int>> ooi2
= std::optional
<short>();
271 ooi2
= std::optional
<short>();
273 ooi2
= std::optional
<short>(6);
276 std::optional
<std::optional
<int>> ooi3
= std::optional
<int>(42);
279 std::optional
<std::optional
<int>> ooi4
= std::optional
<short>(6);