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.
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)
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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
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
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
73 // NB: g++ can not compile these if declared within the class
75 namespace __gnu_internal
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.
89 template<typename _Iterator
, typename _Container
>
90 class __normal_iterator
;
91 } // namespace __gnu_cxx
93 struct __true_type
{ };
94 struct __false_type
{ };
100 { typedef __false_type __type
; };
103 struct __truth_type
<true>
104 { typedef __true_type __type
; };
106 template<class _Sp
, class _Tp
>
109 enum { __value
= _Sp::__value
|| _Tp::__value
};
110 typedef typename __truth_type
<__value
>::__type __type
;
113 // Compare for equality of types.
114 template<typename
, typename
>
117 enum { __value
= 0 };
118 typedef __false_type __type
;
121 template<typename _Tp
>
122 struct __are_same
<_Tp
, _Tp
>
124 enum { __value
= 1 };
125 typedef __true_type __type
;
128 // Define a nested type if some predicate holds.
129 template<typename
, bool>
134 template<typename _Tp
>
135 struct __enable_if
<_Tp
, true>
140 // Holds if the template-argument is a void type.
141 template<typename _Tp
>
144 enum { __value
= 0 };
145 typedef __false_type __type
;
149 struct __is_void
<void>
151 enum { __value
= 1 };
152 typedef __true_type __type
;
158 template<typename _Tp
>
161 enum { __value
= 0 };
162 typedef __false_type __type
;
165 // Thirteen specializations (yes there are eleven standard integer
166 // types; 'long long' and 'unsigned long long' are supported as
169 struct __is_integer
<bool>
171 enum { __value
= 1 };
172 typedef __true_type __type
;
176 struct __is_integer
<char>
178 enum { __value
= 1 };
179 typedef __true_type __type
;
183 struct __is_integer
<signed char>
185 enum { __value
= 1 };
186 typedef __true_type __type
;
190 struct __is_integer
<unsigned char>
192 enum { __value
= 1 };
193 typedef __true_type __type
;
196 # ifdef _GLIBCXX_USE_WCHAR_T
198 struct __is_integer
<wchar_t>
200 enum { __value
= 1 };
201 typedef __true_type __type
;
206 struct __is_integer
<short>
208 enum { __value
= 1 };
209 typedef __true_type __type
;
213 struct __is_integer
<unsigned short>
215 enum { __value
= 1 };
216 typedef __true_type __type
;
220 struct __is_integer
<int>
222 enum { __value
= 1 };
223 typedef __true_type __type
;
227 struct __is_integer
<unsigned int>
229 enum { __value
= 1 };
230 typedef __true_type __type
;
234 struct __is_integer
<long>
236 enum { __value
= 1 };
237 typedef __true_type __type
;
241 struct __is_integer
<unsigned long>
243 enum { __value
= 1 };
244 typedef __true_type __type
;
248 struct __is_integer
<long long>
250 enum { __value
= 1 };
251 typedef __true_type __type
;
255 struct __is_integer
<unsigned long long>
257 enum { __value
= 1 };
258 typedef __true_type __type
;
262 // Floating point types
264 template<typename _Tp
>
267 enum { __value
= 0 };
268 typedef __false_type __type
;
271 // three specializations (float, double and 'long double')
273 struct __is_floating
<float>
275 enum { __value
= 1 };
276 typedef __true_type __type
;
280 struct __is_floating
<double>
282 enum { __value
= 1 };
283 typedef __true_type __type
;
287 struct __is_floating
<long double>
289 enum { __value
= 1 };
290 typedef __true_type __type
;
296 template<typename _Tp
>
299 enum { __value
= 0 };
300 typedef __false_type __type
;
303 template<typename _Tp
>
304 struct __is_pointer
<_Tp
*>
306 enum { __value
= 1 };
307 typedef __true_type __type
;
311 // Normal iterator type
313 template<typename _Tp
>
314 struct __is_normal_iterator
316 enum { __value
= 0 };
317 typedef __false_type __type
;
320 template<typename _Iterator
, typename _Container
>
321 struct __is_normal_iterator
< __gnu_cxx::__normal_iterator
<_Iterator
,
324 enum { __value
= 1 };
325 typedef __true_type __type
;
329 // An arithmetic type is an integer type or a floating point type
331 template<typename _Tp
>
332 struct __is_arithmetic
333 : public __traitor
<__is_integer
<_Tp
>, __is_floating
<_Tp
> >
337 // A fundamental type is `void' or and arithmetic type
339 template<typename _Tp
>
340 struct __is_fundamental
341 : public __traitor
<__is_void
<_Tp
>, __is_arithmetic
<_Tp
> >
345 // A scalar type is an arithmetic type or a pointer type
347 template<typename _Tp
>
349 : public __traitor
<__is_arithmetic
<_Tp
>, __is_pointer
<_Tp
> >
353 // For the immediate use, the following is a good approximation
355 template<typename _Tp
>
360 __value
= (sizeof(__gnu_internal::__test_type
<_Tp
>(0))
361 != sizeof(__gnu_internal::__one
))
367 #endif //_CPP_TYPE_TRAITS_H