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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 // N.B. The conversions to bool are needed due to the issue
107 // explained in c++/19404.
108 template<class _Sp, class _Tp>
111 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
112 typedef typename __truth_type<__value>::__type __type;
115 // Compare for equality of types.
116 template<typename, typename>
119 enum { __value = 0 };
120 typedef __false_type __type;
123 template<typename _Tp>
124 struct __are_same<_Tp, _Tp>
126 enum { __value = 1 };
127 typedef __true_type __type;
130 // Define a nested type if some predicate holds.
131 template<typename, bool>
136 template<typename _Tp>
137 struct __enable_if<_Tp, true>
142 // Holds if the template-argument is a void type.
143 template<typename _Tp>
146 enum { __value = 0 };
147 typedef __false_type __type;
151 struct __is_void<void>
153 enum { __value = 1 };
154 typedef __true_type __type;
160 template<typename _Tp>
163 enum { __value = 0 };
164 typedef __false_type __type;
167 // Thirteen specializations (yes there are eleven standard integer
168 // types; 'long long' and 'unsigned long long' are supported as
171 struct __is_integer<bool>
173 enum { __value = 1 };
174 typedef __true_type __type;
178 struct __is_integer<char>
180 enum { __value = 1 };
181 typedef __true_type __type;
185 struct __is_integer<signed char>
187 enum { __value = 1 };
188 typedef __true_type __type;
192 struct __is_integer<unsigned char>
194 enum { __value = 1 };
195 typedef __true_type __type;
198 # ifdef _GLIBCXX_USE_WCHAR_T
200 struct __is_integer<wchar_t>
202 enum { __value = 1 };
203 typedef __true_type __type;
208 struct __is_integer<short>
210 enum { __value = 1 };
211 typedef __true_type __type;
215 struct __is_integer<unsigned short>
217 enum { __value = 1 };
218 typedef __true_type __type;
222 struct __is_integer<int>
224 enum { __value = 1 };
225 typedef __true_type __type;
229 struct __is_integer<unsigned int>
231 enum { __value = 1 };
232 typedef __true_type __type;
236 struct __is_integer<long>
238 enum { __value = 1 };
239 typedef __true_type __type;
243 struct __is_integer<unsigned long>
245 enum { __value = 1 };
246 typedef __true_type __type;
250 struct __is_integer<long long>
252 enum { __value = 1 };
253 typedef __true_type __type;
257 struct __is_integer<unsigned long long>
259 enum { __value = 1 };
260 typedef __true_type __type;
264 // Floating point types
266 template<typename _Tp>
269 enum { __value = 0 };
270 typedef __false_type __type;
273 // three specializations (float, double and 'long double')
275 struct __is_floating<float>
277 enum { __value = 1 };
278 typedef __true_type __type;
282 struct __is_floating<double>
284 enum { __value = 1 };
285 typedef __true_type __type;
289 struct __is_floating<long double>
291 enum { __value = 1 };
292 typedef __true_type __type;
298 template<typename _Tp>
301 enum { __value = 0 };
302 typedef __false_type __type;
305 template<typename _Tp>
306 struct __is_pointer<_Tp*>
308 enum { __value = 1 };
309 typedef __true_type __type;
313 // Normal iterator type
315 template<typename _Tp>
316 struct __is_normal_iterator
318 enum { __value = 0 };
319 typedef __false_type __type;
322 template<typename _Iterator, typename _Container>
323 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
326 enum { __value = 1 };
327 typedef __true_type __type;
331 // An arithmetic type is an integer type or a floating point type
333 template<typename _Tp>
334 struct __is_arithmetic
335 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
339 // A fundamental type is `void' or and arithmetic type
341 template<typename _Tp>
342 struct __is_fundamental
343 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
347 // A scalar type is an arithmetic type or a pointer type
349 template<typename _Tp>
351 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
355 // For the immediate use, the following is a good approximation
357 template<typename _Tp>
362 __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))
363 != sizeof(__gnu_internal::__one))
368 // A stripped-down version of std::tr1::is_empty
370 template<typename _Tp>
376 template<typename _Up>
383 __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
389 #endif //_CPP_TYPE_TRAITS_H