]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/optional/requirements.cc
Update copyright years in libstdc++-v3/
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / optional / requirements.cc
CommitLineData
2b5ab1e4
MB
1// { dg-options "-std=gnu++1y" }
2// { dg-do run }
3
aa118a03 4// Copyright (C) 2013-2014 Free Software Foundation, Inc.
2b5ab1e4
MB
5//
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)
10// any later version.
11
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.
16
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/>.
20
21#include <experimental/optional>
22#include <testsuite_hooks.h>
23
24#include <tuple>
25
26struct trivially_destructible
27{
28 trivially_destructible() = delete;
29 trivially_destructible(trivially_destructible const&) = delete;
30 trivially_destructible& operator=(trivially_destructible const&) = delete;
31 trivially_destructible(trivially_destructible&&) = delete;
32 trivially_destructible& operator=(trivially_destructible&&) = delete;
33 ~trivially_destructible() noexcept = default;
34};
35
36static_assert( std::is_trivially_destructible<trivially_destructible>(), "" );
37
38struct no_default_constructor
39{
40 no_default_constructor() = delete;
41};
42
43struct no_copy_constructor
44{
45 no_copy_constructor() = default;
46 no_copy_constructor(no_copy_constructor const&) = delete;
47 no_copy_constructor& operator=(no_copy_constructor const&) = default;
48 no_copy_constructor(no_copy_constructor&&) = default;
49 no_copy_constructor& operator=(no_copy_constructor&&) = default;
50};
51
52struct no_copy_assignment
53{
54 no_copy_assignment() = default;
55 no_copy_assignment(no_copy_assignment const&) = default;
56 no_copy_assignment(no_copy_assignment&&) = default;
57 no_copy_assignment& operator=(no_copy_assignment&&) = default;
58};
59
60struct no_move_constructor
61{
62 no_move_constructor() = default;
63 no_move_constructor(no_move_constructor const&) = default;
64 no_move_constructor& operator=(no_move_constructor const&) = default;
65 no_move_constructor(no_move_constructor&&) = delete;
66 no_move_constructor& operator=(no_move_constructor&&) = default;
67};
68
69struct no_move_assignment
70{
71 no_move_assignment() = default;
72 no_move_assignment(no_move_assignment const&) = default;
73 no_move_assignment& operator=(no_move_assignment const&) = default;
74 no_move_assignment(no_move_assignment&&) = default;
75 no_move_assignment& operator=(no_move_assignment&&) = delete;
76};
77
78struct no_copy : no_copy_constructor, no_copy_assignment { };
79struct no_move : no_move_constructor, no_move_assignment { };
80
81// Laxest possible model of a value type for optional
82struct only_destructible
83{
84 only_destructible(only_destructible&&) = delete;
85};
86
87int main()
88{
89 {
90 static_assert( std::is_trivially_destructible<std::experimental::optional<trivially_destructible>>(), "" );
91 }
92
93 {
94 using T = no_default_constructor;
95 using O = std::experimental::optional<T>;
96 static_assert( std::is_same<O::value_type, T>(), "" );
97 static_assert( std::is_default_constructible<O>(), "" );
98 { O o; }
99 static_assert( std::is_copy_constructible<O>(), "" );
100 { O o; auto copy = o; }
101 static_assert( std::is_copy_assignable<O>(), "" );
102 { O o, p; p = o; }
103 static_assert( std::is_move_constructible<O>(), "" );
104 { O o; auto moved_to = std::move(o); }
105 static_assert( std::is_move_assignable<O>(), "" );
106 { O o, p; p = std::move(o); }
107 }
108
109 {
110 using T = no_copy_constructor;
111 using O = std::experimental::optional<T>;
112 static_assert( std::is_same<O::value_type, T>(), "" );
113 static_assert( std::is_default_constructible<O>(), "" );
114 { O o; }
115 static_assert( !std::is_copy_constructible<O>(), "" );
116 static_assert( !std::is_copy_assignable<O>(), "" );
117 static_assert( std::is_move_constructible<O>(), "" );
118 { O o; auto moved_to = std::move(o); }
119 static_assert( std::is_move_assignable<O>(), "" );
120 { O o, p; p = std::move(o); }
121 }
122
123 {
124 using T = no_copy_assignment;
125 using O = std::experimental::optional<T>;
126 static_assert( std::is_default_constructible<O>(), "" );
127 { O o; }
128 static_assert( std::is_copy_constructible<O>(), "" );
129 { O o; auto copy = o; }
130 static_assert( !std::is_copy_assignable<O>(), "" );
131 static_assert( std::is_move_constructible<O>(), "" );
132 { O o; auto moved_to = std::move(o); }
133 static_assert( std::is_move_assignable<O>(), "" );
134 { O o, p; p = std::move(o); }
135 }
136
137 {
138 using T = no_copy;
139 using O = std::experimental::optional<T>;
140 static_assert( std::is_same<O::value_type, T>(), "" );
141 static_assert( std::is_default_constructible<O>(), "" );
142 { O o; }
143 static_assert( !std::is_copy_constructible<O>(), "" );
144 static_assert( !std::is_copy_assignable<O>(), "" );
145 static_assert( std::is_move_constructible<O>(), "" );
146 { O o; auto moved_to = std::move(o); }
147 static_assert( std::is_move_assignable<O>(), "" );
148 { O o, p; p = std::move(o); }
149 }
150
151 {
152 using T = no_move_constructor;
153 using O = std::experimental::optional<T>;
154 static_assert( std::is_same<O::value_type, T>(), "" );
155 static_assert( std::is_default_constructible<O>(), "" );
156 { O o; }
157 static_assert( std::is_copy_constructible<O>(), "" );
158 { O o; auto copy = o; }
159 static_assert( std::is_copy_assignable<O>(), "" );
160 /*
161 * T should be move constructible due to [12.8/11], which is a new rule in C++1y
162 * not yet implemented by GCC. Because there is already a special exception in C++11
163 * for the generation of the special members that GCC implements (at least some of the
164 * time), this does not affect the std::experimental::optional implementation however. So the assertion
165 * for T should be changed (or removed altogether) when the time comes, but the rest
166 * should however remain correct and unchanged.
167 */
168 static_assert( !std::is_move_constructible<T>(), "" );
169 static_assert( std::is_move_constructible<O>(), "" );
170 { O o; auto moved_to = std::move(o); }
171 static_assert( std::is_move_assignable<O>(), "" );
172 { O o, p; p = std::move(o); }
173 }
174
175 {
176 using T = no_move_assignment;
177 using O = std::experimental::optional<T>;
178 static_assert( std::is_same<O::value_type, T>(), "" );
179 static_assert( std::is_default_constructible<O>(), "" );
180 { O o; }
181 static_assert( std::is_copy_constructible<O>(), "" );
182 { O o; auto copy = o; }
183 static_assert( std::is_copy_assignable<O>(), "" );
184 { O o, p; p = o; }
185 static_assert( std::is_move_constructible<O>(), "" );
186 { O o; auto moved_to = std::move(o); }
187 /*
188 * Paragraph 23 of same leads to a similar situation but with respect to move
189 * assignment.
190 */
191 static_assert( !std::is_move_assignable<T>(), "" );
192 static_assert( std::is_move_assignable<O>(), "" );
193 { O o, p; p = std::move(o); }
194 }
195
196 {
197 using T = no_move;
198 using O = std::experimental::optional<T>;
199 static_assert( std::is_same<O::value_type, T>(), "" );
200 static_assert( std::is_default_constructible<O>(), "" );
201 { O o; }
202 static_assert( std::is_copy_constructible<O>(), "" );
203 { O o; auto copy = o; }
204 static_assert( std::is_copy_assignable<O>(), "" );
205 { O o, p; p = o; }
206 static_assert( std::is_move_constructible<O>(), "" );
207 { O o; auto moved_to = std::move(o); }
208 static_assert( std::is_move_assignable<O>(), "" );
209 { O o, p; p = std::move(o); }
210 }
211
212 {
213 using T = only_destructible;
214 using O = std::experimental::optional<T>;
215 static_assert( std::is_same<O::value_type, T>(), "" );
216 static_assert( std::is_default_constructible<O>(), "" );
217 { O o; }
218 static_assert( !std::is_copy_constructible<O>(), "" );
219 static_assert( !std::is_copy_assignable<O>(), "" );
220 static_assert( !std::is_move_constructible<O>(), "" );
221 static_assert( !std::is_move_assignable<O>(), "" );
222 }
223
224 {
225 /*
226 * Should not complain about 'invalid' specializations as long as
227 * they're not instantiated.
228 */
229 using A = std::experimental::optional<int&>;
230 using B = std::experimental::optional<int&&>;
231 using C1 = std::experimental::optional<std::experimental::in_place_t>;
232 using C2 = std::experimental::optional<std::experimental::in_place_t const>;
233 using C3 = std::experimental::optional<std::experimental::in_place_t volatile>;
234 using C4 = std::experimental::optional<std::experimental::in_place_t const volatile>;
235 using D1 = std::experimental::optional<std::experimental::nullopt_t>;
236 using D2 = std::experimental::optional<std::experimental::nullopt_t const>;
237 using D3 = std::experimental::optional<std::experimental::nullopt_t volatile>;
238 using D4 = std::experimental::optional<std::experimental::nullopt_t const volatile>;
239
240 using X = std::tuple<A, B, C1, C2, C3, C4, D1, D2, D3, D4>;
241 }
242
243 {
244 std::experimental::optional<const int> o { 42 };
245 static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
246 VERIFY( o );
247 VERIFY( *o == 42 );
248 }
249
250 {
251 constexpr std::experimental::optional<const int> o { 33 };
252 static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
253 static_assert( o, "" );
254 static_assert( *o == 33, "" );
255 }
256}