OSDN Git Service

2007-09-16 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_member_object_pointer
137     : public false_type { };
138   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
139                !is_function<_Tp>::value)
140
141   template<typename>
142     struct is_member_function_pointer
143     : public false_type { };
144   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
145                is_function<_Tp>::value)
146
147   template<typename _Tp>
148     struct is_enum
149     : public integral_constant<bool, __is_enum(_Tp)>
150     { };
151
152   template<typename _Tp>
153     struct is_union
154     : public integral_constant<bool, __is_union(_Tp)>
155     { };
156
157   template<typename _Tp>
158     struct is_class
159     : public integral_constant<bool, __is_class(_Tp)>
160     { };
161
162   template<typename>
163     struct __is_function_helper
164     : public false_type { };
165
166   template<typename _Res, typename... _ArgTypes>
167     struct __is_function_helper<_Res(_ArgTypes...)>
168     : public true_type { };
169
170   template<typename _Res, typename... _ArgTypes>
171     struct __is_function_helper<_Res(_ArgTypes......)>
172     : public true_type { };
173
174   template<typename _Tp>
175     struct is_function
176     : public integral_constant<bool, (__is_function_helper<typename
177                                       remove_cv<_Tp>::type>::value)>
178     { };
179
180   /// @brief  composite type traits [4.5.2].
181   template<typename _Tp>
182     struct is_arithmetic
183     : public integral_constant<bool, (is_integral<_Tp>::value
184                                       || is_floating_point<_Tp>::value)>
185     { };
186
187   template<typename _Tp>
188     struct is_fundamental
189     : public integral_constant<bool, (is_arithmetic<_Tp>::value
190                                       || is_void<_Tp>::value)>
191     { };
192
193   template<typename _Tp>
194     struct is_object
195     : public integral_constant<bool, !(is_function<_Tp>::value
196                                        || is_reference<_Tp>::value
197                                        || is_void<_Tp>::value)>
198     { };
199
200   template<typename _Tp>
201     struct is_scalar
202     : public integral_constant<bool, (is_arithmetic<_Tp>::value
203                                       || is_enum<_Tp>::value
204                                       || is_pointer<_Tp>::value
205                                       || is_member_pointer<_Tp>::value)>
206     { };
207
208   template<typename _Tp>
209     struct is_compound
210     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
211
212   template<typename _Tp>
213     struct is_member_pointer
214     : public integral_constant<bool,
215                                (is_member_object_pointer<_Tp>::value
216                                 || is_member_function_pointer<_Tp>::value)>
217     { };
218
219   /// @brief  type properties [4.5.3].
220   template<typename>
221     struct is_const
222     : public false_type { };
223
224   template<typename _Tp>
225     struct is_const<_Tp const>
226     : public true_type { };
227   
228   template<typename>
229     struct is_volatile
230     : public false_type { };
231
232   template<typename _Tp>
233     struct is_volatile<_Tp volatile>
234     : public true_type { };
235
236   template<typename _Tp>
237     struct is_empty
238     : public integral_constant<bool, __is_empty(_Tp)>
239     { };
240
241   template<typename _Tp>
242     struct is_polymorphic
243     : public integral_constant<bool, __is_polymorphic(_Tp)>
244     { };
245
246   template<typename _Tp>
247     struct is_abstract
248     : public integral_constant<bool, __is_abstract(_Tp)>
249     { };
250
251   template<typename _Tp>
252     struct has_virtual_destructor
253     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
254     { };
255
256   template<typename _Tp>
257     struct alignment_of
258     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
259   
260   template<typename>
261     struct rank
262     : public integral_constant<std::size_t, 0> { };
263    
264   template<typename _Tp, std::size_t _Size>
265     struct rank<_Tp[_Size]>
266     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
267
268   template<typename _Tp>
269     struct rank<_Tp[]>
270     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
271    
272   template<typename, unsigned>
273     struct extent
274     : public integral_constant<std::size_t, 0> { };
275   
276   template<typename _Tp, unsigned _Uint, std::size_t _Size>
277     struct extent<_Tp[_Size], _Uint>
278     : public integral_constant<std::size_t,
279                                _Uint == 0 ? _Size : extent<_Tp,
280                                                            _Uint - 1>::value>
281     { };
282
283   template<typename _Tp, unsigned _Uint>
284     struct extent<_Tp[], _Uint>
285     : public integral_constant<std::size_t,
286                                _Uint == 0 ? 0 : extent<_Tp,
287                                                        _Uint - 1>::value>
288     { };
289   
290   /// @brief  relationships between types [4.6].
291   template<typename, typename>
292     struct is_same
293     : public false_type { };
294
295   template<typename _Tp>
296     struct is_same<_Tp, _Tp>
297     : public true_type { };
298
299   /// @brief  const-volatile modifications [4.7.1].
300   template<typename _Tp>
301     struct remove_const
302     { typedef _Tp     type; };
303
304   template<typename _Tp>
305     struct remove_const<_Tp const>
306     { typedef _Tp     type; };
307   
308   template<typename _Tp>
309     struct remove_volatile
310     { typedef _Tp     type; };
311
312   template<typename _Tp>
313     struct remove_volatile<_Tp volatile>
314     { typedef _Tp     type; };
315   
316   template<typename _Tp>
317     struct remove_cv
318     {
319       typedef typename
320       remove_const<typename remove_volatile<_Tp>::type>::type     type;
321     };
322   
323   template<typename _Tp>
324     struct add_const
325     { typedef _Tp const     type; };
326    
327   template<typename _Tp>
328     struct add_volatile
329     { typedef _Tp volatile     type; };
330   
331   template<typename _Tp>
332     struct add_cv
333     {
334       typedef typename
335       add_const<typename add_volatile<_Tp>::type>::type     type;
336     };
337
338   /// @brief  array modifications [4.7.3].
339   template<typename _Tp>
340     struct remove_extent
341     { typedef _Tp     type; };
342
343   template<typename _Tp, std::size_t _Size>
344     struct remove_extent<_Tp[_Size]>
345     { typedef _Tp     type; };
346
347   template<typename _Tp>
348     struct remove_extent<_Tp[]>
349     { typedef _Tp     type; };
350
351   template<typename _Tp>
352     struct remove_all_extents
353     { typedef _Tp     type; };
354
355   template<typename _Tp, std::size_t _Size>
356     struct remove_all_extents<_Tp[_Size]>
357     { typedef typename remove_all_extents<_Tp>::type     type; };
358
359   template<typename _Tp>
360     struct remove_all_extents<_Tp[]>
361     { typedef typename remove_all_extents<_Tp>::type     type; };
362
363   /// @brief  pointer modifications [4.7.4].
364 #undef _DEFINE_SPEC_BODY
365 #define _DEFINE_SPEC_BODY(_Value)      \
366     { typedef _Tp     type; };
367
368   template<typename _Tp>
369     struct remove_pointer
370     { typedef _Tp     type; };
371   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
372   
373   template<typename _Tp>
374     struct add_pointer
375     { typedef typename remove_reference<_Tp>::type*     type; };
376
377   /// @brief  other transformations [4.8].
378   template<std::size_t _Len, std::size_t _Align>
379     struct aligned_storage
380     { 
381       union type
382       {
383         unsigned char __data[_Len];
384         struct __attribute__((__aligned__((_Align)))) { } __aligner; 
385       };
386     };
387
388 #undef _DEFINE_SPEC_0_HELPER
389 #undef _DEFINE_SPEC_1_HELPER
390 #undef _DEFINE_SPEC_2_HELPER
391 #undef _DEFINE_SPEC
392 #undef _DEFINE_SPEC_BODY
393
394 _GLIBCXX_END_NAMESPACE_TR1
395 }