OSDN Git Service

2010-05-06 Jonathan Wakely <jwakely.gcc@gmail.com>
[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, 2007, 2009, 2010
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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /** @file cpp_type_traits.h
27  *  This is an internal header file, included by other library headers.
28  *  You should not attempt to use it directly.
29  */
30
31 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
32
33 #ifndef _CPP_TYPE_TRAITS_H
34 #define _CPP_TYPE_TRAITS_H 1
35
36 #pragma GCC system_header
37
38 #include <bits/c++config.h>
39
40 //
41 // This file provides some compile-time information about various types.
42 // These representations were designed, on purpose, to be constant-expressions
43 // and not types as found in <bits/type_traits.h>.  In particular, they
44 // can be used in control structures and the optimizer hopefully will do
45 // the obvious thing.
46 //
47 // Why integral expressions, and not functions nor types?
48 // Firstly, these compile-time entities are used as template-arguments
49 // so function return values won't work:  We need compile-time entities.
50 // We're left with types and constant  integral expressions.
51 // Secondly, from the point of view of ease of use, type-based compile-time
52 // information is -not- *that* convenient.  On has to write lots of
53 // overloaded functions and to hope that the compiler will select the right
54 // one. As a net effect, the overall structure isn't very clear at first
55 // glance.
56 // Thirdly, partial ordering and overload resolution (of function templates)
57 // is highly costly in terms of compiler-resource.  It is a Good Thing to
58 // keep these resource consumption as least as possible.
59 //
60 // See valarray_array.h for a case use.
61 //
62 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
63 //
64 // Update 2005: types are also provided and <bits/type_traits.h> has been
65 // removed.
66 //
67
68 // Forward declaration hack, should really include this from somewhere.
69 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
70
71   template<typename _Iterator, typename _Container>
72     class __normal_iterator;
73
74 _GLIBCXX_END_NAMESPACE
75
76 _GLIBCXX_BEGIN_NAMESPACE(std)
77
78   struct __true_type { };
79   struct __false_type { };
80
81   template<bool>
82     struct __truth_type
83     { typedef __false_type __type; };
84
85   template<>
86     struct __truth_type<true>
87     { typedef __true_type __type; };
88
89   // N.B. The conversions to bool are needed due to the issue
90   // explained in c++/19404.
91   template<class _Sp, class _Tp>
92     struct __traitor
93     {
94       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
95       typedef typename __truth_type<__value>::__type __type;
96     };
97
98   // Compare for equality of types.
99   template<typename, typename>
100     struct __are_same
101     {
102       enum { __value = 0 };
103       typedef __false_type __type;
104     };
105
106   template<typename _Tp>
107     struct __are_same<_Tp, _Tp>
108     {
109       enum { __value = 1 };
110       typedef __true_type __type;
111     };
112
113   // Holds if the template-argument is a void type.
114   template<typename _Tp>
115     struct __is_void
116     {
117       enum { __value = 0 };
118       typedef __false_type __type;
119     };
120
121   template<>
122     struct __is_void<void>
123     {
124       enum { __value = 1 };
125       typedef __true_type __type;
126     };
127
128   //
129   // Integer types
130   //
131   template<typename _Tp>
132     struct __is_integer
133     {
134       enum { __value = 0 };
135       typedef __false_type __type;
136     };
137
138   // Thirteen specializations (yes there are eleven standard integer
139   // types; <em>long long</em> and <em>unsigned long long</em> are
140   // supported as extensions)
141   template<>
142     struct __is_integer<bool>
143     {
144       enum { __value = 1 };
145       typedef __true_type __type;
146     };
147
148   template<>
149     struct __is_integer<char>
150     {
151       enum { __value = 1 };
152       typedef __true_type __type;
153     };
154
155   template<>
156     struct __is_integer<signed char>
157     {
158       enum { __value = 1 };
159       typedef __true_type __type;
160     };
161
162   template<>
163     struct __is_integer<unsigned char>
164     {
165       enum { __value = 1 };
166       typedef __true_type __type;
167     };
168
169 # ifdef _GLIBCXX_USE_WCHAR_T
170   template<>
171     struct __is_integer<wchar_t>
172     {
173       enum { __value = 1 };
174       typedef __true_type __type;
175     };
176 # endif
177
178 #ifdef __GXX_EXPERIMENTAL_CXX0X__
179   template<>
180     struct __is_integer<char16_t>
181     {
182       enum { __value = 1 };
183       typedef __true_type __type;
184     };
185
186   template<>
187     struct __is_integer<char32_t>
188     {
189       enum { __value = 1 };
190       typedef __true_type __type;
191     };
192 #endif
193
194   template<>
195     struct __is_integer<short>
196     {
197       enum { __value = 1 };
198       typedef __true_type __type;
199     };
200
201   template<>
202     struct __is_integer<unsigned short>
203     {
204       enum { __value = 1 };
205       typedef __true_type __type;
206     };
207
208   template<>
209     struct __is_integer<int>
210     {
211       enum { __value = 1 };
212       typedef __true_type __type;
213     };
214
215   template<>
216     struct __is_integer<unsigned int>
217     {
218       enum { __value = 1 };
219       typedef __true_type __type;
220     };
221
222   template<>
223     struct __is_integer<long>
224     {
225       enum { __value = 1 };
226       typedef __true_type __type;
227     };
228
229   template<>
230     struct __is_integer<unsigned long>
231     {
232       enum { __value = 1 };
233       typedef __true_type __type;
234     };
235
236   template<>
237     struct __is_integer<long long>
238     {
239       enum { __value = 1 };
240       typedef __true_type __type;
241     };
242
243   template<>
244     struct __is_integer<unsigned long long>
245     {
246       enum { __value = 1 };
247       typedef __true_type __type;
248     };
249
250   //
251   // Floating point types
252   //
253   template<typename _Tp>
254     struct __is_floating
255     {
256       enum { __value = 0 };
257       typedef __false_type __type;
258     };
259
260   // three specializations (float, double and 'long double')
261   template<>
262     struct __is_floating<float>
263     {
264       enum { __value = 1 };
265       typedef __true_type __type;
266     };
267
268   template<>
269     struct __is_floating<double>
270     {
271       enum { __value = 1 };
272       typedef __true_type __type;
273     };
274
275   template<>
276     struct __is_floating<long double>
277     {
278       enum { __value = 1 };
279       typedef __true_type __type;
280     };
281
282   //
283   // Pointer types
284   //
285   template<typename _Tp>
286     struct __is_pointer
287     {
288       enum { __value = 0 };
289       typedef __false_type __type;
290     };
291
292   template<typename _Tp>
293     struct __is_pointer<_Tp*>
294     {
295       enum { __value = 1 };
296       typedef __true_type __type;
297     };
298
299   //
300   // Normal iterator type
301   //
302   template<typename _Tp>
303     struct __is_normal_iterator
304     {
305       enum { __value = 0 };
306       typedef __false_type __type;
307     };
308
309   template<typename _Iterator, typename _Container>
310     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
311                                                               _Container> >
312     {
313       enum { __value = 1 };
314       typedef __true_type __type;
315     };
316
317   //
318   // An arithmetic type is an integer type or a floating point type
319   //
320   template<typename _Tp>
321     struct __is_arithmetic
322     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
323     { };
324
325   //
326   // A fundamental type is `void' or and arithmetic type
327   //
328   template<typename _Tp>
329     struct __is_fundamental
330     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
331     { };
332
333   //
334   // A scalar type is an arithmetic type or a pointer type
335   // 
336   template<typename _Tp>
337     struct __is_scalar
338     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
339     { };
340
341   //
342   // For use in std::copy and std::find overloads for streambuf iterators.
343   //
344   template<typename _Tp>
345     struct __is_char
346     {
347       enum { __value = 0 };
348       typedef __false_type __type;
349     };
350
351   template<>
352     struct __is_char<char>
353     {
354       enum { __value = 1 };
355       typedef __true_type __type;
356     };
357
358 #ifdef _GLIBCXX_USE_WCHAR_T
359   template<>
360     struct __is_char<wchar_t>
361     {
362       enum { __value = 1 };
363       typedef __true_type __type;
364     };
365 #endif
366
367   template<typename _Tp>
368     struct __is_byte
369     {
370       enum { __value = 0 };
371       typedef __false_type __type;
372     };
373
374   template<>
375     struct __is_byte<char>
376     {
377       enum { __value = 1 };
378       typedef __true_type __type;
379     };
380
381   template<>
382     struct __is_byte<signed char>
383     {
384       enum { __value = 1 };
385       typedef __true_type __type;
386     };
387
388   template<>
389     struct __is_byte<unsigned char>
390     {
391       enum { __value = 1 };
392       typedef __true_type __type;
393     };
394
395   //
396   // Move iterator type
397   //
398   template<typename _Tp>
399     struct __is_move_iterator
400     {
401       enum { __value = 0 };
402       typedef __false_type __type;
403     };
404
405 #ifdef __GXX_EXPERIMENTAL_CXX0X__
406   template<typename _Iterator>
407     class move_iterator;
408
409   template<typename _Iterator>
410     struct __is_move_iterator< move_iterator<_Iterator> >
411     {
412       enum { __value = 1 };
413       typedef __true_type __type;
414     };
415 #endif
416
417 _GLIBCXX_END_NAMESPACE
418
419 #endif //_CPP_TYPE_TRAITS_H