]>
Commit | Line | Data |
---|---|---|
493bc460 PC |
1 | // TR1 type_traits -*- C++ -*- |
2 | ||
464b277b | 3 | // Copyright (C) 2004, 2005 Free Software Foundation, Inc. |
493bc460 PC |
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 2, 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 | // You should have received a copy of the GNU General Public License along | |
17 | // with this library; see the file COPYING. If not, write to the Free | |
83f51799 | 18 | // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
493bc460 PC |
19 | // USA. |
20 | ||
909a9d44 PC |
21 | // As a special exception, you may use this file as part of a free software |
22 | // library without restriction. Specifically, if other files instantiate | |
23 | // templates or use macros or inline functions from this file, or you compile | |
24 | // this file and link it with other files to produce an executable, this | |
25 | // file does not by itself cause the resulting executable to be covered by | |
26 | // the GNU General Public License. This exception does not however | |
27 | // invalidate any other reasons why the executable file might be covered by | |
28 | // the GNU General Public License. | |
29 | ||
493bc460 PC |
30 | /** @file |
31 | * This is a TR1 C++ Library header. | |
32 | */ | |
33 | ||
e21cb773 PC |
34 | #ifndef _TYPE_TRAITS |
35 | #define _TYPE_TRAITS 1 | |
493bc460 PC |
36 | |
37 | #include <bits/c++config.h> | |
821c5063 | 38 | #include <tr1/type_traits_fwd.h> |
493bc460 | 39 | |
cacd0a2c | 40 | // namespace std::tr1 |
493bc460 PC |
41 | namespace std |
42 | { | |
43 | namespace tr1 | |
44 | { | |
f4e4284d | 45 | // For use in __conv_helper, is_abstract and elsewhere. |
cacd0a2c PC |
46 | struct __sfinae_types |
47 | { | |
48 | typedef char __one; | |
49 | typedef struct { char __arr[2]; } __two; | |
50 | }; | |
e192ab01 | 51 | |
f8023b78 PC |
52 | template<typename _From, typename _To> |
53 | struct __conv_helper | |
54 | : public __sfinae_types | |
55 | { | |
56 | private: | |
57 | static __one __test(_To); | |
58 | static __two __test(...); | |
59 | static _From __makeFrom(); | |
60 | ||
61 | public: | |
62 | static const bool __value = sizeof(__test(__makeFrom())) == 1; | |
63 | }; | |
64 | ||
51687431 PC |
65 | #define _DEFINE_SPEC_BODY(_Value) \ |
66 | : public integral_constant<bool, _Value> { }; | |
67 | ||
68 | #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \ | |
69 | template<> \ | |
70 | struct _Spec \ | |
71 | _DEFINE_SPEC_BODY(_Value) | |
72 | ||
73 | #define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \ | |
74 | template<typename _Tp> \ | |
75 | struct _Spec \ | |
76 | _DEFINE_SPEC_BODY(_Value) | |
e192ab01 | 77 | |
51687431 PC |
78 | #define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \ |
79 | template<typename _Tp, typename _Cp> \ | |
80 | struct _Spec \ | |
81 | _DEFINE_SPEC_BODY(_Value) | |
186e6683 | 82 | |
51687431 PC |
83 | #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ |
84 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \ | |
85 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \ | |
86 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \ | |
87 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value) | |
e192ab01 | 88 | |
cacd0a2c PC |
89 | /// @brief helper classes [4.3]. |
90 | template<typename _Tp, _Tp __v> | |
91 | struct integral_constant | |
92 | { | |
93 | static const _Tp value = __v; | |
94 | typedef _Tp value_type; | |
95 | typedef integral_constant<_Tp, __v> type; | |
96 | }; | |
97 | typedef integral_constant<bool, true> true_type; | |
98 | typedef integral_constant<bool, false> false_type; | |
99 | ||
493bc460 PC |
100 | /// @brief primary type categories [4.5.1]. |
101 | template<typename> | |
102 | struct is_void | |
103 | : public false_type { }; | |
51687431 | 104 | _DEFINE_SPEC(0, is_void, void, true) |
493bc460 PC |
105 | |
106 | template<typename> | |
107 | struct is_integral | |
108 | : public false_type { }; | |
51687431 PC |
109 | _DEFINE_SPEC(0, is_integral, bool, true) |
110 | _DEFINE_SPEC(0, is_integral, char, true) | |
111 | _DEFINE_SPEC(0, is_integral, signed char, true) | |
112 | _DEFINE_SPEC(0, is_integral, unsigned char, true) | |
493bc460 | 113 | #ifdef _GLIBCXX_USE_WCHAR_T |
51687431 | 114 | _DEFINE_SPEC(0, is_integral, wchar_t, true) |
493bc460 | 115 | #endif |
51687431 PC |
116 | _DEFINE_SPEC(0, is_integral, short, true) |
117 | _DEFINE_SPEC(0, is_integral, unsigned short, true) | |
118 | _DEFINE_SPEC(0, is_integral, int, true) | |
119 | _DEFINE_SPEC(0, is_integral, unsigned int, true) | |
120 | _DEFINE_SPEC(0, is_integral, long, true) | |
121 | _DEFINE_SPEC(0, is_integral, unsigned long, true) | |
122 | _DEFINE_SPEC(0, is_integral, long long, true) | |
123 | _DEFINE_SPEC(0, is_integral, unsigned long long, true) | |
493bc460 PC |
124 | |
125 | template<typename> | |
126 | struct is_floating_point | |
127 | : public false_type { }; | |
51687431 PC |
128 | _DEFINE_SPEC(0, is_floating_point, float, true) |
129 | _DEFINE_SPEC(0, is_floating_point, double, true) | |
130 | _DEFINE_SPEC(0, is_floating_point, long double, true) | |
493bc460 PC |
131 | |
132 | template<typename> | |
133 | struct is_array | |
134 | : public false_type { }; | |
135 | ||
136 | template<typename _Tp, std::size_t _Size> | |
137 | struct is_array<_Tp[_Size]> | |
138 | : public true_type { }; | |
139 | ||
140 | template<typename _Tp> | |
141 | struct is_array<_Tp[]> | |
142 | : public true_type { }; | |
186e6683 | 143 | |
e192ab01 PC |
144 | template<typename> |
145 | struct is_pointer | |
146 | : public false_type { }; | |
51687431 | 147 | _DEFINE_SPEC(1, is_pointer, _Tp*, true) |
e192ab01 | 148 | |
e21cb773 PC |
149 | template<typename> |
150 | struct is_reference | |
151 | : public false_type { }; | |
152 | ||
493bc460 | 153 | template<typename _Tp> |
e21cb773 PC |
154 | struct is_reference<_Tp&> |
155 | : public true_type { }; | |
186e6683 | 156 | |
186e6683 PC |
157 | template<typename> |
158 | struct is_member_object_pointer | |
159 | : public false_type { }; | |
51687431 PC |
160 | _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*, |
161 | !is_function<_Tp>::value) | |
186e6683 PC |
162 | |
163 | template<typename> | |
164 | struct is_member_function_pointer | |
11996a3c PC |
165 | : public false_type { }; |
166 | _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*, | |
167 | is_function<_Tp>::value) | |
186e6683 | 168 | |
cacd0a2c | 169 | template<typename _Tp> |
a9e7ba81 | 170 | struct is_enum |
9e38f702 PC |
171 | : public integral_constant<bool, !(is_fundamental<_Tp>::value |
172 | || is_array<_Tp>::value | |
173 | || is_pointer<_Tp>::value | |
174 | || is_reference<_Tp>::value | |
175 | || is_member_pointer<_Tp>::value | |
176 | || is_function<_Tp>::value | |
177 | || __is_union_or_class<_Tp>::value)> | |
178 | { }; | |
179 | ||
180 | template<typename> | |
181 | struct is_union { }; | |
182 | ||
183 | template<typename> | |
184 | struct is_class { }; | |
a9e7ba81 | 185 | |
c150a271 PC |
186 | template<typename _Tp, bool = (is_void<_Tp>::value |
187 | || is_reference<_Tp>::value)> | |
7536f1ed PC |
188 | struct __is_function_helper |
189 | { | |
190 | static const bool __value = (__conv_helper<typename | |
191 | add_reference<_Tp>::type, typename | |
192 | add_pointer<_Tp>::type>::__value); | |
193 | }; | |
194 | ||
195 | template<typename _Tp> | |
196 | struct __is_function_helper<_Tp, true> | |
197 | { static const bool __value = false; }; | |
198 | ||
493bc460 | 199 | template<typename _Tp> |
cacd0a2c | 200 | struct is_function |
7536f1ed | 201 | : public integral_constant<bool, __is_function_helper<_Tp>::__value> |
f8023b78 | 202 | { }; |
493bc460 | 203 | |
493bc460 PC |
204 | /// @brief composite type traits [4.5.2]. |
205 | template<typename _Tp> | |
206 | struct is_arithmetic | |
207 | : public integral_constant<bool, (is_integral<_Tp>::value | |
208 | || is_floating_point<_Tp>::value)> | |
209 | { }; | |
210 | ||
211 | template<typename _Tp> | |
212 | struct is_fundamental | |
213 | : public integral_constant<bool, (is_arithmetic<_Tp>::value | |
214 | || is_void<_Tp>::value)> | |
215 | { }; | |
216 | ||
217 | template<typename _Tp> | |
218 | struct is_object | |
219 | : public integral_constant<bool, !(is_function<_Tp>::value | |
220 | || is_reference<_Tp>::value | |
221 | || is_void<_Tp>::value)> | |
222 | { }; | |
223 | ||
493bc460 PC |
224 | template<typename _Tp> |
225 | struct is_scalar | |
226 | : public integral_constant<bool, (is_arithmetic<_Tp>::value | |
227 | || is_enum<_Tp>::value | |
228 | || is_pointer<_Tp>::value | |
229 | || is_member_pointer<_Tp>::value)> | |
230 | { }; | |
821c5063 | 231 | |
493bc460 PC |
232 | template<typename _Tp> |
233 | struct is_compound | |
234 | : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; | |
821c5063 PC |
235 | |
236 | template<typename _Tp> | |
237 | struct is_member_pointer | |
238 | : public integral_constant<bool, | |
239 | (is_member_object_pointer<_Tp>::value | |
240 | || is_member_function_pointer<_Tp>::value)> | |
241 | { }; | |
9e38f702 PC |
242 | |
243 | template<typename _Tp> | |
244 | struct __is_union_or_class_helper | |
245 | : public __sfinae_types | |
246 | { | |
247 | private: | |
248 | template<typename _Up> | |
249 | static __one __test(int _Up::*); | |
250 | template<typename> | |
251 | static __two __test(...); | |
252 | ||
253 | public: | |
254 | static const bool __value = sizeof(__test<_Tp>(0)) == 1; | |
255 | }; | |
256 | ||
257 | // Extension. | |
258 | template<typename _Tp> | |
259 | struct __is_union_or_class | |
260 | : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value> | |
261 | { }; | |
821c5063 | 262 | |
493bc460 | 263 | /// @brief type properties [4.5.3]. |
0f910b4f PC |
264 | template<typename> |
265 | struct is_const | |
266 | : public false_type { }; | |
267 | ||
493bc460 | 268 | template<typename _Tp> |
0f910b4f PC |
269 | struct is_const<_Tp const> |
270 | : public true_type { }; | |
493bc460 | 271 | |
0f910b4f PC |
272 | template<typename> |
273 | struct is_volatile | |
274 | : public false_type { }; | |
275 | ||
493bc460 | 276 | template<typename _Tp> |
0f910b4f PC |
277 | struct is_volatile<_Tp volatile> |
278 | : public true_type { }; | |
493bc460 | 279 | |
1933b74f PC |
280 | template<typename _Tp> |
281 | struct is_pod | |
282 | : public integral_constant<bool, (is_void<_Tp>::value | |
283 | || is_scalar<typename | |
284 | remove_all_extents<_Tp>::type>::value)> | |
285 | { }; | |
286 | ||
9e38f702 | 287 | // N.B. Without compiler support we cannot tell union from class types, |
442dca70 | 288 | // and is_empty and is_polymorphic don't work at all with the former. |
9e38f702 | 289 | template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> |
91e390fe | 290 | struct __is_empty_helper |
9e38f702 PC |
291 | { |
292 | private: | |
293 | template<typename> | |
442dca70 | 294 | struct __first { }; |
9e38f702 | 295 | template<typename _Up> |
442dca70 | 296 | struct __second |
9e38f702 PC |
297 | : public _Up { }; |
298 | ||
299 | public: | |
442dca70 | 300 | static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); |
9e38f702 | 301 | }; |
91e390fe PC |
302 | |
303 | template<typename _Tp> | |
304 | struct __is_empty_helper<_Tp, true> | |
305 | { static const bool __value = false; }; | |
306 | ||
307 | template<typename _Tp> | |
308 | struct is_empty | |
309 | : public integral_constant<bool, __is_empty_helper<_Tp>::__value> | |
310 | { }; | |
311 | ||
442dca70 PC |
312 | template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> |
313 | struct __is_polymorphic_helper | |
314 | { | |
315 | private: | |
316 | template<typename _Up> | |
317 | struct __first | |
318 | : public _Up { }; | |
319 | template<typename _Up> | |
320 | struct __second | |
321 | : public _Up | |
cff001b2 PC |
322 | { |
323 | virtual void __dummy(); | |
77633f4c | 324 | virtual ~__second() throw(); |
cff001b2 PC |
325 | }; |
326 | ||
442dca70 PC |
327 | public: |
328 | static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); | |
329 | }; | |
330 | ||
331 | template<typename _Tp> | |
332 | struct __is_polymorphic_helper<_Tp, true> | |
333 | { static const bool __value = false; }; | |
334 | ||
335 | template<typename _Tp> | |
336 | struct is_polymorphic | |
337 | : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value> | |
338 | { }; | |
339 | ||
f8023b78 | 340 | // Exploit the resolution DR core/337. |
91e390fe | 341 | template<typename _Tp, bool = !is_object<_Tp>::value> |
f8023b78 PC |
342 | struct __is_abstract_helper |
343 | : public __sfinae_types | |
344 | { | |
345 | private: | |
346 | template<typename> | |
347 | static __one __test(...); | |
348 | template<typename _Up> | |
349 | static __two __test(_Up(*)[1]); | |
350 | ||
351 | public: | |
352 | static const bool __value = sizeof(__test<_Tp>(0)) == 1; | |
353 | }; | |
354 | ||
355 | template<typename _Tp> | |
356 | struct __is_abstract_helper<_Tp, true> | |
357 | { static const bool __value = false; }; | |
358 | ||
359 | template<typename _Tp> | |
360 | struct is_abstract | |
361 | : public integral_constant<bool, __is_abstract_helper<_Tp>::__value> { }; | |
362 | ||
1933b74f PC |
363 | template<typename _Tp> |
364 | struct has_trivial_constructor | |
365 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
366 | ||
36651afe PC |
367 | template<typename _Tp> |
368 | struct has_trivial_copy | |
4e5362a2 | 369 | : public integral_constant<bool, is_pod<_Tp>::value> { }; |
36651afe PC |
370 | |
371 | template<typename _Tp> | |
372 | struct has_trivial_assign | |
4e5362a2 | 373 | : public integral_constant<bool, is_pod<_Tp>::value> { }; |
36651afe | 374 | |
1933b74f PC |
375 | template<typename _Tp> |
376 | struct has_trivial_destructor | |
377 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
378 | ||
5249b4b0 PC |
379 | template<typename _Tp> |
380 | struct has_nothrow_constructor | |
381 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
382 | ||
36651afe PC |
383 | template<typename _Tp> |
384 | struct has_nothrow_copy | |
4e5362a2 | 385 | : public integral_constant<bool, is_pod<_Tp>::value> { }; |
36651afe PC |
386 | |
387 | template<typename _Tp> | |
388 | struct has_nothrow_assign | |
4e5362a2 | 389 | : public integral_constant<bool, is_pod<_Tp>::value> { }; |
36651afe | 390 | |
821c5063 | 391 | template<typename> |
493bc460 PC |
392 | struct has_virtual_destructor |
393 | : public false_type { }; | |
464b277b | 394 | |
e930780c PC |
395 | template<typename> |
396 | struct is_signed | |
397 | : public false_type { }; | |
398 | _DEFINE_SPEC(0, is_signed, signed char, true) | |
399 | _DEFINE_SPEC(0, is_signed, short, true) | |
400 | _DEFINE_SPEC(0, is_signed, int, true) | |
401 | _DEFINE_SPEC(0, is_signed, long, true) | |
402 | _DEFINE_SPEC(0, is_signed, long long, true) | |
403 | ||
404 | template<typename> | |
405 | struct is_unsigned | |
406 | : public false_type { }; | |
407 | _DEFINE_SPEC(0, is_unsigned, unsigned char, true) | |
408 | _DEFINE_SPEC(0, is_unsigned, unsigned short, true) | |
409 | _DEFINE_SPEC(0, is_unsigned, unsigned int, true) | |
410 | _DEFINE_SPEC(0, is_unsigned, unsigned long, true) | |
411 | _DEFINE_SPEC(0, is_unsigned, unsigned long long, true) | |
412 | ||
464b277b PC |
413 | template<typename _Tp> |
414 | struct alignment_of | |
415 | : public integral_constant<std::size_t, __alignof__(_Tp)> { }; | |
493bc460 | 416 | |
db5ff236 PC |
417 | template<typename> |
418 | struct rank | |
419 | : public integral_constant<std::size_t, 0> { }; | |
420 | ||
421 | template<typename _Tp, std::size_t _Size> | |
422 | struct rank<_Tp[_Size]> | |
423 | : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; | |
424 | ||
493bc460 | 425 | template<typename _Tp> |
db5ff236 PC |
426 | struct rank<_Tp[]> |
427 | : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; | |
493bc460 | 428 | |
821c5063 | 429 | template<typename, unsigned> |
973cb10b | 430 | struct extent |
273dfd21 | 431 | : public integral_constant<std::size_t, 0> { }; |
973cb10b PC |
432 | |
433 | template<typename _Tp, unsigned _Uint, std::size_t _Size> | |
434 | struct extent<_Tp[_Size], _Uint> | |
273dfd21 PC |
435 | : public integral_constant<std::size_t, |
436 | _Uint == 0 ? _Size : extent<_Tp, | |
437 | _Uint - 1>::value> | |
973cb10b PC |
438 | { }; |
439 | ||
440 | template<typename _Tp, unsigned _Uint> | |
441 | struct extent<_Tp[], _Uint> | |
273dfd21 PC |
442 | : public integral_constant<std::size_t, |
443 | _Uint == 0 ? 0 : extent<_Tp, | |
444 | _Uint - 1>::value> | |
973cb10b | 445 | { }; |
493bc460 PC |
446 | |
447 | /// @brief relationships between types [4.6]. | |
d63a0e22 PC |
448 | template<typename, typename> |
449 | struct is_same | |
450 | : public false_type { }; | |
451 | ||
452 | template<typename _Tp> | |
453 | struct is_same<_Tp, _Tp> | |
454 | : public true_type { }; | |
493bc460 | 455 | |
f4e4284d PC |
456 | // See Daveed Vandevoorde explanation in http://tinyurl.com/502f. |
457 | // Also see Rani Sharoni in http://tinyurl.com/6jvyq. | |
458 | template<typename _Base, typename _Derived, | |
459 | bool = (!__is_union_or_class<_Base>::value | |
460 | || !__is_union_or_class<_Derived>::value | |
461 | || is_same<_Base, _Derived>::value)> | |
462 | struct __is_base_of_helper | |
463 | : public __sfinae_types | |
464 | { | |
465 | private: | |
466 | typedef typename remove_cv<_Base>::type _NoCv_Base; | |
467 | typedef typename remove_cv<_Derived>::type _NoCv_Derived; | |
468 | ||
469 | template<typename _Up> | |
470 | static __one __test(_NoCv_Derived&, _Up); | |
471 | static __two __test(_NoCv_Base&, int); | |
472 | ||
473 | struct _Conv | |
474 | { | |
475 | operator _NoCv_Derived&(); | |
476 | operator _NoCv_Base&() const; | |
477 | }; | |
478 | ||
479 | public: | |
480 | static const bool __value = sizeof(__test(_Conv(), 0)) == 1; | |
481 | }; | |
482 | ||
483 | template<typename _Base, typename _Derived> | |
484 | struct __is_base_of_helper<_Base, _Derived, true> | |
485 | { static const bool __value = is_same<_Base, _Derived>::value; }; | |
486 | ||
487 | template<typename _Base, typename _Derived> | |
488 | struct is_base_of | |
489 | : public integral_constant<bool, | |
490 | __is_base_of_helper<_Base, _Derived>::__value> | |
491 | { }; | |
492 | ||
c150a271 PC |
493 | template<typename _Tp> |
494 | struct __is_int_or_cref | |
495 | { | |
496 | typedef typename remove_reference<_Tp>::type __rr_Tp; | |
497 | static const bool __value = (is_integral<_Tp>::value | |
498 | || (is_integral<__rr_Tp>::value | |
499 | && is_const<__rr_Tp>::value | |
500 | && !is_volatile<__rr_Tp>::value)); | |
501 | }; | |
502 | ||
503 | template<typename _From, typename _To, | |
152d9676 PC |
504 | bool = (is_void<_From>::value || is_void<_To>::value |
505 | || is_function<_To>::value || is_array<_To>::value | |
c150a271 PC |
506 | // This special case is here only to avoid warnings. |
507 | || (is_floating_point<typename | |
508 | remove_reference<_From>::type>::value | |
509 | && __is_int_or_cref<_To>::__value))> | |
510 | struct __is_convertible_helper | |
511 | { | |
512 | // "An imaginary lvalue of type From...". | |
513 | static const bool __value = (__conv_helper<typename | |
514 | add_reference<_From>::type, _To>::__value); | |
515 | }; | |
516 | ||
517 | template<typename _From, typename _To> | |
518 | struct __is_convertible_helper<_From, _To, true> | |
152d9676 PC |
519 | { static const bool __value = (is_void<_To>::value |
520 | || (__is_int_or_cref<_To>::__value | |
521 | && !is_void<_From>::value)); }; | |
c150a271 PC |
522 | |
523 | template<typename _From, typename _To> | |
524 | struct is_convertible | |
525 | : public integral_constant<bool, | |
526 | __is_convertible_helper<_From, _To>::__value> | |
527 | { }; | |
528 | ||
493bc460 PC |
529 | /// @brief const-volatile modifications [4.7.1]. |
530 | template<typename _Tp> | |
d5f60056 | 531 | struct remove_const |
e192ab01 | 532 | { typedef _Tp type; }; |
d5f60056 PC |
533 | |
534 | template<typename _Tp> | |
535 | struct remove_const<_Tp const> | |
e192ab01 | 536 | { typedef _Tp type; }; |
493bc460 PC |
537 | |
538 | template<typename _Tp> | |
d5f60056 | 539 | struct remove_volatile |
e192ab01 | 540 | { typedef _Tp type; }; |
d5f60056 PC |
541 | |
542 | template<typename _Tp> | |
543 | struct remove_volatile<_Tp volatile> | |
e192ab01 | 544 | { typedef _Tp type; }; |
493bc460 PC |
545 | |
546 | template<typename _Tp> | |
d5f60056 PC |
547 | struct remove_cv |
548 | { | |
549 | typedef typename | |
550 | remove_const<typename remove_volatile<_Tp>::type>::type type; | |
551 | }; | |
493bc460 PC |
552 | |
553 | template<typename _Tp> | |
a02def09 PC |
554 | struct add_const |
555 | { typedef _Tp const type; }; | |
493bc460 PC |
556 | |
557 | template<typename _Tp> | |
a02def09 PC |
558 | struct add_volatile |
559 | { typedef _Tp volatile type; }; | |
493bc460 PC |
560 | |
561 | template<typename _Tp> | |
a02def09 PC |
562 | struct add_cv |
563 | { | |
564 | typedef typename | |
565 | add_const<typename add_volatile<_Tp>::type>::type type; | |
566 | }; | |
493bc460 PC |
567 | |
568 | /// @brief reference modifications [4.7.2]. | |
569 | template<typename _Tp> | |
d63a0e22 | 570 | struct remove_reference |
e192ab01 | 571 | { typedef _Tp type; }; |
d63a0e22 PC |
572 | |
573 | template<typename _Tp> | |
574 | struct remove_reference<_Tp&> | |
e192ab01 | 575 | { typedef _Tp type; }; |
493bc460 PC |
576 | |
577 | template<typename _Tp> | |
d63a0e22 | 578 | struct add_reference |
e192ab01 | 579 | { typedef _Tp& type; }; |
d63a0e22 PC |
580 | |
581 | template<typename _Tp> | |
582 | struct add_reference<_Tp&> | |
e192ab01 | 583 | { typedef _Tp& type; }; |
493bc460 PC |
584 | |
585 | /// @brief array modififications [4.7.3]. | |
586 | template<typename _Tp> | |
366e6bd1 | 587 | struct remove_extent |
e192ab01 | 588 | { typedef _Tp type; }; |
366e6bd1 PC |
589 | |
590 | template<typename _Tp, std::size_t _Size> | |
591 | struct remove_extent<_Tp[_Size]> | |
e192ab01 | 592 | { typedef _Tp type; }; |
366e6bd1 PC |
593 | |
594 | template<typename _Tp> | |
595 | struct remove_extent<_Tp[]> | |
e192ab01 | 596 | { typedef _Tp type; }; |
366e6bd1 | 597 | |
493bc460 | 598 | template<typename _Tp> |
366e6bd1 | 599 | struct remove_all_extents |
e192ab01 | 600 | { typedef _Tp type; }; |
366e6bd1 PC |
601 | |
602 | template<typename _Tp, std::size_t _Size> | |
603 | struct remove_all_extents<_Tp[_Size]> | |
e192ab01 | 604 | { typedef typename remove_all_extents<_Tp>::type type; }; |
366e6bd1 PC |
605 | |
606 | template<typename _Tp> | |
607 | struct remove_all_extents<_Tp[]> | |
e192ab01 | 608 | { typedef typename remove_all_extents<_Tp>::type type; }; |
493bc460 PC |
609 | |
610 | /// @brief pointer modifications [4.7.4]. | |
51687431 PC |
611 | #undef _DEFINE_SPEC_BODY |
612 | #define _DEFINE_SPEC_BODY(_Value) \ | |
e192ab01 PC |
613 | { typedef _Tp type; }; |
614 | ||
493bc460 | 615 | template<typename _Tp> |
e192ab01 PC |
616 | struct remove_pointer |
617 | { typedef _Tp type; }; | |
51687431 | 618 | _DEFINE_SPEC(1, remove_pointer, _Tp*, false) |
493bc460 PC |
619 | |
620 | template<typename _Tp> | |
e192ab01 PC |
621 | struct add_pointer |
622 | { typedef typename remove_reference<_Tp>::type* type; }; | |
493bc460 PC |
623 | |
624 | /// @brief other transformations [4.8]. | |
464b277b PC |
625 | |
626 | // Due to c++/19163 and c++/17743, for the time being we cannot use | |
627 | // the correct, neat implementation :-( | |
628 | // | |
629 | // template<std::size_t _Len, std::size_t _Align> | |
630 | // struct aligned_storage | |
96144e13 | 631 | // { typedef char type[_Len] __attribute__((__aligned__(_Align))); } |
464b277b PC |
632 | // |
633 | // Temporary workaround, useful for Align up to 32: | |
634 | template<std::size_t, std::size_t> | |
635 | struct aligned_storage { }; | |
636 | ||
637 | template<std::size_t _Len> | |
638 | struct aligned_storage<_Len, 1> | |
639 | { | |
640 | union type | |
641 | { | |
642 | unsigned char __data[_Len]; | |
96144e13 | 643 | char __align __attribute__((__aligned__(1))); |
464b277b PC |
644 | }; |
645 | }; | |
646 | ||
647 | template<std::size_t _Len> | |
648 | struct aligned_storage<_Len, 2> | |
649 | { | |
650 | union type | |
651 | { | |
652 | unsigned char __data[_Len]; | |
96144e13 | 653 | char __align __attribute__((__aligned__(2))); |
464b277b PC |
654 | }; |
655 | }; | |
656 | ||
657 | template<std::size_t _Len> | |
658 | struct aligned_storage<_Len, 4> | |
659 | { | |
660 | union type | |
661 | { | |
662 | unsigned char __data[_Len]; | |
96144e13 | 663 | char __align __attribute__((__aligned__(4))); |
464b277b PC |
664 | }; |
665 | }; | |
666 | ||
667 | template<std::size_t _Len> | |
668 | struct aligned_storage<_Len, 8> | |
669 | { | |
670 | union type | |
671 | { | |
672 | unsigned char __data[_Len]; | |
96144e13 | 673 | char __align __attribute__((__aligned__(8))); |
464b277b PC |
674 | }; |
675 | }; | |
676 | ||
677 | template<std::size_t _Len> | |
678 | struct aligned_storage<_Len, 16> | |
679 | { | |
680 | union type | |
681 | { | |
682 | unsigned char __data[_Len]; | |
96144e13 | 683 | char __align __attribute__((__aligned__(16))); |
464b277b PC |
684 | }; |
685 | }; | |
686 | ||
687 | template<std::size_t _Len> | |
688 | struct aligned_storage<_Len, 32> | |
689 | { | |
690 | union type | |
691 | { | |
692 | unsigned char __data[_Len]; | |
96144e13 | 693 | char __align __attribute__((__aligned__(32))); |
464b277b PC |
694 | }; |
695 | }; | |
e192ab01 | 696 | |
186e6683 PC |
697 | #undef _DEFINE_SPEC_0_HELPER |
698 | #undef _DEFINE_SPEC_1_HELPER | |
699 | #undef _DEFINE_SPEC_2_HELPER | |
e2f5c678 | 700 | #undef _DEFINE_SPEC |
51687431 | 701 | #undef _DEFINE_SPEC_BODY |
e192ab01 | 702 | |
493bc460 PC |
703 | } |
704 | } | |
705 | ||
706 | #endif |