1// <bits/enable_special_members.h> -*- C++ -*-
2
3// Copyright (C) 2013-2018 Free Software Foundation, Inc.
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
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/enable_special_members.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly.
28 */
29
30#ifndef _ENABLE_SPECIAL_MEMBERS_H
31#define _ENABLE_SPECIAL_MEMBERS_H 1
32
33#pragma GCC system_header
34
35namespace std _GLIBCXX_VISIBILITY(default)
36{
37_GLIBCXX_BEGIN_NAMESPACE_VERSION
38
39 struct _Enable_default_constructor_tag
40 {
41 explicit constexpr _Enable_default_constructor_tag() = default;
42 };
43
44/**
45 * @brief A mixin helper to conditionally enable or disable the default
46 * constructor.
47 * @sa _Enable_special_members
48 */
49template<bool _Switch, typename _Tag = void>
50 struct _Enable_default_constructor
51 {
52 constexpr _Enable_default_constructor() noexcept = default;
53 constexpr _Enable_default_constructor(_Enable_default_constructor const&)
54 noexcept = default;
55 constexpr _Enable_default_constructor(_Enable_default_constructor&&)
56 noexcept = default;
57 _Enable_default_constructor&
58 operator=(_Enable_default_constructor const&) noexcept = default;
59 _Enable_default_constructor&
60 operator=(_Enable_default_constructor&&) noexcept = default;
61
62 // Can be used in other ctors.
63 constexpr explicit
64 _Enable_default_constructor(_Enable_default_constructor_tag) { }
65 };
66
67
68/**
69 * @brief A mixin helper to conditionally enable or disable the default
70 * destructor.
71 * @sa _Enable_special_members
72 */
73template<bool _Switch, typename _Tag = void>
74 struct _Enable_destructor { };
75
76/**
77 * @brief A mixin helper to conditionally enable or disable the copy/move
78 * special members.
79 * @sa _Enable_special_members
80 */
81template<bool _Copy, bool _CopyAssignment,
82 bool _Move, bool _MoveAssignment,
83 typename _Tag = void>
84 struct _Enable_copy_move { };
85
86/**
87 * @brief A mixin helper to conditionally enable or disable the special
88 * members.
89 *
90 * The @c _Tag type parameter is to make mixin bases unique and thus avoid
91 * ambiguities.
92 */
93template<bool _Default, bool _Destructor,
94 bool _Copy, bool _CopyAssignment,
95 bool _Move, bool _MoveAssignment,
96 typename _Tag = void>
97 struct _Enable_special_members
98 : private _Enable_default_constructor<_Default, _Tag>,
99 private _Enable_destructor<_Destructor, _Tag>,
100 private _Enable_copy_move<_Copy, _CopyAssignment,
101 _Move, _MoveAssignment,
102 _Tag>
103 { };
104
105// Boilerplate follows.
106
107template<typename _Tag>
108 struct _Enable_default_constructor<false, _Tag>
109 {
110 constexpr _Enable_default_constructor() noexcept = delete;
111 constexpr _Enable_default_constructor(_Enable_default_constructor const&)
112 noexcept = default;
113 constexpr _Enable_default_constructor(_Enable_default_constructor&&)
114 noexcept = default;
115 _Enable_default_constructor&
116 operator=(_Enable_default_constructor const&) noexcept = default;
117 _Enable_default_constructor&
118 operator=(_Enable_default_constructor&&) noexcept = default;
119
120 // Can be used in other ctors.
121 constexpr explicit
122 _Enable_default_constructor(_Enable_default_constructor_tag) { }
123 };
124
125template<typename _Tag>
126 struct _Enable_destructor<false, _Tag>
127 { ~_Enable_destructor() noexcept = delete; };
128
129template<typename _Tag>
130 struct _Enable_copy_move<false, true, true, true, _Tag>
131 {
132 constexpr _Enable_copy_move() noexcept = default;
133 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
134 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
135 _Enable_copy_move&
136 operator=(_Enable_copy_move const&) noexcept = default;
137 _Enable_copy_move&
138 operator=(_Enable_copy_move&&) noexcept = default;
139 };
140
141template<typename _Tag>
142 struct _Enable_copy_move<true, false, true, true, _Tag>
143 {
144 constexpr _Enable_copy_move() noexcept = default;
145 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
146 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
147 _Enable_copy_move&
148 operator=(_Enable_copy_move const&) noexcept = delete;
149 _Enable_copy_move&
150 operator=(_Enable_copy_move&&) noexcept = default;
151 };
152
153template<typename _Tag>
154 struct _Enable_copy_move<false, false, true, true, _Tag>
155 {
156 constexpr _Enable_copy_move() noexcept = default;
157 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
158 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
159 _Enable_copy_move&
160 operator=(_Enable_copy_move const&) noexcept = delete;
161 _Enable_copy_move&
162 operator=(_Enable_copy_move&&) noexcept = default;
163 };
164
165template<typename _Tag>
166 struct _Enable_copy_move<true, true, false, true, _Tag>
167 {
168 constexpr _Enable_copy_move() noexcept = default;
169 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
170 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
171 _Enable_copy_move&
172 operator=(_Enable_copy_move const&) noexcept = default;
173 _Enable_copy_move&
174 operator=(_Enable_copy_move&&) noexcept = default;
175 };
176
177template<typename _Tag>
178 struct _Enable_copy_move<false, true, false, true, _Tag>
179 {
180 constexpr _Enable_copy_move() noexcept = default;
181 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
182 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
183 _Enable_copy_move&
184 operator=(_Enable_copy_move const&) noexcept = default;
185 _Enable_copy_move&
186 operator=(_Enable_copy_move&&) noexcept = default;
187 };
188
189template<typename _Tag>
190 struct _Enable_copy_move<true, false, false, true, _Tag>
191 {
192 constexpr _Enable_copy_move() noexcept = default;
193 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
194 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
195 _Enable_copy_move&
196 operator=(_Enable_copy_move const&) noexcept = delete;
197 _Enable_copy_move&
198 operator=(_Enable_copy_move&&) noexcept = default;
199 };
200
201template<typename _Tag>
202 struct _Enable_copy_move<false, false, false, true, _Tag>
203 {
204 constexpr _Enable_copy_move() noexcept = default;
205 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
206 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
207 _Enable_copy_move&
208 operator=(_Enable_copy_move const&) noexcept = delete;
209 _Enable_copy_move&
210 operator=(_Enable_copy_move&&) noexcept = default;
211 };
212
213template<typename _Tag>
214 struct _Enable_copy_move<true, true, true, false, _Tag>
215 {
216 constexpr _Enable_copy_move() noexcept = default;
217 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
218 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
219 _Enable_copy_move&
220 operator=(_Enable_copy_move const&) noexcept = default;
221 _Enable_copy_move&
222 operator=(_Enable_copy_move&&) noexcept = delete;
223 };
224
225template<typename _Tag>
226 struct _Enable_copy_move<false, true, true, false, _Tag>
227 {
228 constexpr _Enable_copy_move() noexcept = default;
229 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
230 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
231 _Enable_copy_move&
232 operator=(_Enable_copy_move const&) noexcept = default;
233 _Enable_copy_move&
234 operator=(_Enable_copy_move&&) noexcept = delete;
235 };
236
237template<typename _Tag>
238 struct _Enable_copy_move<true, false, true, false, _Tag>
239 {
240 constexpr _Enable_copy_move() noexcept = default;
241 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
242 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
243 _Enable_copy_move&
244 operator=(_Enable_copy_move const&) noexcept = delete;
245 _Enable_copy_move&
246 operator=(_Enable_copy_move&&) noexcept = delete;
247 };
248
249template<typename _Tag>
250 struct _Enable_copy_move<false, false, true, false, _Tag>
251 {
252 constexpr _Enable_copy_move() noexcept = default;
253 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
254 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
255 _Enable_copy_move&
256 operator=(_Enable_copy_move const&) noexcept = delete;
257 _Enable_copy_move&
258 operator=(_Enable_copy_move&&) noexcept = delete;
259 };
260
261template<typename _Tag>
262 struct _Enable_copy_move<true, true, false, false, _Tag>
263 {
264 constexpr _Enable_copy_move() noexcept = default;
265 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
266 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
267 _Enable_copy_move&
268 operator=(_Enable_copy_move const&) noexcept = default;
269 _Enable_copy_move&
270 operator=(_Enable_copy_move&&) noexcept = delete;
271 };
272
273template<typename _Tag>
274 struct _Enable_copy_move<false, true, false, false, _Tag>
275 {
276 constexpr _Enable_copy_move() noexcept = default;
277 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
278 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
279 _Enable_copy_move&
280 operator=(_Enable_copy_move const&) noexcept = default;
281 _Enable_copy_move&
282 operator=(_Enable_copy_move&&) noexcept = delete;
283 };
284
285template<typename _Tag>
286 struct _Enable_copy_move<true, false, false, false, _Tag>
287 {
288 constexpr _Enable_copy_move() noexcept = default;
289 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
290 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
291 _Enable_copy_move&
292 operator=(_Enable_copy_move const&) noexcept = delete;
293 _Enable_copy_move&
294 operator=(_Enable_copy_move&&) noexcept = delete;
295 };
296
297template<typename _Tag>
298 struct _Enable_copy_move<false, false, false, false, _Tag>
299 {
300 constexpr _Enable_copy_move() noexcept = default;
301 constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
302 constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
303 _Enable_copy_move&
304 operator=(_Enable_copy_move const&) noexcept = delete;
305 _Enable_copy_move&
306 operator=(_Enable_copy_move&&) noexcept = delete;
307 };
308
309_GLIBCXX_END_NAMESPACE_VERSION
310} // namespace std
311
312#endif // _ENABLE_SPECIAL_MEMBERS_H
313