1// The -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
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 3, 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// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file bits/cpp_type_traits.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{ext/type_traits}
29 */
30
31// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
32
33#ifndef _CPP_TYPE_TRAITS_H
34#define _CPP_TYPE_TRAITS_H 1
35
36#pragma GCC system_header
37
38#include <bits/c++config.h>
39
40//
41// This file provides some compile-time information about various types.
42// These representations were designed, on purpose, to be constant-expressions
43// and not types as found in <bits/type_traits.h>. In particular, they
44// can be used in control structures and the optimizer hopefully will do
45// the obvious thing.
46//
47// Why integral expressions, and not functions nor types?
48// Firstly, these compile-time entities are used as template-arguments
49// so function return values won't work: We need compile-time entities.
50// We're left with types and constant integral expressions.
51// Secondly, from the point of view of ease of use, type-based compile-time
52// information is -not- *that* convenient. On has to write lots of
53// overloaded functions and to hope that the compiler will select the right
54// one. As a net effect, the overall structure isn't very clear at first
55// glance.
56// Thirdly, partial ordering and overload resolution (of function templates)
57// is highly costly in terms of compiler-resource. It is a Good Thing to
58// keep these resource consumption as least as possible.
59//
60// See valarray_array.h for a case use.
61//
62// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
63//
64// Update 2005: types are also provided and <bits/type_traits.h> has been
65// removed.
66//
67
68// Forward declaration hack, should really include this from somewhere.
69namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
70{
71_GLIBCXX_BEGIN_NAMESPACE_VERSION
72
73 template<typename _Iterator, typename _Container>
74 class __normal_iterator;
75
76_GLIBCXX_END_NAMESPACE_VERSION
77} // namespace
78
79namespace std _GLIBCXX_VISIBILITY(default)
80{
81_GLIBCXX_BEGIN_NAMESPACE_VERSION
82
83 struct __true_type { };
84 struct __false_type { };
85
86 template<bool>
87 struct __truth_type
88 { typedef __false_type __type; };
89
90 template<>
91 struct __truth_type<true>
92 { typedef __true_type __type; };
93
94 // N.B. The conversions to bool are needed due to the issue
95 // explained in c++/19404.
96 template<class _Sp, class _Tp>
97 struct __traitor
98 {
99 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
100 typedef typename __truth_type<__value>::__type __type;
101 };
102
103 // Compare for equality of types.
104 template<typename, typename>
105 struct __are_same
106 {
107 enum { __value = 0 };
108 typedef __false_type __type;
109 };
110
111 template<typename _Tp>
112 struct __are_same<_Tp, _Tp>
113 {
114 enum { __value = 1 };
115 typedef __true_type __type;
116 };
117
118 // Holds if the template-argument is a void type.
119 template<typename _Tp>
120 struct __is_void
121 {
122 enum { __value = 0 };
123 typedef __false_type __type;
124 };
125
126 template<>
127 struct __is_void<void>
128 {
129 enum { __value = 1 };
130 typedef __true_type __type;
131 };
132
133 //
134 // Integer types
135 //
136 template<typename _Tp>
137 struct __is_integer
138 {
139 enum { __value = 0 };
140 typedef __false_type __type;
141 };
142
143 // Thirteen specializations (yes there are eleven standard integer
144 // types; <em>long long</em> and <em>unsigned long long</em> are
145 // supported as extensions)
146 template<>
147 struct __is_integer<bool>
148 {
149 enum { __value = 1 };
150 typedef __true_type __type;
151 };
152
153 template<>
154 struct __is_integer<char>
155 {
156 enum { __value = 1 };
157 typedef __true_type __type;
158 };
159
160 template<>
161 struct __is_integer<signed char>
162 {
163 enum { __value = 1 };
164 typedef __true_type __type;
165 };
166
167 template<>
168 struct __is_integer<unsigned char>
169 {
170 enum { __value = 1 };
171 typedef __true_type __type;
172 };
173
174# ifdef _GLIBCXX_USE_WCHAR_T
175 template<>
176 struct __is_integer<wchar_t>
177 {
178 enum { __value = 1 };
179 typedef __true_type __type;
180 };
181# endif
182
183#ifdef __GXX_EXPERIMENTAL_CXX0X__
184 template<>
185 struct __is_integer<char16_t>
186 {
187 enum { __value = 1 };
188 typedef __true_type __type;
189 };
190
191 template<>
192 struct __is_integer<char32_t>
193 {
194 enum { __value = 1 };
195 typedef __true_type __type;
196 };
197#endif
198
199 template<>
200 struct __is_integer<short>
201 {
202 enum { __value = 1 };
203 typedef __true_type __type;
204 };
205
206 template<>
207 struct __is_integer<unsigned short>
208 {
209 enum { __value = 1 };
210 typedef __true_type __type;
211 };
212
213 template<>
214 struct __is_integer<int>
215 {
216 enum { __value = 1 };
217 typedef __true_type __type;
218 };
219
220 template<>
221 struct __is_integer<unsigned int>
222 {
223 enum { __value = 1 };
224 typedef __true_type __type;
225 };
226
227 template<>
228 struct __is_integer<long>
229 {
230 enum { __value = 1 };
231 typedef __true_type __type;
232 };
233
234 template<>
235 struct __is_integer<unsigned long>
236 {
237 enum { __value = 1 };
238 typedef __true_type __type;
239 };
240
241 template<>
242 struct __is_integer<long long>
243 {
244 enum { __value = 1 };
245 typedef __true_type __type;
246 };
247
248 template<>
249 struct __is_integer<unsigned long long>
250 {
251 enum { __value = 1 };
252 typedef __true_type __type;
253 };
254
255 //
256 // Floating point types
257 //
258 template<typename _Tp>
259 struct __is_floating
260 {
261 enum { __value = 0 };
262 typedef __false_type __type;
263 };
264
265 // three specializations (float, double and 'long double')
266 template<>
267 struct __is_floating<float>
268 {
269 enum { __value = 1 };
270 typedef __true_type __type;
271 };
272
273 template<>
274 struct __is_floating<double>
275 {
276 enum { __value = 1 };
277 typedef __true_type __type;
278 };
279
280 template<>
281 struct __is_floating<long double>
282 {
283 enum { __value = 1 };
284 typedef __true_type __type;
285 };
286
287 //
288 // Pointer types
289 //
290 template<typename _Tp>
291 struct __is_pointer
292 {
293 enum { __value = 0 };
294 typedef __false_type __type;
295 };
296
297 template<typename _Tp>
298 struct __is_pointer<_Tp*>
299 {
300 enum { __value = 1 };
301 typedef __true_type __type;
302 };
303
304 //
305 // Normal iterator type
306 //
307 template<typename _Tp>
308 struct __is_normal_iterator
309 {
310 enum { __value = 0 };
311 typedef __false_type __type;
312 };
313
314 template<typename _Iterator, typename _Container>
315 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
316 _Container> >
317 {
318 enum { __value = 1 };
319 typedef __true_type __type;
320 };
321
322 //
323 // An arithmetic type is an integer type or a floating point type
324 //
325 template<typename _Tp>
326 struct __is_arithmetic
327 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
328 { };
329
330 //
331 // A fundamental type is `void' or and arithmetic type
332 //
333 template<typename _Tp>
334 struct __is_fundamental
335 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
336 { };
337
338 //
339 // A scalar type is an arithmetic type or a pointer type
340 //
341 template<typename _Tp>
342 struct __is_scalar
343 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
344 { };
345
346 //
347 // For use in std::copy and std::find overloads for streambuf iterators.
348 //
349 template<typename _Tp>
350 struct __is_char
351 {
352 enum { __value = 0 };
353 typedef __false_type __type;
354 };
355
356 template<>
357 struct __is_char<char>
358 {
359 enum { __value = 1 };
360 typedef __true_type __type;
361 };
362
363#ifdef _GLIBCXX_USE_WCHAR_T
364 template<>
365 struct __is_char<wchar_t>
366 {
367 enum { __value = 1 };
368 typedef __true_type __type;
369 };
370#endif
371
372 template<typename _Tp>
373 struct __is_byte
374 {
375 enum { __value = 0 };
376 typedef __false_type __type;
377 };
378
379 template<>
380 struct __is_byte<char>
381 {
382 enum { __value = 1 };
383 typedef __true_type __type;
384 };
385
386 template<>
387 struct __is_byte<signed char>
388 {
389 enum { __value = 1 };
390 typedef __true_type __type;
391 };
392
393 template<>
394 struct __is_byte<unsigned char>
395 {
396 enum { __value = 1 };
397 typedef __true_type __type;
398 };
399
400 //
401 // Move iterator type
402 //
403 template<typename _Tp>
404 struct __is_move_iterator
405 {
406 enum { __value = 0 };
407 typedef __false_type __type;
408 };
409
410#ifdef __GXX_EXPERIMENTAL_CXX0X__
411 template<typename _Iterator>
412 class move_iterator;
413
414 template<typename _Iterator>
415 struct __is_move_iterator< move_iterator<_Iterator> >
416 {
417 enum { __value = 1 };
418 typedef __true_type __type;
419 };
420#endif
421
422_GLIBCXX_END_NAMESPACE_VERSION
423} // namespace
424
425#endif //_CPP_TYPE_TRAITS_H
426