2005-12-18 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / include / bits / cpp_type_traits.h
blobe75bf47f08b6ad8486c95b5efece21e340d2e911
1 // The -*- C++ -*- type traits classes for internal use in libstdc++
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.
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.
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.
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.
31 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
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.
38 #ifndef _CPP_TYPE_TRAITS_H
39 #define _CPP_TYPE_TRAITS_H 1
41 #pragma GCC system_header
43 #include <bits/c++config.h>
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.
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.
65 // See valarray_array.h for a case use.
67 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
69 // Update 2005: types are also provided and <bits/type_traits.h> has been
70 // removed.
73 // NB: g++ can not compile these if declared within the class
74 // __is_pod itself.
75 namespace __gnu_internal
77 typedef char __one;
78 typedef char __two[2];
80 template<typename _Tp>
81 __one __test_type(int _Tp::*);
82 template<typename _Tp>
83 __two& __test_type(...);
84 } // namespace __gnu_internal
86 // Forward declaration hack, should really include this from somewhere.
87 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
89 template<typename _Iterator, typename _Container>
90 class __normal_iterator;
92 _GLIBCXX_END_NAMESPACE
94 struct __true_type { };
95 struct __false_type { };
97 _GLIBCXX_BEGIN_NAMESPACE(std)
99 template<bool>
100 struct __truth_type
101 { typedef __false_type __type; };
103 template<>
104 struct __truth_type<true>
105 { typedef __true_type __type; };
107 // N.B. The conversions to bool are needed due to the issue
108 // explained in c++/19404.
109 template<class _Sp, class _Tp>
110 struct __traitor
112 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
113 typedef typename __truth_type<__value>::__type __type;
116 // Compare for equality of types.
117 template<typename, typename>
118 struct __are_same
120 enum { __value = 0 };
121 typedef __false_type __type;
124 template<typename _Tp>
125 struct __are_same<_Tp, _Tp>
127 enum { __value = 1 };
128 typedef __true_type __type;
131 // Define a nested type if some predicate holds.
132 template<typename, bool>
133 struct __enable_if
137 template<typename _Tp>
138 struct __enable_if<_Tp, true>
140 typedef _Tp __type;
143 // Holds if the template-argument is a void type.
144 template<typename _Tp>
145 struct __is_void
147 enum { __value = 0 };
148 typedef __false_type __type;
151 template<>
152 struct __is_void<void>
154 enum { __value = 1 };
155 typedef __true_type __type;
159 // Integer types
161 template<typename _Tp>
162 struct __is_integer
164 enum { __value = 0 };
165 typedef __false_type __type;
168 // Thirteen specializations (yes there are eleven standard integer
169 // types; 'long long' and 'unsigned long long' are supported as
170 // extensions)
171 template<>
172 struct __is_integer<bool>
174 enum { __value = 1 };
175 typedef __true_type __type;
178 template<>
179 struct __is_integer<char>
181 enum { __value = 1 };
182 typedef __true_type __type;
185 template<>
186 struct __is_integer<signed char>
188 enum { __value = 1 };
189 typedef __true_type __type;
192 template<>
193 struct __is_integer<unsigned char>
195 enum { __value = 1 };
196 typedef __true_type __type;
199 # ifdef _GLIBCXX_USE_WCHAR_T
200 template<>
201 struct __is_integer<wchar_t>
203 enum { __value = 1 };
204 typedef __true_type __type;
206 # endif
208 template<>
209 struct __is_integer<short>
211 enum { __value = 1 };
212 typedef __true_type __type;
215 template<>
216 struct __is_integer<unsigned short>
218 enum { __value = 1 };
219 typedef __true_type __type;
222 template<>
223 struct __is_integer<int>
225 enum { __value = 1 };
226 typedef __true_type __type;
229 template<>
230 struct __is_integer<unsigned int>
232 enum { __value = 1 };
233 typedef __true_type __type;
236 template<>
237 struct __is_integer<long>
239 enum { __value = 1 };
240 typedef __true_type __type;
243 template<>
244 struct __is_integer<unsigned long>
246 enum { __value = 1 };
247 typedef __true_type __type;
250 template<>
251 struct __is_integer<long long>
253 enum { __value = 1 };
254 typedef __true_type __type;
257 template<>
258 struct __is_integer<unsigned long long>
260 enum { __value = 1 };
261 typedef __true_type __type;
265 // Floating point types
267 template<typename _Tp>
268 struct __is_floating
270 enum { __value = 0 };
271 typedef __false_type __type;
274 // three specializations (float, double and 'long double')
275 template<>
276 struct __is_floating<float>
278 enum { __value = 1 };
279 typedef __true_type __type;
282 template<>
283 struct __is_floating<double>
285 enum { __value = 1 };
286 typedef __true_type __type;
289 template<>
290 struct __is_floating<long double>
292 enum { __value = 1 };
293 typedef __true_type __type;
297 // Pointer types
299 template<typename _Tp>
300 struct __is_pointer
302 enum { __value = 0 };
303 typedef __false_type __type;
306 template<typename _Tp>
307 struct __is_pointer<_Tp*>
309 enum { __value = 1 };
310 typedef __true_type __type;
314 // Normal iterator type
316 template<typename _Tp>
317 struct __is_normal_iterator
319 enum { __value = 0 };
320 typedef __false_type __type;
323 template<typename _Iterator, typename _Container>
324 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
325 _Container> >
327 enum { __value = 1 };
328 typedef __true_type __type;
332 // An arithmetic type is an integer type or a floating point type
334 template<typename _Tp>
335 struct __is_arithmetic
336 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
337 { };
340 // A fundamental type is `void' or and arithmetic type
342 template<typename _Tp>
343 struct __is_fundamental
344 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
345 { };
348 // A scalar type is an arithmetic type or a pointer type
350 template<typename _Tp>
351 struct __is_scalar
352 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
353 { };
356 // For the immediate use, the following is a good approximation
358 template<typename _Tp>
359 struct __is_pod
361 enum
363 __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))
364 != sizeof(__gnu_internal::__one))
369 // A stripped-down version of std::tr1::is_empty
371 template<typename _Tp>
372 struct __is_empty
374 private:
375 template<typename>
376 struct __first { };
377 template<typename _Up>
378 struct __second
379 : public _Up { };
381 public:
382 enum
384 __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
388 _GLIBCXX_END_NAMESPACE
390 #endif //_CPP_TYPE_TRAITS_H