1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2007 Free Software Foundation, Inc.
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)
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.
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
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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.
30 /** @file tr1_impl/type_traits
31 * This is an internal header file, included by other library headers.
32 * You should not attempt to use it directly.
35 #include <tr1_impl/type_traitsfwd.h>
39 _GLIBCXX_BEGIN_NAMESPACE_TR1
41 // For use in __is_convertible_simple.
45 typedef struct { char __arr[2]; } __two;
48 #define _DEFINE_SPEC_BODY(_Value) \
49 : public integral_constant<bool, _Value> { };
51 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \
54 _DEFINE_SPEC_BODY(_Value)
56 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \
57 template<typename _Tp> \
59 _DEFINE_SPEC_BODY(_Value)
61 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \
62 template<typename _Tp, typename _Cp> \
64 _DEFINE_SPEC_BODY(_Value)
66 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
67 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \
68 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \
69 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \
70 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
72 /// @brief helper classes [4.3].
73 template<typename _Tp, _Tp __v>
74 struct integral_constant
76 static const _Tp value = __v;
77 typedef _Tp value_type;
78 typedef integral_constant<_Tp, __v> type;
80 typedef integral_constant<bool, true> true_type;
81 typedef integral_constant<bool, false> false_type;
83 template<typename _Tp, _Tp __v>
84 const _Tp integral_constant<_Tp, __v>::value;
86 /// @brief primary type categories [4.5.1].
89 : public false_type { };
90 _DEFINE_SPEC(0, is_void, void, true)
94 : public false_type { };
95 _DEFINE_SPEC(0, is_integral, bool, true)
96 _DEFINE_SPEC(0, is_integral, char, true)
97 _DEFINE_SPEC(0, is_integral, signed char, true)
98 _DEFINE_SPEC(0, is_integral, unsigned char, true)
99 #ifdef _GLIBCXX_USE_WCHAR_T
100 _DEFINE_SPEC(0, is_integral, wchar_t, true)
102 _DEFINE_SPEC(0, is_integral, short, true)
103 _DEFINE_SPEC(0, is_integral, unsigned short, true)
104 _DEFINE_SPEC(0, is_integral, int, true)
105 _DEFINE_SPEC(0, is_integral, unsigned int, true)
106 _DEFINE_SPEC(0, is_integral, long, true)
107 _DEFINE_SPEC(0, is_integral, unsigned long, true)
108 _DEFINE_SPEC(0, is_integral, long long, true)
109 _DEFINE_SPEC(0, is_integral, unsigned long long, true)
112 struct is_floating_point
113 : public false_type { };
114 _DEFINE_SPEC(0, is_floating_point, float, true)
115 _DEFINE_SPEC(0, is_floating_point, double, true)
116 _DEFINE_SPEC(0, is_floating_point, long double, true)
120 : public false_type { };
122 template<typename _Tp, std::size_t _Size>
123 struct is_array<_Tp[_Size]>
124 : public true_type { };
126 template<typename _Tp>
127 struct is_array<_Tp[]>
128 : public true_type { };
132 : public false_type { };
133 _DEFINE_SPEC(1, is_pointer, _Tp*, true)
137 : public false_type { };
139 template<typename _Tp>
140 struct is_reference<_Tp&>
141 : public true_type { };
144 struct is_member_object_pointer
145 : public false_type { };
146 _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
147 !is_function<_Tp>::value)
150 struct is_member_function_pointer
151 : public false_type { };
152 _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
153 is_function<_Tp>::value)
155 template<typename _Tp>
157 : public integral_constant<bool, __is_enum(_Tp)>
160 template<typename _Tp>
162 : public integral_constant<bool, __is_union(_Tp)>
165 template<typename _Tp>
167 : public integral_constant<bool, __is_class(_Tp)>
171 struct __is_function_helper
172 : public false_type { };
174 template<typename _Res, typename... _ArgTypes>
175 struct __is_function_helper<_Res(_ArgTypes...)>
176 : public true_type { };
178 template<typename _Res, typename... _ArgTypes>
179 struct __is_function_helper<_Res(_ArgTypes......)>
180 : public true_type { };
182 template<typename _Tp>
184 : public integral_constant<bool, (__is_function_helper<typename
185 remove_cv<_Tp>::type>::value)>
188 /// @brief composite type traits [4.5.2].
189 template<typename _Tp>
191 : public integral_constant<bool, (is_integral<_Tp>::value
192 || is_floating_point<_Tp>::value)>
195 template<typename _Tp>
196 struct is_fundamental
197 : public integral_constant<bool, (is_arithmetic<_Tp>::value
198 || is_void<_Tp>::value)>
201 template<typename _Tp>
203 : public integral_constant<bool, !(is_function<_Tp>::value
204 || is_reference<_Tp>::value
205 || is_void<_Tp>::value)>
208 template<typename _Tp>
210 : public integral_constant<bool, (is_arithmetic<_Tp>::value
211 || is_enum<_Tp>::value
212 || is_pointer<_Tp>::value
213 || is_member_pointer<_Tp>::value)>
216 template<typename _Tp>
218 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
220 template<typename _Tp>
221 struct is_member_pointer
222 : public integral_constant<bool,
223 (is_member_object_pointer<_Tp>::value
224 || is_member_function_pointer<_Tp>::value)>
227 /// @brief type properties [4.5.3].
230 : public false_type { };
232 template<typename _Tp>
233 struct is_const<_Tp const>
234 : public true_type { };
238 : public false_type { };
240 template<typename _Tp>
241 struct is_volatile<_Tp volatile>
242 : public true_type { };
244 template<typename _Tp>
246 : public integral_constant<bool, __is_empty(_Tp)>
249 template<typename _Tp>
250 struct is_polymorphic
251 : public integral_constant<bool, __is_polymorphic(_Tp)>
254 template<typename _Tp>
256 : public integral_constant<bool, __is_abstract(_Tp)>
259 template<typename _Tp>
260 struct has_virtual_destructor
261 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
264 template<typename _Tp>
266 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
270 : public integral_constant<std::size_t, 0> { };
272 template<typename _Tp, std::size_t _Size>
273 struct rank<_Tp[_Size]>
274 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
276 template<typename _Tp>
278 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
280 template<typename, unsigned>
282 : public integral_constant<std::size_t, 0> { };
284 template<typename _Tp, unsigned _Uint, std::size_t _Size>
285 struct extent<_Tp[_Size], _Uint>
286 : public integral_constant<std::size_t,
287 _Uint == 0 ? _Size : extent<_Tp,
291 template<typename _Tp, unsigned _Uint>
292 struct extent<_Tp[], _Uint>
293 : public integral_constant<std::size_t,
294 _Uint == 0 ? 0 : extent<_Tp,
298 /// @brief relationships between types [4.6].
299 template<typename, typename>
301 : public false_type { };
303 template<typename _Tp>
304 struct is_same<_Tp, _Tp>
305 : public true_type { };
307 /// @brief const-volatile modifications [4.7.1].
308 template<typename _Tp>
310 { typedef _Tp type; };
312 template<typename _Tp>
313 struct remove_const<_Tp const>
314 { typedef _Tp type; };
316 template<typename _Tp>
317 struct remove_volatile
318 { typedef _Tp type; };
320 template<typename _Tp>
321 struct remove_volatile<_Tp volatile>
322 { typedef _Tp type; };
324 template<typename _Tp>
328 remove_const<typename remove_volatile<_Tp>::type>::type type;
331 template<typename _Tp>
333 { typedef _Tp const type; };
335 template<typename _Tp>
337 { typedef _Tp volatile type; };
339 template<typename _Tp>
343 add_const<typename add_volatile<_Tp>::type>::type type;
346 /// @brief reference modifications [4.7.2].
347 template<typename _Tp>
348 struct remove_reference
349 { typedef _Tp type; };
351 template<typename _Tp>
352 struct remove_reference<_Tp&>
353 { typedef _Tp type; };
355 // NB: Careful with reference to void.
356 template<typename _Tp, bool = (is_void<_Tp>::value
357 || is_reference<_Tp>::value)>
358 struct __add_reference_helper
359 { typedef _Tp& type; };
361 template<typename _Tp>
362 struct __add_reference_helper<_Tp, true>
363 { typedef _Tp type; };
365 template<typename _Tp>
367 : public __add_reference_helper<_Tp>
370 /// @brief array modifications [4.7.3].
371 template<typename _Tp>
373 { typedef _Tp type; };
375 template<typename _Tp, std::size_t _Size>
376 struct remove_extent<_Tp[_Size]>
377 { typedef _Tp type; };
379 template<typename _Tp>
380 struct remove_extent<_Tp[]>
381 { typedef _Tp type; };
383 template<typename _Tp>
384 struct remove_all_extents
385 { typedef _Tp type; };
387 template<typename _Tp, std::size_t _Size>
388 struct remove_all_extents<_Tp[_Size]>
389 { typedef typename remove_all_extents<_Tp>::type type; };
391 template<typename _Tp>
392 struct remove_all_extents<_Tp[]>
393 { typedef typename remove_all_extents<_Tp>::type type; };
395 /// @brief pointer modifications [4.7.4].
396 #undef _DEFINE_SPEC_BODY
397 #define _DEFINE_SPEC_BODY(_Value) \
398 { typedef _Tp type; };
400 template<typename _Tp>
401 struct remove_pointer
402 { typedef _Tp type; };
403 _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
405 template<typename _Tp>
407 { typedef typename remove_reference<_Tp>::type* type; };
409 /// @brief other transformations [4.8].
411 // Due to c++/19163 and c++/17743, for the time being we cannot use
412 // the correct, neat implementation :-(
414 // template<std::size_t _Len, std::size_t _Align>
415 // struct aligned_storage
416 // { typedef char type[_Len] __attribute__((__aligned__(_Align))); }
418 // Temporary workaround, useful for Align up to 32:
419 template<std::size_t, std::size_t>
420 struct aligned_storage { };
422 template<std::size_t _Len>
423 struct aligned_storage<_Len, 1>
427 unsigned char __data[_Len];
428 char __align __attribute__((__aligned__(1)));
432 template<std::size_t _Len>
433 struct aligned_storage<_Len, 2>
437 unsigned char __data[_Len];
438 char __align __attribute__((__aligned__(2)));
442 template<std::size_t _Len>
443 struct aligned_storage<_Len, 4>
447 unsigned char __data[_Len];
448 char __align __attribute__((__aligned__(4)));
452 template<std::size_t _Len>
453 struct aligned_storage<_Len, 8>
457 unsigned char __data[_Len];
458 char __align __attribute__((__aligned__(8)));
462 template<std::size_t _Len>
463 struct aligned_storage<_Len, 16>
467 unsigned char __data[_Len];
468 char __align __attribute__((__aligned__(16)));
472 template<std::size_t _Len>
473 struct aligned_storage<_Len, 32>
477 unsigned char __data[_Len];
478 char __align __attribute__((__aligned__(32)));
482 #undef _DEFINE_SPEC_0_HELPER
483 #undef _DEFINE_SPEC_1_HELPER
484 #undef _DEFINE_SPEC_2_HELPER
486 #undef _DEFINE_SPEC_BODY
488 _GLIBCXX_END_NAMESPACE_TR1