1 // { dg-options "-std=gnu++17" }
4 // Copyright (C) 2013-2018 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 copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
22 #include <testsuite_hooks.h>
26 using std::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::optional
<trivially_destructible
>>(), "" );
97 using T
= no_default_constructor
;
98 using O
= std::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::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::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::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::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::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::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::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::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::optional
<int&>;
233 using B
= std::optional
<int&&>;
234 using C1
= std::optional
<std::in_place_t
>;
235 using C2
= std::optional
<std::in_place_t
const>;
236 using C3
= std::optional
<std::in_place_t
volatile>;
237 using C4
= std::optional
<std::in_place_t
const volatile>;
238 using D1
= std::optional
<std::nullopt_t
>;
239 using D2
= std::optional
<std::nullopt_t
const>;
240 using D3
= std::optional
<std::nullopt_t
volatile>;
241 using D4
= std::optional
<std::nullopt_t
const volatile>;
243 using X
= std::tuple
<A
, B
, C1
, C2
, C3
, C4
, D1
, D2
, D3
, D4
>;
247 std::optional
<const int> o
{ 42 };
248 static_assert( std::is_same
<decltype(o
)::value_type
, const int>(), "" );
254 constexpr std::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, "" );
263 using std::true_type
;
264 using std::false_type
;
266 template <class T
, class = void>
267 struct is_eq_comparable
: false_type
{};
269 struct is_eq_comparable
<T
, void_t
<decltype(declval
<T
>() == declval
<T
>())>>
272 template <class T
, class = void>
273 struct is_neq_comparable
: false_type
{};
275 struct is_neq_comparable
<T
, void_t
<decltype(declval
<T
>() != declval
<T
>())>>
278 template <class T
, class = void>
279 struct is_lt_comparable
: false_type
{};
281 struct is_lt_comparable
<T
, void_t
<decltype(declval
<T
>() < declval
<T
>())>>
284 template <class T
, class = void>
285 struct is_gt_comparable
: false_type
{};
287 struct is_gt_comparable
<T
, void_t
<decltype(declval
<T
>() > declval
<T
>())>>
290 template <class T
, class = void>
291 struct is_le_comparable
: false_type
{};
293 struct is_le_comparable
<T
, void_t
<decltype(declval
<T
>() <= declval
<T
>())>>
296 template <class T
, class = void>
297 struct is_ge_comparable
: false_type
{};
299 struct is_ge_comparable
<T
, void_t
<decltype(declval
<T
>() >= declval
<T
>())>>
304 static_assert(is_eq_comparable
<optional
<int>>::value
, "");
305 static_assert(is_neq_comparable
<optional
<int>>::value
, "");
306 static_assert(is_lt_comparable
<optional
<int>>::value
, "");
307 static_assert(is_gt_comparable
<optional
<int>>::value
, "");
308 static_assert(is_le_comparable
<optional
<int>>::value
, "");
309 static_assert(is_ge_comparable
<optional
<int>>::value
, "");
312 bool operator==(const JustEq
&, const JustEq
&);
314 static_assert(is_eq_comparable
<optional
<JustEq
>>::value
, "");
315 static_assert(!is_neq_comparable
<optional
<JustEq
>>::value
, "");
316 static_assert(!is_lt_comparable
<optional
<JustEq
>>::value
, "");
317 static_assert(!is_gt_comparable
<optional
<JustEq
>>::value
, "");
318 static_assert(!is_le_comparable
<optional
<JustEq
>>::value
, "");
319 static_assert(!is_ge_comparable
<optional
<JustEq
>>::value
, "");
322 bool operator<(const JustLt
&, const JustLt
&);
324 static_assert(!is_eq_comparable
<optional
<JustLt
>>::value
, "");
325 static_assert(!is_neq_comparable
<optional
<JustLt
>>::value
, "");
326 static_assert(is_lt_comparable
<optional
<JustLt
>>::value
, "");
327 static_assert(!is_gt_comparable
<optional
<JustLt
>>::value
, "");
328 static_assert(!is_le_comparable
<optional
<JustLt
>>::value
, "");
329 static_assert(!is_ge_comparable
<optional
<JustLt
>>::value
, "");
331 static_assert(!std::is_assignable
<optional
<JustEq
>&,
332 optional
<JustLt
>>::value
, "");
333 static_assert(!std::is_assignable
<optional
<JustEq
>&,
335 static_assert(!std::is_assignable
<optional
<JustEq
>&,
336 optional
<JustLt
>&>::value
, "");
337 static_assert(!std::is_assignable
<optional
<JustEq
>&,
338 JustLt
&>::value
, "");