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 
35 namespace 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   */
49 template<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   */
73 template<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   */
81 template<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   */
93 template<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 
107 template<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 
125 template<typename _Tag>
126   struct _Enable_destructor<false, _Tag>
127   { ~_Enable_destructor() noexcept = delete; };
128 
129 template<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 
141 template<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 
153 template<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 
165 template<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 
177 template<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 
189 template<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 
201 template<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 
213 template<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 
225 template<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 
237 template<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 
249 template<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 
261 template<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 
273 template<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 
285 template<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 
297 template<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