OSDN Git Service

2007-05-31 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1_impl / type_traits
1 // TR1 type_traits -*- C++ -*-
2
3 // Copyright (C) 2007 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 #include <tr1_impl/type_traitsfwd.h>
36
37 namespace std
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_TR1
40
41   // For use in __is_convertible_simple.
42   struct __sfinae_types
43   {
44     typedef char __one;
45     typedef struct { char __arr[2]; } __two;
46   };
47
48 #define _DEFINE_SPEC_BODY(_Value)                                    \
49     : public integral_constant<bool, _Value> { };
50
51 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
52   template<>                                                         \
53     struct _Spec                                                     \
54     _DEFINE_SPEC_BODY(_Value)
55
56 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
57   template<typename _Tp>                                             \
58     struct _Spec                                                     \
59     _DEFINE_SPEC_BODY(_Value)
60       
61 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
62   template<typename _Tp, typename _Cp>                               \
63     struct _Spec                                                     \
64     _DEFINE_SPEC_BODY(_Value)
65
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)
71
72   /// @brief  helper classes [4.3].
73   template<typename _Tp, _Tp __v>
74     struct integral_constant
75     {
76       static const _Tp                      value = __v;
77       typedef _Tp                           value_type;
78       typedef integral_constant<_Tp, __v>   type;
79     };
80   typedef integral_constant<bool, true>     true_type;
81   typedef integral_constant<bool, false>    false_type;
82
83   template<typename _Tp, _Tp __v>
84     const _Tp integral_constant<_Tp, __v>::value;
85
86   /// @brief  primary type categories [4.5.1].
87   template<typename>
88     struct is_void
89     : public false_type { };
90   _DEFINE_SPEC(0, is_void, void, true)
91
92   template<typename>
93     struct is_integral
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)
101 #endif
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)
110
111   template<typename>
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)
117
118   template<typename>
119     struct is_array
120     : public false_type { };
121
122   template<typename _Tp, std::size_t _Size>
123     struct is_array<_Tp[_Size]>
124     : public true_type { };
125
126   template<typename _Tp>
127     struct is_array<_Tp[]>
128     : public true_type { };
129
130   template<typename>
131     struct is_pointer
132     : public false_type { };
133   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
134  
135   template<typename>
136     struct is_reference
137     : public false_type { };
138
139   template<typename _Tp>
140     struct is_reference<_Tp&>
141     : public true_type { };
142
143   template<typename>
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)
148
149   template<typename>
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)
154
155   template<typename _Tp>
156     struct is_enum
157     : public integral_constant<bool, __is_enum(_Tp)>
158     { };
159
160   template<typename _Tp>
161     struct is_union
162     : public integral_constant<bool, __is_union(_Tp)>
163     { };
164
165   template<typename _Tp>
166     struct is_class
167     : public integral_constant<bool, __is_class(_Tp)>
168     { };
169
170   template<typename>
171     struct __is_function_helper
172     : public false_type { };
173
174   template<typename _Res, typename... _ArgTypes>
175     struct __is_function_helper<_Res(_ArgTypes...)>
176     : public true_type { };
177
178   template<typename _Res, typename... _ArgTypes>
179     struct __is_function_helper<_Res(_ArgTypes......)>
180     : public true_type { };
181
182   template<typename _Tp>
183     struct is_function
184     : public integral_constant<bool, (__is_function_helper<typename
185                                       remove_cv<_Tp>::type>::value)>
186     { };
187
188   /// @brief  composite type traits [4.5.2].
189   template<typename _Tp>
190     struct is_arithmetic
191     : public integral_constant<bool, (is_integral<_Tp>::value
192                                       || is_floating_point<_Tp>::value)>
193     { };
194
195   template<typename _Tp>
196     struct is_fundamental
197     : public integral_constant<bool, (is_arithmetic<_Tp>::value
198                                       || is_void<_Tp>::value)>
199     { };
200
201   template<typename _Tp>
202     struct is_object
203     : public integral_constant<bool, !(is_function<_Tp>::value
204                                        || is_reference<_Tp>::value
205                                        || is_void<_Tp>::value)>
206     { };
207
208   template<typename _Tp>
209     struct is_scalar
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)>
214     { };
215
216   template<typename _Tp>
217     struct is_compound
218     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
219
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)>
225     { };
226
227   /// @brief  type properties [4.5.3].
228   template<typename>
229     struct is_const
230     : public false_type { };
231
232   template<typename _Tp>
233     struct is_const<_Tp const>
234     : public true_type { };
235   
236   template<typename>
237     struct is_volatile
238     : public false_type { };
239
240   template<typename _Tp>
241     struct is_volatile<_Tp volatile>
242     : public true_type { };
243
244   template<typename _Tp>
245     struct is_empty
246     : public integral_constant<bool, __is_empty(_Tp)>
247     { };
248
249   template<typename _Tp>
250     struct is_polymorphic
251     : public integral_constant<bool, __is_polymorphic(_Tp)>
252     { };
253
254   template<typename _Tp>
255     struct is_abstract
256     : public integral_constant<bool, __is_abstract(_Tp)>
257     { };
258
259   template<typename _Tp>
260     struct has_virtual_destructor
261     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
262     { };
263
264   template<typename _Tp>
265     struct alignment_of
266     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
267   
268   template<typename>
269     struct rank
270     : public integral_constant<std::size_t, 0> { };
271    
272   template<typename _Tp, std::size_t _Size>
273     struct rank<_Tp[_Size]>
274     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
275
276   template<typename _Tp>
277     struct rank<_Tp[]>
278     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
279    
280   template<typename, unsigned>
281     struct extent
282     : public integral_constant<std::size_t, 0> { };
283   
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,
288                                                            _Uint - 1>::value>
289     { };
290
291   template<typename _Tp, unsigned _Uint>
292     struct extent<_Tp[], _Uint>
293     : public integral_constant<std::size_t,
294                                _Uint == 0 ? 0 : extent<_Tp,
295                                                        _Uint - 1>::value>
296     { };
297   
298   /// @brief  relationships between types [4.6].
299   template<typename, typename>
300     struct is_same
301     : public false_type { };
302
303   template<typename _Tp>
304     struct is_same<_Tp, _Tp>
305     : public true_type { };
306
307   /// @brief  const-volatile modifications [4.7.1].
308   template<typename _Tp>
309     struct remove_const
310     { typedef _Tp     type; };
311
312   template<typename _Tp>
313     struct remove_const<_Tp const>
314     { typedef _Tp     type; };
315   
316   template<typename _Tp>
317     struct remove_volatile
318     { typedef _Tp     type; };
319
320   template<typename _Tp>
321     struct remove_volatile<_Tp volatile>
322     { typedef _Tp     type; };
323   
324   template<typename _Tp>
325     struct remove_cv
326     {
327       typedef typename
328       remove_const<typename remove_volatile<_Tp>::type>::type     type;
329     };
330   
331   template<typename _Tp>
332     struct add_const
333     { typedef _Tp const     type; };
334    
335   template<typename _Tp>
336     struct add_volatile
337     { typedef _Tp volatile     type; };
338   
339   template<typename _Tp>
340     struct add_cv
341     {
342       typedef typename
343       add_const<typename add_volatile<_Tp>::type>::type     type;
344     };
345
346   /// @brief  reference modifications [4.7.2].
347   template<typename _Tp>
348     struct remove_reference
349     { typedef _Tp     type; };
350
351   template<typename _Tp>
352     struct remove_reference<_Tp&>
353     { typedef _Tp     type; };
354
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; };
360
361   template<typename _Tp>
362     struct __add_reference_helper<_Tp, true>
363     { typedef _Tp     type; };
364
365   template<typename _Tp>
366     struct add_reference
367     : public __add_reference_helper<_Tp>
368     { };
369
370   /// @brief  array modifications [4.7.3].
371   template<typename _Tp>
372     struct remove_extent
373     { typedef _Tp     type; };
374
375   template<typename _Tp, std::size_t _Size>
376     struct remove_extent<_Tp[_Size]>
377     { typedef _Tp     type; };
378
379   template<typename _Tp>
380     struct remove_extent<_Tp[]>
381     { typedef _Tp     type; };
382
383   template<typename _Tp>
384     struct remove_all_extents
385     { typedef _Tp     type; };
386
387   template<typename _Tp, std::size_t _Size>
388     struct remove_all_extents<_Tp[_Size]>
389     { typedef typename remove_all_extents<_Tp>::type     type; };
390
391   template<typename _Tp>
392     struct remove_all_extents<_Tp[]>
393     { typedef typename remove_all_extents<_Tp>::type     type; };
394
395   /// @brief  pointer modifications [4.7.4].
396 #undef _DEFINE_SPEC_BODY
397 #define _DEFINE_SPEC_BODY(_Value)      \
398     { typedef _Tp     type; };
399
400   template<typename _Tp>
401     struct remove_pointer
402     { typedef _Tp     type; };
403   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
404   
405   template<typename _Tp>
406     struct add_pointer
407     { typedef typename remove_reference<_Tp>::type*     type; };
408
409   /// @brief  other transformations [4.8].
410   
411   // Due to c++/19163 and c++/17743, for the time being we cannot use
412   // the correct, neat implementation :-(
413   // 
414   // template<std::size_t _Len, std::size_t _Align>
415   //   struct aligned_storage
416   //   { typedef char type[_Len] __attribute__((__aligned__(_Align))); }
417   //
418   // Temporary workaround, useful for Align up to 32:
419   template<std::size_t, std::size_t>
420     struct aligned_storage { };
421
422   template<std::size_t _Len>
423     struct aligned_storage<_Len, 1>
424     {
425       union type
426       {
427         unsigned char __data[_Len];
428         char __align __attribute__((__aligned__(1)));
429       };
430     };
431
432   template<std::size_t _Len>
433     struct aligned_storage<_Len, 2>
434     {
435       union type
436       {
437         unsigned char __data[_Len];
438         char __align __attribute__((__aligned__(2)));
439       };
440     };
441
442   template<std::size_t _Len>
443     struct aligned_storage<_Len, 4>
444     {
445       union type
446       {
447         unsigned char __data[_Len];
448         char __align __attribute__((__aligned__(4)));
449       };
450     };
451
452   template<std::size_t _Len>
453     struct aligned_storage<_Len, 8>
454     {
455       union type
456       {
457         unsigned char __data[_Len];
458         char __align __attribute__((__aligned__(8)));
459       };
460     };
461
462   template<std::size_t _Len>
463     struct aligned_storage<_Len, 16>
464     {
465       union type
466       {
467         unsigned char __data[_Len];
468         char __align __attribute__((__aligned__(16)));
469       };
470     };
471   
472   template<std::size_t _Len>
473     struct aligned_storage<_Len, 32>
474     {
475       union type
476       {
477         unsigned char __data[_Len];
478         char __align __attribute__((__aligned__(32)));
479       };
480     };
481
482 #undef _DEFINE_SPEC_0_HELPER
483 #undef _DEFINE_SPEC_1_HELPER
484 #undef _DEFINE_SPEC_2_HELPER
485 #undef _DEFINE_SPEC
486 #undef _DEFINE_SPEC_BODY
487
488 _GLIBCXX_END_NAMESPACE_TR1
489 }