OSDN Git Service

2008-08-09 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1_impl / type_traits
1 // TR1 type_traits -*- C++ -*-
2
3 // Copyright (C) 2007, 2008 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 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
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
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
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.
33 */
34
35 namespace std
36 {
37 _GLIBCXX_BEGIN_NAMESPACE_TR1
38
39   // For use in __is_convertible_simple.
40   struct __sfinae_types
41   {
42     typedef char __one;
43     typedef struct { char __arr[2]; } __two;
44   };
45
46 #define _DEFINE_SPEC_BODY(_Value)                                    \
47     : public integral_constant<bool, _Value> { };
48
49 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
50   template<>                                                         \
51     struct _Spec                                                     \
52     _DEFINE_SPEC_BODY(_Value)
53
54 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
55   template<typename _Tp>                                             \
56     struct _Spec                                                     \
57     _DEFINE_SPEC_BODY(_Value)
58       
59 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
60   template<typename _Tp, typename _Cp>                               \
61     struct _Spec                                                     \
62     _DEFINE_SPEC_BODY(_Value)
63
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)
69
70   /// helper classes [4.3].
71   template<typename _Tp, _Tp __v>
72     struct integral_constant
73     {
74       static const _Tp                      value = __v;
75       typedef _Tp                           value_type;
76       typedef integral_constant<_Tp, __v>   type;
77     };
78   
79   /// typedef for true_type
80   typedef integral_constant<bool, true>     true_type;
81
82   /// typedef for true_type
83   typedef integral_constant<bool, false>    false_type;
84
85   template<typename _Tp, _Tp __v>
86     const _Tp integral_constant<_Tp, __v>::value;
87
88   /// primary type categories [4.5.1].
89   template<typename>
90     struct is_void
91     : public false_type { };
92   _DEFINE_SPEC(0, is_void, void, true)
93
94   /// is_integral
95   template<typename>
96     struct is_integral
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)
104 #endif
105 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
106   _DEFINE_SPEC(0, is_integral, char16_t, true)
107   _DEFINE_SPEC(0, is_integral, char32_t, true)
108 #endif
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)
117
118   /// is_floating_point
119   template<typename>
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)
125
126   /// is_array
127   template<typename>
128     struct is_array
129     : public false_type { };
130
131   template<typename _Tp, std::size_t _Size>
132     struct is_array<_Tp[_Size]>
133     : public true_type { };
134
135   template<typename _Tp>
136     struct is_array<_Tp[]>
137     : public true_type { };
138
139   /// is_pointer
140   template<typename>
141     struct is_pointer
142     : public false_type { };
143   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
144
145   /// is_reference
146   template<typename _Tp>
147     struct is_reference;
148
149   /// is_function
150   template<typename _Tp>
151     struct is_function;
152
153   /// is_member_object_pointer
154   template<typename>
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)
159
160   /// is_member_function_pointer
161   template<typename>
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)
166
167   /// is_enum
168   template<typename _Tp>
169     struct is_enum
170     : public integral_constant<bool, __is_enum(_Tp)>
171     { };
172
173   /// is_union
174   template<typename _Tp>
175     struct is_union
176     : public integral_constant<bool, __is_union(_Tp)>
177     { };
178
179   /// is_class
180   template<typename _Tp>
181     struct is_class
182     : public integral_constant<bool, __is_class(_Tp)>
183     { };
184
185   template<typename _Tp>
186     struct remove_cv;
187
188   template<typename>
189     struct __is_function_helper
190     : public false_type { };
191
192   template<typename _Res, typename... _ArgTypes>
193     struct __is_function_helper<_Res(_ArgTypes...)>
194     : public true_type { };
195
196   template<typename _Res, typename... _ArgTypes>
197     struct __is_function_helper<_Res(_ArgTypes......)>
198     : public true_type { };
199
200   /// is_function
201   template<typename _Tp>
202     struct is_function
203     : public integral_constant<bool, (__is_function_helper<typename
204                                       remove_cv<_Tp>::type>::value)>
205     { };
206
207   /// composite type traits [4.5.2].
208   template<typename _Tp>
209     struct is_arithmetic
210     : public integral_constant<bool, (is_integral<_Tp>::value
211                                       || is_floating_point<_Tp>::value)>
212     { };
213
214   /// is_fundamental
215   template<typename _Tp>
216     struct is_fundamental
217     : public integral_constant<bool, (is_arithmetic<_Tp>::value
218                                       || is_void<_Tp>::value)>
219     { };
220
221   /// is_object
222   template<typename _Tp>
223     struct is_object
224     : public integral_constant<bool, !(is_function<_Tp>::value
225                                        || is_reference<_Tp>::value
226                                        || is_void<_Tp>::value)>
227     { };
228
229   /// is_member_pointer
230   template<typename _Tp>
231     struct is_member_pointer;
232
233   /// is_scalar
234   template<typename _Tp>
235     struct is_scalar
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)>
240     { };
241
242   /// is_compound
243   template<typename _Tp>
244     struct is_compound
245     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
246
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)>
253     { };
254
255   /// type properties [4.5.3].
256   template<typename>
257     struct is_const
258     : public false_type { };
259
260   /// is_const
261   template<typename _Tp>
262     struct is_const<_Tp const>
263     : public true_type { };
264   
265   /// is_volatile
266   template<typename>
267     struct is_volatile
268     : public false_type { };
269
270   template<typename _Tp>
271     struct is_volatile<_Tp volatile>
272     : public true_type { };
273
274   /// is_empty
275   template<typename _Tp>
276     struct is_empty
277     : public integral_constant<bool, __is_empty(_Tp)>
278     { };
279
280   /// is_polymorphic
281   template<typename _Tp>
282     struct is_polymorphic
283     : public integral_constant<bool, __is_polymorphic(_Tp)>
284     { };
285
286   /// is_abstract
287   template<typename _Tp>
288     struct is_abstract
289     : public integral_constant<bool, __is_abstract(_Tp)>
290     { };
291
292   /// has_virtual_destructor
293   template<typename _Tp>
294     struct has_virtual_destructor
295     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
296     { };
297
298   /// alignment_of
299   template<typename _Tp>
300     struct alignment_of
301     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
302   
303   /// rank
304   template<typename>
305     struct rank
306     : public integral_constant<std::size_t, 0> { };
307    
308   template<typename _Tp, std::size_t _Size>
309     struct rank<_Tp[_Size]>
310     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
311
312   template<typename _Tp>
313     struct rank<_Tp[]>
314     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
315
316   /// extent
317   template<typename, unsigned _Uint = 0>
318     struct extent
319     : public integral_constant<std::size_t, 0> { };
320   
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,
325                                                            _Uint - 1>::value>
326     { };
327
328   template<typename _Tp, unsigned _Uint>
329     struct extent<_Tp[], _Uint>
330     : public integral_constant<std::size_t,
331                                _Uint == 0 ? 0 : extent<_Tp,
332                                                        _Uint - 1>::value>
333     { };
334
335   /// relationships between types [4.6].
336   template<typename, typename>
337     struct is_same
338     : public false_type { };
339
340   template<typename _Tp>
341     struct is_same<_Tp, _Tp>
342     : public true_type { };
343
344   /// const-volatile modifications [4.7.1].
345   template<typename _Tp>
346     struct remove_const
347     { typedef _Tp     type; };
348
349   template<typename _Tp>
350     struct remove_const<_Tp const>
351     { typedef _Tp     type; };
352   
353   /// remove_volatile
354   template<typename _Tp>
355     struct remove_volatile
356     { typedef _Tp     type; };
357
358   template<typename _Tp>
359     struct remove_volatile<_Tp volatile>
360     { typedef _Tp     type; };
361   
362   /// remove_cv
363   template<typename _Tp>
364     struct remove_cv
365     {
366       typedef typename
367       remove_const<typename remove_volatile<_Tp>::type>::type     type;
368     };
369   
370   /// add_const
371   template<typename _Tp>
372     struct add_const
373     { typedef _Tp const     type; };
374    
375   /// add_volatile
376   template<typename _Tp>
377     struct add_volatile
378     { typedef _Tp volatile     type; };
379   
380   /// add_cv
381   template<typename _Tp>
382     struct add_cv
383     {
384       typedef typename
385       add_const<typename add_volatile<_Tp>::type>::type     type;
386     };
387
388   /// array modifications [4.7.3].
389   template<typename _Tp>
390     struct remove_extent
391     { typedef _Tp     type; };
392
393   template<typename _Tp, std::size_t _Size>
394     struct remove_extent<_Tp[_Size]>
395     { typedef _Tp     type; };
396
397   template<typename _Tp>
398     struct remove_extent<_Tp[]>
399     { typedef _Tp     type; };
400
401   /// remove_all_extents
402   template<typename _Tp>
403     struct remove_all_extents
404     { typedef _Tp     type; };
405
406   template<typename _Tp, std::size_t _Size>
407     struct remove_all_extents<_Tp[_Size]>
408     { typedef typename remove_all_extents<_Tp>::type     type; };
409
410   template<typename _Tp>
411     struct remove_all_extents<_Tp[]>
412     { typedef typename remove_all_extents<_Tp>::type     type; };
413
414   /// pointer modifications [4.7.4].
415 #undef _DEFINE_SPEC_BODY
416 #define _DEFINE_SPEC_BODY(_Value)      \
417     { typedef _Tp     type; };
418
419   /// remove_pointer
420   template<typename _Tp>
421     struct remove_pointer
422     { typedef _Tp     type; };
423   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
424
425   /// remove_reference
426   template<typename _Tp>
427     struct remove_reference;
428
429   /// add_pointer
430   template<typename _Tp>
431     struct add_pointer
432     { typedef typename remove_reference<_Tp>::type*     type; };
433
434 #undef _DEFINE_SPEC_0_HELPER
435 #undef _DEFINE_SPEC_1_HELPER
436 #undef _DEFINE_SPEC_2_HELPER
437 #undef _DEFINE_SPEC
438 #undef _DEFINE_SPEC_BODY
439
440 _GLIBCXX_END_NAMESPACE_TR1
441 }