Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[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, 2004 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 // NB: g++ can not compile these if declared within the class
68 // __is_pod itself.
69 namespace __gnu_internal
70 {
71   typedef char __one;
72   typedef char __two[2];
73
74   template <typename _Tp>
75   __one __test_type (int _Tp::*);
76   template <typename _Tp>
77   __two& __test_type (...);
78 } // namespace __gnu_internal
79
80 namespace std
81 {
82   // Compare for equality of types.
83   template<typename, typename>
84     struct __are_same
85     {
86       enum
87         {
88           _M_type = 0
89         };
90     };
91
92   template<typename _Tp>
93     struct __are_same<_Tp, _Tp>
94     {
95       enum
96         {
97           _M_type = 1
98         };
99     };
100
101   // Define a nested type if some predicate holds.
102   template<typename, bool>
103     struct __enable_if
104     {
105     };
106
107   template<typename _Tp>
108     struct __enable_if<_Tp, true>
109     {
110       typedef _Tp _M_type;
111     };
112
113   // Holds if the template-argument is a void type.
114   template<typename _Tp>
115     struct __is_void
116     {
117       enum
118         {
119           _M_type = 0
120         };
121     };
122
123   template<>
124     struct __is_void<void>
125     {
126       enum
127         {
128           _M_type = 1
129         };
130     };
131
132   //
133   // Integer types
134   //
135   template<typename _Tp>
136     struct __is_integer
137     {
138       enum
139         {
140           _M_type = 0
141         };
142     };
143
144   // Thirteen specializations (yes there are eleven standard integer
145   // types; 'long long' and 'unsigned long long' are supported as
146   // extensions)
147   template<>
148     struct __is_integer<bool>
149     {
150       enum
151         {
152           _M_type = 1
153         };
154     };
155
156   template<>
157     struct __is_integer<char>
158     {
159       enum
160         {
161           _M_type = 1
162         };
163     };
164
165   template<>
166     struct __is_integer<signed char>
167     {
168       enum
169         {
170           _M_type = 1
171         };
172     };
173
174   template<>
175     struct __is_integer<unsigned char>
176     {
177       enum
178         {
179           _M_type = 1
180         };
181     };
182
183 # ifdef _GLIBCXX_USE_WCHAR_T
184   template<>
185     struct __is_integer<wchar_t>
186     {
187       enum
188         {
189           _M_type = 1
190         };
191     };
192 # endif
193
194   template<>
195     struct __is_integer<short>
196     {
197       enum
198         {
199           _M_type = 1
200         };
201     };
202
203   template<>
204     struct __is_integer<unsigned short>
205     {
206       enum
207         {
208           _M_type = 1
209         };
210     };
211
212   template<>
213     struct __is_integer<int>
214     {
215       enum
216         {
217           _M_type = 1
218         };
219     };
220
221   template<>
222     struct __is_integer<unsigned int>
223     {
224       enum
225         {
226           _M_type = 1
227         };
228     };
229
230   template<>
231     struct __is_integer<long>
232     {
233       enum
234         {
235           _M_type = 1
236         };
237     };
238
239   template<>
240     struct __is_integer<unsigned long>
241     {
242       enum
243         {
244           _M_type = 1
245         };
246     };
247
248   template<>
249     struct __is_integer<long long>
250     {
251       enum
252         {
253           _M_type = 1
254         };
255     };
256
257   template<>
258     struct __is_integer<unsigned long long>
259     {
260       enum
261         {
262           _M_type = 1
263         };
264     };
265
266   //
267   // Floating point types
268   //
269   template<typename _Tp>
270     struct __is_floating
271     {
272       enum
273         {
274           _M_type = 0
275         };
276     };
277
278   // three specializations (float, double and 'long double')
279   template<>
280     struct __is_floating<float>
281     {
282       enum
283         {
284           _M_type = 1
285         };
286     };
287
288   template<>
289     struct __is_floating<double>
290     {
291       enum
292         {
293           _M_type = 1
294         };
295     };
296
297   template<>
298     struct __is_floating<long double>
299     {
300       enum
301         {
302           _M_type = 1
303         };
304     };
305
306   //
307   // An arithmetic type is an integer type or a floating point type
308   //
309   template<typename _Tp>
310     struct __is_arithmetic
311     {
312       enum
313         {
314           _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
315         };
316     };
317   
318   //
319   // A fundamental type is `void' or and arithmetic type
320   //
321   template<typename _Tp>
322     struct __is_fundamental
323     {
324       enum
325         {
326           _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
327         };
328     };
329
330   //
331   // For the immediate use, the following is a good approximation
332   //
333   template<typename _Tp>
334     struct __is_pod
335     {
336       enum
337         {
338           _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0))
339                      != sizeof(__gnu_internal::__one))
340         };
341     };
342
343 } // namespace std
344
345 #endif //_CPP_TYPE_TRAITS_H