1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2007, 2008 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.
37 _GLIBCXX_BEGIN_NAMESPACE_TR1
39 // For use in __is_convertible_simple.
43 typedef struct { char __arr[2]; } __two;
46 #define _DEFINE_SPEC_BODY(_Value) \
47 : public integral_constant<bool, _Value> { };
49 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \
52 _DEFINE_SPEC_BODY(_Value)
54 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \
55 template<typename _Tp> \
57 _DEFINE_SPEC_BODY(_Value)
59 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \
60 template<typename _Tp, typename _Cp> \
62 _DEFINE_SPEC_BODY(_Value)
64 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
65 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \
66 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \
67 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \
68 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
70 /// helper classes [4.3].
71 template<typename _Tp, _Tp __v>
72 struct integral_constant
74 static const _Tp value = __v;
75 typedef _Tp value_type;
76 typedef integral_constant<_Tp, __v> type;
79 /// typedef for true_type
80 typedef integral_constant<bool, true> true_type;
82 /// typedef for true_type
83 typedef integral_constant<bool, false> false_type;
85 template<typename _Tp, _Tp __v>
86 const _Tp integral_constant<_Tp, __v>::value;
88 /// primary type categories [4.5.1].
91 : public false_type { };
92 _DEFINE_SPEC(0, is_void, void, true)
97 : public false_type { };
98 _DEFINE_SPEC(0, is_integral, bool, true)
99 _DEFINE_SPEC(0, is_integral, char, true)
100 _DEFINE_SPEC(0, is_integral, signed char, true)
101 _DEFINE_SPEC(0, is_integral, unsigned char, true)
102 #ifdef _GLIBCXX_USE_WCHAR_T
103 _DEFINE_SPEC(0, is_integral, wchar_t, true)
105 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
106 _DEFINE_SPEC(0, is_integral, char16_t, true)
107 _DEFINE_SPEC(0, is_integral, char32_t, true)
109 _DEFINE_SPEC(0, is_integral, short, true)
110 _DEFINE_SPEC(0, is_integral, unsigned short, true)
111 _DEFINE_SPEC(0, is_integral, int, true)
112 _DEFINE_SPEC(0, is_integral, unsigned int, true)
113 _DEFINE_SPEC(0, is_integral, long, true)
114 _DEFINE_SPEC(0, is_integral, unsigned long, true)
115 _DEFINE_SPEC(0, is_integral, long long, true)
116 _DEFINE_SPEC(0, is_integral, unsigned long long, true)
118 /// is_floating_point
120 struct is_floating_point
121 : public false_type { };
122 _DEFINE_SPEC(0, is_floating_point, float, true)
123 _DEFINE_SPEC(0, is_floating_point, double, true)
124 _DEFINE_SPEC(0, is_floating_point, long double, true)
129 : public false_type { };
131 template<typename _Tp, std::size_t _Size>
132 struct is_array<_Tp[_Size]>
133 : public true_type { };
135 template<typename _Tp>
136 struct is_array<_Tp[]>
137 : public true_type { };
142 : public false_type { };
143 _DEFINE_SPEC(1, is_pointer, _Tp*, true)
146 template<typename _Tp>
150 template<typename _Tp>
153 /// is_member_object_pointer
155 struct is_member_object_pointer
156 : public false_type { };
157 _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
158 !is_function<_Tp>::value)
160 /// is_member_function_pointer
162 struct is_member_function_pointer
163 : public false_type { };
164 _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
165 is_function<_Tp>::value)
168 template<typename _Tp>
170 : public integral_constant<bool, __is_enum(_Tp)>
174 template<typename _Tp>
176 : public integral_constant<bool, __is_union(_Tp)>
180 template<typename _Tp>
182 : public integral_constant<bool, __is_class(_Tp)>
185 template<typename _Tp>
189 struct __is_function_helper
190 : public false_type { };
192 template<typename _Res, typename... _ArgTypes>
193 struct __is_function_helper<_Res(_ArgTypes...)>
194 : public true_type { };
196 template<typename _Res, typename... _ArgTypes>
197 struct __is_function_helper<_Res(_ArgTypes......)>
198 : public true_type { };
201 template<typename _Tp>
203 : public integral_constant<bool, (__is_function_helper<typename
204 remove_cv<_Tp>::type>::value)>
207 /// composite type traits [4.5.2].
208 template<typename _Tp>
210 : public integral_constant<bool, (is_integral<_Tp>::value
211 || is_floating_point<_Tp>::value)>
215 template<typename _Tp>
216 struct is_fundamental
217 : public integral_constant<bool, (is_arithmetic<_Tp>::value
218 || is_void<_Tp>::value)>
222 template<typename _Tp>
224 : public integral_constant<bool, !(is_function<_Tp>::value
225 || is_reference<_Tp>::value
226 || is_void<_Tp>::value)>
229 /// is_member_pointer
230 template<typename _Tp>
231 struct is_member_pointer;
234 template<typename _Tp>
236 : public integral_constant<bool, (is_arithmetic<_Tp>::value
237 || is_enum<_Tp>::value
238 || is_pointer<_Tp>::value
239 || is_member_pointer<_Tp>::value)>
243 template<typename _Tp>
245 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
247 /// is_member_pointer
248 template<typename _Tp>
249 struct is_member_pointer
250 : public integral_constant<bool,
251 (is_member_object_pointer<_Tp>::value
252 || is_member_function_pointer<_Tp>::value)>
255 /// type properties [4.5.3].
258 : public false_type { };
261 template<typename _Tp>
262 struct is_const<_Tp const>
263 : public true_type { };
268 : public false_type { };
270 template<typename _Tp>
271 struct is_volatile<_Tp volatile>
272 : public true_type { };
275 template<typename _Tp>
277 : public integral_constant<bool, __is_empty(_Tp)>
281 template<typename _Tp>
282 struct is_polymorphic
283 : public integral_constant<bool, __is_polymorphic(_Tp)>
287 template<typename _Tp>
289 : public integral_constant<bool, __is_abstract(_Tp)>
292 /// has_virtual_destructor
293 template<typename _Tp>
294 struct has_virtual_destructor
295 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
299 template<typename _Tp>
301 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
306 : public integral_constant<std::size_t, 0> { };
308 template<typename _Tp, std::size_t _Size>
309 struct rank<_Tp[_Size]>
310 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
312 template<typename _Tp>
314 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
317 template<typename, unsigned _Uint = 0>
319 : public integral_constant<std::size_t, 0> { };
321 template<typename _Tp, unsigned _Uint, std::size_t _Size>
322 struct extent<_Tp[_Size], _Uint>
323 : public integral_constant<std::size_t,
324 _Uint == 0 ? _Size : extent<_Tp,
328 template<typename _Tp, unsigned _Uint>
329 struct extent<_Tp[], _Uint>
330 : public integral_constant<std::size_t,
331 _Uint == 0 ? 0 : extent<_Tp,
335 /// relationships between types [4.6].
336 template<typename, typename>
338 : public false_type { };
340 template<typename _Tp>
341 struct is_same<_Tp, _Tp>
342 : public true_type { };
344 /// const-volatile modifications [4.7.1].
345 template<typename _Tp>
347 { typedef _Tp type; };
349 template<typename _Tp>
350 struct remove_const<_Tp const>
351 { typedef _Tp type; };
354 template<typename _Tp>
355 struct remove_volatile
356 { typedef _Tp type; };
358 template<typename _Tp>
359 struct remove_volatile<_Tp volatile>
360 { typedef _Tp type; };
363 template<typename _Tp>
367 remove_const<typename remove_volatile<_Tp>::type>::type type;
371 template<typename _Tp>
373 { typedef _Tp const type; };
376 template<typename _Tp>
378 { typedef _Tp volatile type; };
381 template<typename _Tp>
385 add_const<typename add_volatile<_Tp>::type>::type type;
388 /// array modifications [4.7.3].
389 template<typename _Tp>
391 { typedef _Tp type; };
393 template<typename _Tp, std::size_t _Size>
394 struct remove_extent<_Tp[_Size]>
395 { typedef _Tp type; };
397 template<typename _Tp>
398 struct remove_extent<_Tp[]>
399 { typedef _Tp type; };
401 /// remove_all_extents
402 template<typename _Tp>
403 struct remove_all_extents
404 { typedef _Tp type; };
406 template<typename _Tp, std::size_t _Size>
407 struct remove_all_extents<_Tp[_Size]>
408 { typedef typename remove_all_extents<_Tp>::type type; };
410 template<typename _Tp>
411 struct remove_all_extents<_Tp[]>
412 { typedef typename remove_all_extents<_Tp>::type type; };
414 /// pointer modifications [4.7.4].
415 #undef _DEFINE_SPEC_BODY
416 #define _DEFINE_SPEC_BODY(_Value) \
417 { typedef _Tp type; };
420 template<typename _Tp>
421 struct remove_pointer
422 { typedef _Tp type; };
423 _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
426 template<typename _Tp>
427 struct remove_reference;
430 template<typename _Tp>
432 { typedef typename remove_reference<_Tp>::type* type; };
434 #undef _DEFINE_SPEC_0_HELPER
435 #undef _DEFINE_SPEC_1_HELPER
436 #undef _DEFINE_SPEC_2_HELPER
438 #undef _DEFINE_SPEC_BODY
440 _GLIBCXX_END_NAMESPACE_TR1