1 // { dg-do run { target c++14 } }
3 // Copyright (C) 2013-2018 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/>.
20 #include <experimental/optional>
21 #include <testsuite_hooks.h>
25 using std::experimental::bad_optional_access
;
26 static_assert( std::is_default_constructible
<bad_optional_access
>::value
, "" );
28 struct trivially_destructible
30 trivially_destructible() = delete;
31 trivially_destructible(trivially_destructible
const&) = delete;
32 trivially_destructible
& operator=(trivially_destructible
const&) = delete;
33 trivially_destructible(trivially_destructible
&&) = delete;
34 trivially_destructible
& operator=(trivially_destructible
&&) = delete;
35 ~trivially_destructible() noexcept
= default;
38 static_assert( std::is_trivially_destructible
<trivially_destructible
>(), "" );
40 struct no_default_constructor
42 no_default_constructor() = delete;
45 struct no_copy_constructor
47 no_copy_constructor() = default;
48 no_copy_constructor(no_copy_constructor
const&) = delete;
49 no_copy_constructor
& operator=(no_copy_constructor
const&) = default;
50 no_copy_constructor(no_copy_constructor
&&) = default;
51 no_copy_constructor
& operator=(no_copy_constructor
&&) = default;
54 struct no_copy_assignment
56 no_copy_assignment() = default;
57 no_copy_assignment(no_copy_assignment
const&) = default;
58 no_copy_assignment(no_copy_assignment
&&) = default;
59 no_copy_assignment
& operator=(no_copy_assignment
&&) = default;
62 struct no_move_constructor
64 no_move_constructor() = default;
65 no_move_constructor(no_move_constructor
const&) = default;
66 no_move_constructor
& operator=(no_move_constructor
const&) = default;
67 no_move_constructor(no_move_constructor
&&) = delete;
68 no_move_constructor
& operator=(no_move_constructor
&&) = default;
71 struct no_move_assignment
73 no_move_assignment() = default;
74 no_move_assignment(no_move_assignment
const&) = default;
75 no_move_assignment
& operator=(no_move_assignment
const&) = default;
76 no_move_assignment(no_move_assignment
&&) = default;
77 no_move_assignment
& operator=(no_move_assignment
&&) = delete;
80 struct no_copy
: no_copy_constructor
, no_copy_assignment
{ };
81 struct no_move
: no_move_constructor
, no_move_assignment
{ };
83 // Laxest possible model of a value type for optional
84 struct only_destructible
86 only_destructible(only_destructible
&&) = delete;
92 static_assert( std::is_trivially_destructible
<std::experimental::optional
<trivially_destructible
>>(), "" );
96 using T
= no_default_constructor
;
97 using O
= std::experimental::optional
<T
>;
98 static_assert( std::is_same
<O::value_type
, T
>(), "" );
99 static_assert( std::is_default_constructible
<O
>(), "" );
101 static_assert( std::is_copy_constructible
<O
>(), "" );
102 { O o
; auto copy
= o
; }
103 static_assert( std::is_copy_assignable
<O
>(), "" );
105 static_assert( std::is_move_constructible
<O
>(), "" );
106 { O o
; auto moved_to
= std::move(o
); }
107 static_assert( std::is_move_assignable
<O
>(), "" );
108 { O o
, p
; p
= std::move(o
); }
112 using T
= no_copy_constructor
;
113 using O
= std::experimental::optional
<T
>;
114 static_assert( std::is_same
<O::value_type
, T
>(), "" );
115 static_assert( std::is_default_constructible
<O
>(), "" );
117 static_assert( !std::is_copy_constructible
<O
>(), "" );
118 static_assert( !std::is_copy_assignable
<O
>(), "" );
119 static_assert( std::is_move_constructible
<O
>(), "" );
120 { O o
; auto moved_to
= std::move(o
); }
121 static_assert( std::is_move_assignable
<O
>(), "" );
122 { O o
, p
; p
= std::move(o
); }
126 using T
= no_copy_assignment
;
127 using O
= std::experimental::optional
<T
>;
128 static_assert( std::is_default_constructible
<O
>(), "" );
130 static_assert( std::is_copy_constructible
<O
>(), "" );
131 { O o
; auto copy
= o
; }
132 static_assert( !std::is_copy_assignable
<O
>(), "" );
133 static_assert( std::is_move_constructible
<O
>(), "" );
134 { O o
; auto moved_to
= std::move(o
); }
135 static_assert( std::is_move_assignable
<O
>(), "" );
136 { O o
, p
; p
= std::move(o
); }
141 using O
= std::experimental::optional
<T
>;
142 static_assert( std::is_same
<O::value_type
, T
>(), "" );
143 static_assert( std::is_default_constructible
<O
>(), "" );
145 static_assert( !std::is_copy_constructible
<O
>(), "" );
146 static_assert( !std::is_copy_assignable
<O
>(), "" );
147 static_assert( std::is_move_constructible
<O
>(), "" );
148 { O o
; auto moved_to
= std::move(o
); }
149 static_assert( std::is_move_assignable
<O
>(), "" );
150 { O o
, p
; p
= std::move(o
); }
154 using T
= no_move_constructor
;
155 using O
= std::experimental::optional
<T
>;
156 static_assert( std::is_same
<O::value_type
, T
>(), "" );
157 static_assert( std::is_default_constructible
<O
>(), "" );
159 static_assert( std::is_copy_constructible
<O
>(), "" );
160 { O o
; auto copy
= o
; }
161 static_assert( std::is_copy_assignable
<O
>(), "" );
163 * T should be move constructible due to [12.8/11], which is a new rule in C++1y
164 * not yet implemented by GCC. Because there is already a special exception in C++11
165 * for the generation of the special members that GCC implements (at least some of the
166 * time), this does not affect the std::experimental::optional implementation however. So the assertion
167 * for T should be changed (or removed altogether) when the time comes, but the rest
168 * should however remain correct and unchanged.
170 static_assert( !std::is_move_constructible
<T
>(), "" );
171 static_assert( std::is_move_constructible
<O
>(), "" );
172 { O o
; auto moved_to
= std::move(o
); }
173 static_assert( std::is_move_assignable
<O
>(), "" );
174 { O o
, p
; p
= std::move(o
); }
178 using T
= no_move_assignment
;
179 using O
= std::experimental::optional
<T
>;
180 static_assert( std::is_same
<O::value_type
, T
>(), "" );
181 static_assert( std::is_default_constructible
<O
>(), "" );
183 static_assert( std::is_copy_constructible
<O
>(), "" );
184 { O o
; auto copy
= o
; }
185 static_assert( std::is_copy_assignable
<O
>(), "" );
187 static_assert( std::is_move_constructible
<O
>(), "" );
188 { O o
; auto moved_to
= std::move(o
); }
190 * Paragraph 23 of same leads to a similar situation but with respect to move
193 static_assert( !std::is_move_assignable
<T
>(), "" );
194 static_assert( std::is_move_assignable
<O
>(), "" );
195 { O o
, p
; p
= std::move(o
); }
200 using O
= std::experimental::optional
<T
>;
201 static_assert( std::is_same
<O::value_type
, T
>(), "" );
202 static_assert( std::is_default_constructible
<O
>(), "" );
204 static_assert( std::is_copy_constructible
<O
>(), "" );
205 { O o
; auto copy
= o
; }
206 static_assert( std::is_copy_assignable
<O
>(), "" );
208 static_assert( std::is_move_constructible
<O
>(), "" );
209 { O o
; auto moved_to
= std::move(o
); }
210 static_assert( std::is_move_assignable
<O
>(), "" );
211 { O o
, p
; p
= std::move(o
); }
215 using T
= only_destructible
;
216 using O
= std::experimental::optional
<T
>;
217 static_assert( std::is_same
<O::value_type
, T
>(), "" );
218 static_assert( std::is_default_constructible
<O
>(), "" );
220 static_assert( !std::is_copy_constructible
<O
>(), "" );
221 static_assert( !std::is_copy_assignable
<O
>(), "" );
222 static_assert( !std::is_move_constructible
<O
>(), "" );
223 static_assert( !std::is_move_assignable
<O
>(), "" );
228 * Should not complain about 'invalid' specializations as long as
229 * they're not instantiated.
231 using A
= std::experimental::optional
<int&>;
232 using B
= std::experimental::optional
<int&&>;
233 using C1
= std::experimental::optional
<std::experimental::in_place_t
>;
234 using C2
= std::experimental::optional
<std::experimental::in_place_t
const>;
235 using C3
= std::experimental::optional
<std::experimental::in_place_t
volatile>;
236 using C4
= std::experimental::optional
<std::experimental::in_place_t
const volatile>;
237 using D1
= std::experimental::optional
<std::experimental::nullopt_t
>;
238 using D2
= std::experimental::optional
<std::experimental::nullopt_t
const>;
239 using D3
= std::experimental::optional
<std::experimental::nullopt_t
volatile>;
240 using D4
= std::experimental::optional
<std::experimental::nullopt_t
const volatile>;
242 using X
= std::tuple
<A
, B
, C1
, C2
, C3
, C4
, D1
, D2
, D3
, D4
>;
246 std::experimental::optional
<const int> o
{ 42 };
247 static_assert( std::is_same
<decltype(o
)::value_type
, const int>(), "" );
253 constexpr std::experimental::optional
<const int> o
{ 33 };
254 static_assert( std::is_same
<decltype(o
)::value_type
, const int>(), "" );
255 static_assert( o
, "" );
256 static_assert( *o
== 33, "" );