1 // The -*- C++ -*- type traits classes for internal use in libstdc++
3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
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 /** @file cpp_type_traits.h
32 * This is an internal header file, included by other library headers.
33 * You should not attempt to use it directly.
36 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
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 // Forward declaration hack, should really include this from somewhere.
74 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
76 template<typename _Iterator, typename _Container>
77 class __normal_iterator;
79 _GLIBCXX_END_NAMESPACE
81 _GLIBCXX_BEGIN_NAMESPACE(std)
85 // NB: g++ can not compile these if declared within the class
88 typedef char __two[2];
90 template<typename _Tp>
91 __one __test_type(int _Tp::*);
92 template<typename _Tp>
93 __two& __test_type(...);
94 } // namespace __detail
97 struct __true_type { };
98 struct __false_type { };
102 { typedef __false_type __type; };
105 struct __truth_type<true>
106 { typedef __true_type __type; };
108 // N.B. The conversions to bool are needed due to the issue
109 // explained in c++/19404.
110 template<class _Sp, class _Tp>
113 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
114 typedef typename __truth_type<__value>::__type __type;
117 // Compare for equality of types.
118 template<typename, typename>
121 enum { __value = 0 };
122 typedef __false_type __type;
125 template<typename _Tp>
126 struct __are_same<_Tp, _Tp>
128 enum { __value = 1 };
129 typedef __true_type __type;
132 // Holds if the template-argument is a void type.
133 template<typename _Tp>
136 enum { __value = 0 };
137 typedef __false_type __type;
141 struct __is_void<void>
143 enum { __value = 1 };
144 typedef __true_type __type;
150 template<typename _Tp>
153 enum { __value = 0 };
154 typedef __false_type __type;
157 // Thirteen specializations (yes there are eleven standard integer
158 // types; 'long long' and 'unsigned long long' are supported as
161 struct __is_integer<bool>
163 enum { __value = 1 };
164 typedef __true_type __type;
168 struct __is_integer<char>
170 enum { __value = 1 };
171 typedef __true_type __type;
175 struct __is_integer<signed char>
177 enum { __value = 1 };
178 typedef __true_type __type;
182 struct __is_integer<unsigned char>
184 enum { __value = 1 };
185 typedef __true_type __type;
188 # ifdef _GLIBCXX_USE_WCHAR_T
190 struct __is_integer<wchar_t>
192 enum { __value = 1 };
193 typedef __true_type __type;
198 struct __is_integer<short>
200 enum { __value = 1 };
201 typedef __true_type __type;
205 struct __is_integer<unsigned short>
207 enum { __value = 1 };
208 typedef __true_type __type;
212 struct __is_integer<int>
214 enum { __value = 1 };
215 typedef __true_type __type;
219 struct __is_integer<unsigned int>
221 enum { __value = 1 };
222 typedef __true_type __type;
226 struct __is_integer<long>
228 enum { __value = 1 };
229 typedef __true_type __type;
233 struct __is_integer<unsigned long>
235 enum { __value = 1 };
236 typedef __true_type __type;
240 struct __is_integer<long long>
242 enum { __value = 1 };
243 typedef __true_type __type;
247 struct __is_integer<unsigned long long>
249 enum { __value = 1 };
250 typedef __true_type __type;
254 // Floating point types
256 template<typename _Tp>
259 enum { __value = 0 };
260 typedef __false_type __type;
263 // three specializations (float, double and 'long double')
265 struct __is_floating<float>
267 enum { __value = 1 };
268 typedef __true_type __type;
272 struct __is_floating<double>
274 enum { __value = 1 };
275 typedef __true_type __type;
279 struct __is_floating<long double>
281 enum { __value = 1 };
282 typedef __true_type __type;
288 template<typename _Tp>
291 enum { __value = 0 };
292 typedef __false_type __type;
295 template<typename _Tp>
296 struct __is_pointer<_Tp*>
298 enum { __value = 1 };
299 typedef __true_type __type;
303 // Normal iterator type
305 template<typename _Tp>
306 struct __is_normal_iterator
308 enum { __value = 0 };
309 typedef __false_type __type;
312 template<typename _Iterator, typename _Container>
313 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
316 enum { __value = 1 };
317 typedef __true_type __type;
321 // An arithmetic type is an integer type or a floating point type
323 template<typename _Tp>
324 struct __is_arithmetic
325 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
329 // A fundamental type is `void' or and arithmetic type
331 template<typename _Tp>
332 struct __is_fundamental
333 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
337 // A scalar type is an arithmetic type or a pointer type
339 template<typename _Tp>
341 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
344 // For the immediate use, the following is a good approximation.
345 template<typename _Tp>
350 __value = (sizeof(__detail::__test_type<_Tp>(0))
351 != sizeof(__detail::__one))
356 // A stripped-down version of std::tr1::is_empty
358 template<typename _Tp>
364 template<typename _Up>
371 __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
376 // For use in std::copy and std::find overloads for streambuf iterators.
378 template<typename _Tp>
381 enum { __value = 0 };
382 typedef __false_type __type;
386 struct __is_char<char>
388 enum { __value = 1 };
389 typedef __true_type __type;
392 #ifdef _GLIBCXX_USE_WCHAR_T
394 struct __is_char<wchar_t>
396 enum { __value = 1 };
397 typedef __true_type __type;
401 _GLIBCXX_END_NAMESPACE
403 #endif //_CPP_TYPE_TRAITS_H