1 // The -*- C++ -*- type traits classes for internal use in libstdc++
2
3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
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.
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 // 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.
21
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.
30
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.
34 */
35
36 // Written by Gabriel Dos Reis <[email protected]>
37
38 #ifndef _CPP_TYPE_TRAITS_H
39 #define _CPP_TYPE_TRAITS_H 1
40
41 #pragma GCC system_header
42
43 #include <bits/c++config.h>
44
45 //
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.
51 //
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.
64 //
65 // See valarray_array.h for a case use.
66 //
67 // -- Gaby ([email protected]) 2000-03-06.
68 //
69 // Update 2005: types are also provided and <bits/type_traits.h> has been
70 // removed.
71 //
72
73 // Forward declaration hack, should really include this from somewhere.
74 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75
76 template<typename _Iterator, typename _Container>
77 class __normal_iterator;
78
79 _GLIBCXX_END_NAMESPACE
80
_GLIBCXX_BEGIN_NAMESPACE(std)81 _GLIBCXX_BEGIN_NAMESPACE(std)
82
83 #ifdef __clang__
84 // When using clang, suppress warnings about possible keywords (such as
85 // __is_void, __is_pod, etc) being used as identifiers.
86 #pragma clang diagnostic push
87 #pragma clang diagnostic ignored "-Wkeyword-compat"
88 #endif
89
90 namespace __detail
91 {
92 // NB: g++ can not compile these if declared within the class
93 // __is_pod itself.
94 typedef char __one;
95 typedef char __two[2];
96
97 template<typename _Tp>
98 __one __test_type(int _Tp::*);
99 template<typename _Tp>
100 __two& __test_type(...);
101 } // namespace __detail
102
103
104 struct __true_type { };
105 struct __false_type { };
106
107 template<bool>
108 struct __truth_type
109 { typedef __false_type __type; };
110
111 template<>
112 struct __truth_type<true>
113 { typedef __true_type __type; };
114
115 // N.B. The conversions to bool are needed due to the issue
116 // explained in c++/19404.
117 template<class _Sp, class _Tp>
118 struct __traitor
119 {
120 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
121 typedef typename __truth_type<__value>::__type __type;
122 };
123
124 // Compare for equality of types.
125 template<typename, typename>
126 struct __are_same
127 {
128 enum { __value = 0 };
129 typedef __false_type __type;
130 };
131
132 template<typename _Tp>
133 struct __are_same<_Tp, _Tp>
134 {
135 enum { __value = 1 };
136 typedef __true_type __type;
137 };
138
139 // Holds if the template-argument is a void type.
140 template<typename _Tp>
141 struct __is_void
142 {
143 enum { __value = 0 };
144 typedef __false_type __type;
145 };
146
147 template<>
148 struct __is_void<void>
149 {
150 enum { __value = 1 };
151 typedef __true_type __type;
152 };
153
154 //
155 // Integer types
156 //
157 template<typename _Tp>
158 struct __is_integer
159 {
160 enum { __value = 0 };
161 typedef __false_type __type;
162 };
163
164 // Thirteen specializations (yes there are eleven standard integer
165 // types; 'long long' and 'unsigned long long' are supported as
166 // extensions)
167 template<>
168 struct __is_integer<bool>
169 {
170 enum { __value = 1 };
171 typedef __true_type __type;
172 };
173
174 template<>
175 struct __is_integer<char>
176 {
177 enum { __value = 1 };
178 typedef __true_type __type;
179 };
180
181 template<>
182 struct __is_integer<signed char>
183 {
184 enum { __value = 1 };
185 typedef __true_type __type;
186 };
187
188 template<>
189 struct __is_integer<unsigned char>
190 {
191 enum { __value = 1 };
192 typedef __true_type __type;
193 };
194
195 # ifdef _GLIBCXX_USE_WCHAR_T
196 template<>
197 struct __is_integer<wchar_t>
198 {
199 enum { __value = 1 };
200 typedef __true_type __type;
201 };
202 # endif
203
204 template<>
205 struct __is_integer<short>
206 {
207 enum { __value = 1 };
208 typedef __true_type __type;
209 };
210
211 template<>
212 struct __is_integer<unsigned short>
213 {
214 enum { __value = 1 };
215 typedef __true_type __type;
216 };
217
218 template<>
219 struct __is_integer<int>
220 {
221 enum { __value = 1 };
222 typedef __true_type __type;
223 };
224
225 template<>
226 struct __is_integer<unsigned int>
227 {
228 enum { __value = 1 };
229 typedef __true_type __type;
230 };
231
232 template<>
233 struct __is_integer<long>
234 {
235 enum { __value = 1 };
236 typedef __true_type __type;
237 };
238
239 template<>
240 struct __is_integer<unsigned long>
241 {
242 enum { __value = 1 };
243 typedef __true_type __type;
244 };
245
246 template<>
247 struct __is_integer<long long>
248 {
249 enum { __value = 1 };
250 typedef __true_type __type;
251 };
252
253 template<>
254 struct __is_integer<unsigned long long>
255 {
256 enum { __value = 1 };
257 typedef __true_type __type;
258 };
259
260 //
261 // Floating point types
262 //
263 template<typename _Tp>
264 struct __is_floating
265 {
266 enum { __value = 0 };
267 typedef __false_type __type;
268 };
269
270 // three specializations (float, double and 'long double')
271 template<>
272 struct __is_floating<float>
273 {
274 enum { __value = 1 };
275 typedef __true_type __type;
276 };
277
278 template<>
279 struct __is_floating<double>
280 {
281 enum { __value = 1 };
282 typedef __true_type __type;
283 };
284
285 template<>
286 struct __is_floating<long double>
287 {
288 enum { __value = 1 };
289 typedef __true_type __type;
290 };
291
292 //
293 // Pointer types
294 //
295 template<typename _Tp>
296 struct __is_pointer
297 {
298 enum { __value = 0 };
299 typedef __false_type __type;
300 };
301
302 template<typename _Tp>
303 struct __is_pointer<_Tp*>
304 {
305 enum { __value = 1 };
306 typedef __true_type __type;
307 };
308
309 //
310 // Normal iterator type
311 //
312 template<typename _Tp>
313 struct __is_normal_iterator
314 {
315 enum { __value = 0 };
316 typedef __false_type __type;
317 };
318
319 template<typename _Iterator, typename _Container>
320 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
321 _Container> >
322 {
323 enum { __value = 1 };
324 typedef __true_type __type;
325 };
326
327 //
328 // An arithmetic type is an integer type or a floating point type
329 //
330 template<typename _Tp>
331 struct __is_arithmetic
332 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
333 { };
334
335 //
336 // A fundamental type is `void' or and arithmetic type
337 //
338 template<typename _Tp>
339 struct __is_fundamental
340 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
341 { };
342
343 //
344 // A scalar type is an arithmetic type or a pointer type
345 //
346 template<typename _Tp>
347 struct __is_scalar
348 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
349 { };
350
351 // For the immediate use, the following is a good approximation.
352 template<typename _Tp>
353 struct __is_pod
354 {
355 enum
356 {
357 __value = (sizeof(__detail::__test_type<_Tp>(0))
358 != sizeof(__detail::__one))
359 };
360 };
361
362 //
363 // A stripped-down version of std::tr1::is_empty
364 //
365 template<typename _Tp>
366 struct __is_empty
367 {
368 private:
369 template<typename>
370 struct __first { };
371 template<typename _Up>
372 struct __second
373 : public _Up { };
374
375 public:
376 enum
377 {
378 __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
379 };
380 };
381
382 //
383 // For use in std::copy and std::find overloads for streambuf iterators.
384 //
385 template<typename _Tp>
386 struct __is_char
387 {
388 enum { __value = 0 };
389 typedef __false_type __type;
390 };
391
392 template<>
393 struct __is_char<char>
394 {
395 enum { __value = 1 };
396 typedef __true_type __type;
397 };
398
399 #ifdef _GLIBCXX_USE_WCHAR_T
400 template<>
401 struct __is_char<wchar_t>
402 {
403 enum { __value = 1 };
404 typedef __true_type __type;
405 };
406 #endif
407
408 #ifdef __clang__
409 #pragma clang diagnostic pop
410 #endif
411
412 _GLIBCXX_END_NAMESPACE
413
414 #endif //_CPP_TYPE_TRAITS_H
415