]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/optional/requirements.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / optional / requirements.cc
CommitLineData
52066eae 1// { dg-do run { target c++14 } }
2b5ab1e4 2
8d9254fc 3// Copyright (C) 2013-2020 Free Software Foundation, Inc.
2b5ab1e4
MB
4//
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)
9// any later version.
10
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.
15
c7cbb4da 16// You should have received a copy of the GNU General Public License along
2b5ab1e4
MB
17// with this library; see the file COPYING3. If not see
18// <http://www.gnu.org/licenses/>.
19
20#include <experimental/optional>
21#include <testsuite_hooks.h>
22
23#include <tuple>
24
4159cf0d
JW
25using std::experimental::bad_optional_access;
26static_assert( std::is_default_constructible<bad_optional_access>::value, "" );
27
2b5ab1e4
MB
28struct trivially_destructible
29{
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;
36};
37
38static_assert( std::is_trivially_destructible<trivially_destructible>(), "" );
39
40struct no_default_constructor
41{
42 no_default_constructor() = delete;
43};
44
45struct no_copy_constructor
46{
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;
52};
53
54struct no_copy_assignment
55{
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;
60};
61
62struct no_move_constructor
63{
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;
69};
70
71struct no_move_assignment
72{
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;
78};
79
80struct no_copy : no_copy_constructor, no_copy_assignment { };
81struct no_move : no_move_constructor, no_move_assignment { };
82
83// Laxest possible model of a value type for optional
84struct only_destructible
85{
86 only_destructible(only_destructible&&) = delete;
87};
88
89int main()
90{
91 {
92 static_assert( std::is_trivially_destructible<std::experimental::optional<trivially_destructible>>(), "" );
93 }
94
95 {
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>(), "" );
100 { O o; }
101 static_assert( std::is_copy_constructible<O>(), "" );
102 { O o; auto copy = o; }
103 static_assert( std::is_copy_assignable<O>(), "" );
104 { O o, p; p = 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); }
109 }
110
111 {
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>(), "" );
116 { O 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); }
123 }
124
125 {
126 using T = no_copy_assignment;
127 using O = std::experimental::optional<T>;
128 static_assert( std::is_default_constructible<O>(), "" );
129 { O 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); }
137 }
138
139 {
140 using T = no_copy;
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>(), "" );
144 { O 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); }
151 }
152
153 {
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>(), "" );
158 { O o; }
159 static_assert( std::is_copy_constructible<O>(), "" );
160 { O o; auto copy = o; }
161 static_assert( std::is_copy_assignable<O>(), "" );
162 /*
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.
169 */
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); }
175 }
176
177 {
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>(), "" );
182 { O o; }
183 static_assert( std::is_copy_constructible<O>(), "" );
184 { O o; auto copy = o; }
185 static_assert( std::is_copy_assignable<O>(), "" );
186 { O o, p; p = o; }
187 static_assert( std::is_move_constructible<O>(), "" );
188 { O o; auto moved_to = std::move(o); }
189 /*
190 * Paragraph 23 of same leads to a similar situation but with respect to move
191 * assignment.
192 */
193 static_assert( !std::is_move_assignable<T>(), "" );
194 static_assert( std::is_move_assignable<O>(), "" );
195 { O o, p; p = std::move(o); }
196 }
197
198 {
199 using T = no_move;
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>(), "" );
203 { O o; }
204 static_assert( std::is_copy_constructible<O>(), "" );
205 { O o; auto copy = o; }
206 static_assert( std::is_copy_assignable<O>(), "" );
207 { O o, p; p = 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); }
212 }
213
214 {
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>(), "" );
219 { O 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>(), "" );
224 }
225
226 {
227 /*
228 * Should not complain about 'invalid' specializations as long as
229 * they're not instantiated.
230 */
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>;
241
242 using X = std::tuple<A, B, C1, C2, C3, C4, D1, D2, D3, D4>;
243 }
244
245 {
246 std::experimental::optional<const int> o { 42 };
247 static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
248 VERIFY( o );
249 VERIFY( *o == 42 );
250 }
251
252 {
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, "" );
257 }
258}