OSDN Git Service

8e436dd682b08e96591a7d83faac556f0dad3063
[pf3gnuchains/gcc-fork.git] / 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, 2006
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 // Forward declaration hack, should really include this from somewhere.
74 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75
76   template<typename _Iterator, typename _Container>
77     class __normal_iterator;
78
79 _GLIBCXX_END_NAMESPACE
80
81 _GLIBCXX_BEGIN_NAMESPACE(std)
82
83 namespace __detail
84 {
85   // NB: g++ can not compile these if declared within the class
86   // __is_pod itself.
87   typedef char __one;
88   typedef char __two[2];
89
90   template<typename _Tp>
91   __one __test_type(int _Tp::*);
92   template<typename _Tp>
93   __two& __test_type(...);
94 } // namespace __detail
95
96
97   struct __true_type { };
98   struct __false_type { };
99
100   template<bool>
101     struct __truth_type
102     { typedef __false_type __type; };
103
104   template<>
105     struct __truth_type<true>
106     { typedef __true_type __type; };
107
108   // N.B. The conversions to bool are needed due to the issue
109   // explained in c++/19404.
110   template<class _Sp, class _Tp>
111     struct __traitor
112     {
113       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
114       typedef typename __truth_type<__value>::__type __type;
115     };
116
117   // Compare for equality of types.
118   template<typename, typename>
119     struct __are_same
120     {
121       enum { __value = 0 };
122       typedef __false_type __type;
123     };
124
125   template<typename _Tp>
126     struct __are_same<_Tp, _Tp>
127     {
128       enum { __value = 1 };
129       typedef __true_type __type;
130     };
131
132   // Holds if the template-argument is a void type.
133   template<typename _Tp>
134     struct __is_void
135     {
136       enum { __value = 0 };
137       typedef __false_type __type;
138     };
139
140   template<>
141     struct __is_void<void>
142     {
143       enum { __value = 1 };
144       typedef __true_type __type;
145     };
146
147   //
148   // Integer types
149   //
150   template<typename _Tp>
151     struct __is_integer
152     {
153       enum { __value = 0 };
154       typedef __false_type __type;
155     };
156
157   // Thirteen specializations (yes there are eleven standard integer
158   // types; 'long long' and 'unsigned long long' are supported as
159   // extensions)
160   template<>
161     struct __is_integer<bool>
162     {
163       enum { __value = 1 };
164       typedef __true_type __type;
165     };
166
167   template<>
168     struct __is_integer<char>
169     {
170       enum { __value = 1 };
171       typedef __true_type __type;
172     };
173
174   template<>
175     struct __is_integer<signed char>
176     {
177       enum { __value = 1 };
178       typedef __true_type __type;
179     };
180
181   template<>
182     struct __is_integer<unsigned char>
183     {
184       enum { __value = 1 };
185       typedef __true_type __type;
186     };
187
188 # ifdef _GLIBCXX_USE_WCHAR_T
189   template<>
190     struct __is_integer<wchar_t>
191     {
192       enum { __value = 1 };
193       typedef __true_type __type;
194     };
195 # endif
196
197   template<>
198     struct __is_integer<short>
199     {
200       enum { __value = 1 };
201       typedef __true_type __type;
202     };
203
204   template<>
205     struct __is_integer<unsigned short>
206     {
207       enum { __value = 1 };
208       typedef __true_type __type;
209     };
210
211   template<>
212     struct __is_integer<int>
213     {
214       enum { __value = 1 };
215       typedef __true_type __type;
216     };
217
218   template<>
219     struct __is_integer<unsigned int>
220     {
221       enum { __value = 1 };
222       typedef __true_type __type;
223     };
224
225   template<>
226     struct __is_integer<long>
227     {
228       enum { __value = 1 };
229       typedef __true_type __type;
230     };
231
232   template<>
233     struct __is_integer<unsigned long>
234     {
235       enum { __value = 1 };
236       typedef __true_type __type;
237     };
238
239   template<>
240     struct __is_integer<long long>
241     {
242       enum { __value = 1 };
243       typedef __true_type __type;
244     };
245
246   template<>
247     struct __is_integer<unsigned long long>
248     {
249       enum { __value = 1 };
250       typedef __true_type __type;
251     };
252
253   //
254   // Floating point types
255   //
256   template<typename _Tp>
257     struct __is_floating
258     {
259       enum { __value = 0 };
260       typedef __false_type __type;
261     };
262
263   // three specializations (float, double and 'long double')
264   template<>
265     struct __is_floating<float>
266     {
267       enum { __value = 1 };
268       typedef __true_type __type;
269     };
270
271   template<>
272     struct __is_floating<double>
273     {
274       enum { __value = 1 };
275       typedef __true_type __type;
276     };
277
278   template<>
279     struct __is_floating<long double>
280     {
281       enum { __value = 1 };
282       typedef __true_type __type;
283     };
284
285   //
286   // Pointer types
287   //
288   template<typename _Tp>
289     struct __is_pointer
290     {
291       enum { __value = 0 };
292       typedef __false_type __type;
293     };
294
295   template<typename _Tp>
296     struct __is_pointer<_Tp*>
297     {
298       enum { __value = 1 };
299       typedef __true_type __type;
300     };
301
302   //
303   // Normal iterator type
304   //
305   template<typename _Tp>
306     struct __is_normal_iterator
307     {
308       enum { __value = 0 };
309       typedef __false_type __type;
310     };
311
312   template<typename _Iterator, typename _Container>
313     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
314                                                               _Container> >
315     {
316       enum { __value = 1 };
317       typedef __true_type __type;
318     };
319
320   //
321   // An arithmetic type is an integer type or a floating point type
322   //
323   template<typename _Tp>
324     struct __is_arithmetic
325     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
326     { };
327
328   //
329   // A fundamental type is `void' or and arithmetic type
330   //
331   template<typename _Tp>
332     struct __is_fundamental
333     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
334     { };
335
336   //
337   // A scalar type is an arithmetic type or a pointer type
338   // 
339   template<typename _Tp>
340     struct __is_scalar
341     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
342     { };
343
344   // For the immediate use, the following is a good approximation.
345   template<typename _Tp>
346     struct __is_pod
347     {
348       enum
349         {
350           __value = (sizeof(__detail::__test_type<_Tp>(0))
351                      != sizeof(__detail::__one))
352         };
353     };
354
355   //
356   // A stripped-down version of std::tr1::is_empty
357   //
358   template<typename _Tp>
359     struct __is_empty
360     { 
361     private:
362       template<typename>
363         struct __first { };
364       template<typename _Up>
365         struct __second
366         : public _Up { };
367            
368     public:
369       enum
370         {
371           __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
372         };
373     };
374
375   //
376   // For use in std::copy and std::find overloads for streambuf iterators.
377   //
378   template<typename _Tp>
379     struct __is_char
380     {
381       enum { __value = 0 };
382       typedef __false_type __type;
383     };
384
385   template<>
386     struct __is_char<char>
387     {
388       enum { __value = 1 };
389       typedef __true_type __type;
390     };
391
392 #ifdef _GLIBCXX_USE_WCHAR_T
393   template<>
394     struct __is_char<wchar_t>
395     {
396       enum { __value = 1 };
397       typedef __true_type __type;
398     };
399 #endif
400
401 _GLIBCXX_END_NAMESPACE
402
403 #endif //_CPP_TYPE_TRAITS_H