Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / gcc-4.1 / libstdc++-v3 / include / bits / cpp_type_traits.h
1 // The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
32
33 /** @file cpp_type_traits.h
34  *  This is an internal header file, included by other library headers.
35  *  You should not attempt to use it directly.
36  */
37
38 #ifndef _CPP_TYPE_TRAITS_H
39 #define _CPP_TYPE_TRAITS_H 1
40
41 #pragma GCC system_header
42
43 #include <bits/c++config.h>
44
45 //
46 // This file provides some compile-time information about various types.
47 // These representations were designed, on purpose, to be constant-expressions
48 // and not types as found in <bits/type_traits.h>.  In particular, they
49 // can be used in control structures and the optimizer hopefully will do
50 // the obvious thing.
51 //
52 // Why integral expressions, and not functions nor types?
53 // Firstly, these compile-time entities are used as template-arguments
54 // so function return values won't work:  We need compile-time entities.
55 // We're left with types and constant  integral expressions.
56 // Secondly, from the point of view of ease of use, type-based compile-time
57 // information is -not- *that* convenient.  On has to write lots of
58 // overloaded functions and to hope that the compiler will select the right
59 // one. As a net effect, the overall structure isn't very clear at first
60 // glance.
61 // Thirdly, partial ordering and overload resolution (of function templates)
62 // is highly costly in terms of compiler-resource.  It is a Good Thing to
63 // keep these resource consumption as least as possible.
64 //
65 // See valarray_array.h for a case use.
66 //
67 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
68 //
69 // Update 2005: types are also provided and <bits/type_traits.h> has been
70 // removed.
71 //
72
73 // NB: g++ can not compile these if declared within the class
74 // __is_pod itself.
75 namespace __gnu_internal
76 {
77   typedef char __one;
78   typedef char __two[2];
79
80   template<typename _Tp>
81   __one __test_type(int _Tp::*);
82   template<typename _Tp>
83   __two& __test_type(...);
84 } // namespace __gnu_internal
85
86 // Forward declaration hack, should really include this from somewhere.
87 namespace __gnu_cxx
88 {
89   template<typename _Iterator, typename _Container>
90     class __normal_iterator;
91 } // namespace __gnu_cxx
92
93 struct __true_type { };
94 struct __false_type { };
95
96 namespace std
97 {
98   template<bool>
99     struct __truth_type
100     { typedef __false_type __type; };
101
102   template<>
103     struct __truth_type<true>
104     { typedef __true_type __type; };
105
106   // N.B. The conversions to bool are needed due to the issue
107   // explained in c++/19404.
108   template<class _Sp, class _Tp>
109     struct __traitor
110     {
111       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
112       typedef typename __truth_type<__value>::__type __type;
113     };
114
115   // Compare for equality of types.
116   template<typename, typename>
117     struct __are_same
118     {
119       enum { __value = 0 };
120       typedef __false_type __type;
121     };
122
123   template<typename _Tp>
124     struct __are_same<_Tp, _Tp>
125     {
126       enum { __value = 1 };
127       typedef __true_type __type;
128     };
129
130   // Define a nested type if some predicate holds.
131   template<typename, bool>
132     struct __enable_if
133     { 
134     };
135
136   template<typename _Tp>
137     struct __enable_if<_Tp, true>
138     {
139       typedef _Tp __type;
140     };
141
142   // Holds if the template-argument is a void type.
143   template<typename _Tp>
144     struct __is_void
145     {
146       enum { __value = 0 };
147       typedef __false_type __type;
148     };
149
150   template<>
151     struct __is_void<void>
152     {
153       enum { __value = 1 };
154       typedef __true_type __type;
155     };
156
157   //
158   // Integer types
159   //
160   template<typename _Tp>
161     struct __is_integer
162     {
163       enum { __value = 0 };
164       typedef __false_type __type;
165     };
166
167   // Thirteen specializations (yes there are eleven standard integer
168   // types; 'long long' and 'unsigned long long' are supported as
169   // extensions)
170   template<>
171     struct __is_integer<bool>
172     {
173       enum { __value = 1 };
174       typedef __true_type __type;
175     };
176
177   template<>
178     struct __is_integer<char>
179     {
180       enum { __value = 1 };
181       typedef __true_type __type;
182     };
183
184   template<>
185     struct __is_integer<signed char>
186     {
187       enum { __value = 1 };
188       typedef __true_type __type;
189     };
190
191   template<>
192     struct __is_integer<unsigned char>
193     {
194       enum { __value = 1 };
195       typedef __true_type __type;
196     };
197
198 # ifdef _GLIBCXX_USE_WCHAR_T
199   template<>
200     struct __is_integer<wchar_t>
201     {
202       enum { __value = 1 };
203       typedef __true_type __type;
204     };
205 # endif
206
207   template<>
208     struct __is_integer<short>
209     {
210       enum { __value = 1 };
211       typedef __true_type __type;
212     };
213
214   template<>
215     struct __is_integer<unsigned short>
216     {
217       enum { __value = 1 };
218       typedef __true_type __type;
219     };
220
221   template<>
222     struct __is_integer<int>
223     {
224       enum { __value = 1 };
225       typedef __true_type __type;
226     };
227
228   template<>
229     struct __is_integer<unsigned int>
230     {
231       enum { __value = 1 };
232       typedef __true_type __type;
233     };
234
235   template<>
236     struct __is_integer<long>
237     {
238       enum { __value = 1 };
239       typedef __true_type __type;
240     };
241
242   template<>
243     struct __is_integer<unsigned long>
244     {
245       enum { __value = 1 };
246       typedef __true_type __type;
247     };
248
249   template<>
250     struct __is_integer<long long>
251     {
252       enum { __value = 1 };
253       typedef __true_type __type;
254     };
255
256   template<>
257     struct __is_integer<unsigned long long>
258     {
259       enum { __value = 1 };
260       typedef __true_type __type;
261     };
262
263   //
264   // Floating point types
265   //
266   template<typename _Tp>
267     struct __is_floating
268     {
269       enum { __value = 0 };
270       typedef __false_type __type;
271     };
272
273   // three specializations (float, double and 'long double')
274   template<>
275     struct __is_floating<float>
276     {
277       enum { __value = 1 };
278       typedef __true_type __type;
279     };
280
281   template<>
282     struct __is_floating<double>
283     {
284       enum { __value = 1 };
285       typedef __true_type __type;
286     };
287
288   template<>
289     struct __is_floating<long double>
290     {
291       enum { __value = 1 };
292       typedef __true_type __type;
293     };
294
295   //
296   // Pointer types
297   //
298   template<typename _Tp>
299     struct __is_pointer
300     {
301       enum { __value = 0 };
302       typedef __false_type __type;
303     };
304
305   template<typename _Tp>
306     struct __is_pointer<_Tp*>
307     {
308       enum { __value = 1 };
309       typedef __true_type __type;
310     };
311
312   //
313   // Normal iterator type
314   //
315   template<typename _Tp>
316     struct __is_normal_iterator
317     {
318       enum { __value = 0 };
319       typedef __false_type __type;
320     };
321
322   template<typename _Iterator, typename _Container>
323     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
324                                                               _Container> >
325     {
326       enum { __value = 1 };
327       typedef __true_type __type;
328     };
329
330   //
331   // An arithmetic type is an integer type or a floating point type
332   //
333   template<typename _Tp>
334     struct __is_arithmetic
335     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
336     { };
337
338   //
339   // A fundamental type is `void' or and arithmetic type
340   //
341   template<typename _Tp>
342     struct __is_fundamental
343     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
344     { };
345
346   //
347   // A scalar type is an arithmetic type or a pointer type
348   // 
349   template<typename _Tp>
350     struct __is_scalar
351     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
352     { };
353
354   //
355   // For the immediate use, the following is a good approximation
356   //
357   template<typename _Tp>
358     struct __is_pod
359     {
360       enum
361         {
362           __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))
363                      != sizeof(__gnu_internal::__one))
364         };
365     };
366
367   //
368   // A stripped-down version of std::tr1::is_empty
369   //
370   template<typename _Tp>
371     struct __is_empty
372     { 
373     private:
374       template<typename>
375         struct __first { };
376       template<typename _Up>
377         struct __second
378         : public _Up { };
379            
380     public:
381       enum
382         {
383           __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
384         };
385     };
386
387 } // namespace std
388
389 #endif //_CPP_TYPE_TRAITS_H