1 // { dg-options "-std=gnu++1y" }
4 // Copyright (C) 2013-2014 Free Software Foundation, Inc.
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)
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.
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/>.
21 #include <experimental/optional>
22 #include <testsuite_hooks.h>
26 using std::experimental::bad_optional_access
;
27 static_assert( std::is_default_constructible
<bad_optional_access
>::value
, "" );
29 struct trivially_destructible
31 trivially_destructible() = delete;
32 trivially_destructible(trivially_destructible
const&) = delete;
33 trivially_destructible
& operator=(trivially_destructible
const&) = delete;
34 trivially_destructible(trivially_destructible
&&) = delete;
35 trivially_destructible
& operator=(trivially_destructible
&&) = delete;
36 ~trivially_destructible() noexcept
= default;
39 static_assert( std::is_trivially_destructible
<trivially_destructible
>(), "" );
41 struct no_default_constructor
43 no_default_constructor() = delete;
46 struct no_copy_constructor
48 no_copy_constructor() = default;
49 no_copy_constructor(no_copy_constructor
const&) = delete;
50 no_copy_constructor
& operator=(no_copy_constructor
const&) = default;
51 no_copy_constructor(no_copy_constructor
&&) = default;
52 no_copy_constructor
& operator=(no_copy_constructor
&&) = default;
55 struct no_copy_assignment
57 no_copy_assignment() = default;
58 no_copy_assignment(no_copy_assignment
const&) = default;
59 no_copy_assignment(no_copy_assignment
&&) = default;
60 no_copy_assignment
& operator=(no_copy_assignment
&&) = default;
63 struct no_move_constructor
65 no_move_constructor() = default;
66 no_move_constructor(no_move_constructor
const&) = default;
67 no_move_constructor
& operator=(no_move_constructor
const&) = default;
68 no_move_constructor(no_move_constructor
&&) = delete;
69 no_move_constructor
& operator=(no_move_constructor
&&) = default;
72 struct no_move_assignment
74 no_move_assignment() = default;
75 no_move_assignment(no_move_assignment
const&) = default;
76 no_move_assignment
& operator=(no_move_assignment
const&) = default;
77 no_move_assignment(no_move_assignment
&&) = default;
78 no_move_assignment
& operator=(no_move_assignment
&&) = delete;
81 struct no_copy
: no_copy_constructor
, no_copy_assignment
{ };
82 struct no_move
: no_move_constructor
, no_move_assignment
{ };
84 // Laxest possible model of a value type for optional
85 struct only_destructible
87 only_destructible(only_destructible
&&) = delete;
93 static_assert( std::is_trivially_destructible
<std::experimental::optional
<trivially_destructible
>>(), "" );
97 using T
= no_default_constructor
;
98 using O
= std::experimental::optional
<T
>;
99 static_assert( std::is_same
<O::value_type
, T
>(), "" );
100 static_assert( std::is_default_constructible
<O
>(), "" );
102 static_assert( std::is_copy_constructible
<O
>(), "" );
103 { O o
; auto copy
= o
; }
104 static_assert( std::is_copy_assignable
<O
>(), "" );
106 static_assert( std::is_move_constructible
<O
>(), "" );
107 { O o
; auto moved_to
= std::move(o
); }
108 static_assert( std::is_move_assignable
<O
>(), "" );
109 { O o
, p
; p
= std::move(o
); }
113 using T
= no_copy_constructor
;
114 using O
= std::experimental::optional
<T
>;
115 static_assert( std::is_same
<O::value_type
, T
>(), "" );
116 static_assert( std::is_default_constructible
<O
>(), "" );
118 static_assert( !std::is_copy_constructible
<O
>(), "" );
119 static_assert( !std::is_copy_assignable
<O
>(), "" );
120 static_assert( std::is_move_constructible
<O
>(), "" );
121 { O o
; auto moved_to
= std::move(o
); }
122 static_assert( std::is_move_assignable
<O
>(), "" );
123 { O o
, p
; p
= std::move(o
); }
127 using T
= no_copy_assignment
;
128 using O
= std::experimental::optional
<T
>;
129 static_assert( std::is_default_constructible
<O
>(), "" );
131 static_assert( std::is_copy_constructible
<O
>(), "" );
132 { O o
; auto copy
= o
; }
133 static_assert( !std::is_copy_assignable
<O
>(), "" );
134 static_assert( std::is_move_constructible
<O
>(), "" );
135 { O o
; auto moved_to
= std::move(o
); }
136 static_assert( std::is_move_assignable
<O
>(), "" );
137 { O o
, p
; p
= std::move(o
); }
142 using O
= std::experimental::optional
<T
>;
143 static_assert( std::is_same
<O::value_type
, T
>(), "" );
144 static_assert( std::is_default_constructible
<O
>(), "" );
146 static_assert( !std::is_copy_constructible
<O
>(), "" );
147 static_assert( !std::is_copy_assignable
<O
>(), "" );
148 static_assert( std::is_move_constructible
<O
>(), "" );
149 { O o
; auto moved_to
= std::move(o
); }
150 static_assert( std::is_move_assignable
<O
>(), "" );
151 { O o
, p
; p
= std::move(o
); }
155 using T
= no_move_constructor
;
156 using O
= std::experimental::optional
<T
>;
157 static_assert( std::is_same
<O::value_type
, T
>(), "" );
158 static_assert( std::is_default_constructible
<O
>(), "" );
160 static_assert( std::is_copy_constructible
<O
>(), "" );
161 { O o
; auto copy
= o
; }
162 static_assert( std::is_copy_assignable
<O
>(), "" );
164 * T should be move constructible due to [12.8/11], which is a new rule in C++1y
165 * not yet implemented by GCC. Because there is already a special exception in C++11
166 * for the generation of the special members that GCC implements (at least some of the
167 * time), this does not affect the std::experimental::optional implementation however. So the assertion
168 * for T should be changed (or removed altogether) when the time comes, but the rest
169 * should however remain correct and unchanged.
171 static_assert( !std::is_move_constructible
<T
>(), "" );
172 static_assert( std::is_move_constructible
<O
>(), "" );
173 { O o
; auto moved_to
= std::move(o
); }
174 static_assert( std::is_move_assignable
<O
>(), "" );
175 { O o
, p
; p
= std::move(o
); }
179 using T
= no_move_assignment
;
180 using O
= std::experimental::optional
<T
>;
181 static_assert( std::is_same
<O::value_type
, T
>(), "" );
182 static_assert( std::is_default_constructible
<O
>(), "" );
184 static_assert( std::is_copy_constructible
<O
>(), "" );
185 { O o
; auto copy
= o
; }
186 static_assert( std::is_copy_assignable
<O
>(), "" );
188 static_assert( std::is_move_constructible
<O
>(), "" );
189 { O o
; auto moved_to
= std::move(o
); }
191 * Paragraph 23 of same leads to a similar situation but with respect to move
194 static_assert( !std::is_move_assignable
<T
>(), "" );
195 static_assert( std::is_move_assignable
<O
>(), "" );
196 { O o
, p
; p
= std::move(o
); }
201 using O
= std::experimental::optional
<T
>;
202 static_assert( std::is_same
<O::value_type
, T
>(), "" );
203 static_assert( std::is_default_constructible
<O
>(), "" );
205 static_assert( std::is_copy_constructible
<O
>(), "" );
206 { O o
; auto copy
= o
; }
207 static_assert( std::is_copy_assignable
<O
>(), "" );
209 static_assert( std::is_move_constructible
<O
>(), "" );
210 { O o
; auto moved_to
= std::move(o
); }
211 static_assert( std::is_move_assignable
<O
>(), "" );
212 { O o
, p
; p
= std::move(o
); }
216 using T
= only_destructible
;
217 using O
= std::experimental::optional
<T
>;
218 static_assert( std::is_same
<O::value_type
, T
>(), "" );
219 static_assert( std::is_default_constructible
<O
>(), "" );
221 static_assert( !std::is_copy_constructible
<O
>(), "" );
222 static_assert( !std::is_copy_assignable
<O
>(), "" );
223 static_assert( !std::is_move_constructible
<O
>(), "" );
224 static_assert( !std::is_move_assignable
<O
>(), "" );
229 * Should not complain about 'invalid' specializations as long as
230 * they're not instantiated.
232 using A
= std::experimental::optional
<int&>;
233 using B
= std::experimental::optional
<int&&>;
234 using C1
= std::experimental::optional
<std::experimental::in_place_t
>;
235 using C2
= std::experimental::optional
<std::experimental::in_place_t
const>;
236 using C3
= std::experimental::optional
<std::experimental::in_place_t
volatile>;
237 using C4
= std::experimental::optional
<std::experimental::in_place_t
const volatile>;
238 using D1
= std::experimental::optional
<std::experimental::nullopt_t
>;
239 using D2
= std::experimental::optional
<std::experimental::nullopt_t
const>;
240 using D3
= std::experimental::optional
<std::experimental::nullopt_t
volatile>;
241 using D4
= std::experimental::optional
<std::experimental::nullopt_t
const volatile>;
243 using X
= std::tuple
<A
, B
, C1
, C2
, C3
, C4
, D1
, D2
, D3
, D4
>;
247 std::experimental::optional
<const int> o
{ 42 };
248 static_assert( std::is_same
<decltype(o
)::value_type
, const int>(), "" );
254 constexpr std::experimental::optional
<const int> o
{ 33 };
255 static_assert( std::is_same
<decltype(o
)::value_type
, const int>(), "" );
256 static_assert( o
, "" );
257 static_assert( *o
== 33, "" );