Merge from vendor branch GCC:
[dragonfly.git] / contrib / gcc-3.4 / 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 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
31
32 /** @file cpp_type_traits.h
33  *  This is an internal header file, included by other library headers.
34  *  You should not attempt to use it directly.
35  */
36
37 #ifndef _CPP_TYPE_TRAITS_H
38 #define _CPP_TYPE_TRAITS_H 1
39
40 #pragma GCC system_header
41
42 //
43 // This file provides some compile-time information about various types.
44 // These representations were designed, on purpose, to be constant-expressions
45 // and not types as found in <stl/bits/type_traits.h>.  In particular, they
46 // can be used in control structures and the optimizer hopefully will do
47 // the obvious thing.
48 //
49 // Why integral expressions, and not functions nor types?
50 // Firstly, these compile-time entities are used as template-arguments
51 // so function return values won't work:  We need compile-time entities.
52 // We're left with types and constant  integral expressions.
53 // Secondly, from the point of view of ease of use, type-based compile-time
54 // information is -not- *that* convenient.  On has to write lots of
55 // overloaded functions and to hope that the compiler will select the right
56 // one. As a net effect, the overall structure isn't very clear at first
57 // glance.
58 // Thirdly, partial ordering and overload resolution (of function templates)
59 // is highly costly in terms of compiler-resource.  It is a Good Thing to
60 // keep these resource consumption as least as possible.
61 //
62 // See valarray_array.h for a case use.
63 //
64 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
65 //
66
67 namespace std
68 {
69   // Compare for equality of types.
70   template<typename, typename>
71     struct __are_same
72     {
73       enum
74       {
75         _M_type = 0
76       };
77     };
78
79   template<typename _Tp>
80     struct __are_same<_Tp, _Tp>
81     {
82       enum
83       {
84         _M_type = 1
85       };
86     };
87
88   // Define a nested type if some predicate holds.
89   template<typename, bool>
90     struct __enable_if
91     {
92     };
93
94   template<typename _Tp>
95   struct __enable_if<_Tp, true>
96     {
97       typedef _Tp _M_type;
98     };
99
100   // Holds if the template-argument is a void type.
101   template<typename _Tp>
102     struct __is_void
103     {
104       enum
105       {
106         _M_type = 0
107       };
108     };
109
110   template<>
111     struct __is_void<void>
112     {
113       enum
114       {
115         _M_type = 1
116       };
117     };
118
119   //
120   // Integer types
121   //
122   template<typename _Tp>
123     struct __is_integer
124     {
125       enum
126       {
127         _M_type = 0
128       };
129     };
130
131   // Thirteen specializations (yes there are eleven standard integer
132   // types; 'long long' and 'unsigned long long' are supported as
133   // extensions)
134   template<>
135     struct __is_integer<bool>
136     {
137       enum
138       {
139         _M_type = 1
140       };
141     };
142
143   template<>
144     struct __is_integer<char>
145     {
146       enum
147       {
148         _M_type = 1
149       };
150     };
151
152   template<>
153     struct __is_integer<signed char>
154     {
155       enum
156       {
157         _M_type = 1
158       };
159     };
160
161   template<>
162   struct __is_integer<unsigned char>
163   {
164     enum
165     {
166       _M_type = 1
167     };
168   };
169
170 # ifdef _GLIBCXX_USE_WCHAR_T
171   template<>
172   struct __is_integer<wchar_t>
173   {
174     enum
175     {
176       _M_type = 1
177     };
178   };
179 # endif
180
181   template<>
182   struct __is_integer<short>
183   {
184     enum
185     {
186       _M_type = 1
187     };
188   };
189
190   template<>
191   struct __is_integer<unsigned short>
192   {
193     enum
194     {
195       _M_type = 1
196     };
197   };
198
199   template<>
200   struct __is_integer<int>
201   {
202     enum
203     {
204       _M_type = 1
205     };
206   };
207
208   template<>
209   struct __is_integer<unsigned int>
210   {
211     enum
212     {
213       _M_type = 1
214     };
215   };
216
217   template<>
218   struct __is_integer<long>
219   {
220     enum
221     {
222       _M_type = 1
223     };
224   };
225
226   template<>
227   struct __is_integer<unsigned long>
228   {
229     enum
230     {
231       _M_type = 1
232     };
233   };
234
235   template<>
236   struct __is_integer<long long>
237   {
238     enum
239     {
240       _M_type = 1
241     };
242   };
243
244   template<>
245   struct __is_integer<unsigned long long>
246   {
247     enum
248     {
249       _M_type = 1
250     };
251   };
252
253   //
254   // Floating point types
255   //
256   template<typename _Tp>
257   struct __is_floating
258   {
259     enum
260     {
261       _M_type = 0
262     };
263   };
264
265   // three specializations (float, double and 'long double')
266   template<>
267   struct __is_floating<float>
268   {
269     enum
270     {
271       _M_type = 1
272     };
273   };
274
275   template<>
276   struct __is_floating<double>
277   {
278     enum
279     {
280       _M_type = 1
281     };
282   };
283
284   template<>
285   struct __is_floating<long double>
286   {
287     enum
288     {
289       _M_type = 1
290     };
291   };
292
293   //
294   // An arithmetic type is an integer type or a floating point type
295   //
296   template<typename _Tp>
297   struct __is_arithmetic
298   {
299     enum
300     {
301       _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
302     };
303   };
304
305   //
306   // A fundamental type is `void' or and arithmetic type
307   //
308   template<typename _Tp>
309   struct __is_fundamental
310   {
311     enum
312     {
313       _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
314     };
315   };
316
317   //
318   // For the immediate use, the following is a good approximation
319   //
320
321   // NB: g++ can not compile these if declared within the class
322   // __is_pod itself.
323   namespace __gnu_internal
324   {
325     typedef char __one;
326     typedef char __two[2];
327
328     template <typename _Tp>
329     __one __test_type (int _Tp::*);
330     template <typename _Tp>
331     __two& __test_type (...);
332   }
333
334   
335   template<typename _Tp>
336   struct __is_pod
337   {
338     enum
339     {
340       _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0)) != sizeof(__gnu_internal::__one))
341     };
342   };
343
344 } // namespace std
345
346
347 #endif //_CPP_TYPE_TRAITS_H