1// The -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000-2015 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/cpp_type_traits.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{ext/type_traits}
28 */
29
30// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
31
32#ifndef _CPP_TYPE_TRAITS_H
33#define _CPP_TYPE_TRAITS_H 1
34
35#pragma GCC system_header
36
37#include <bits/c++config.h>
38
39//
40// This file provides some compile-time information about various types.
41// These representations were designed, on purpose, to be constant-expressions
42// and not types as found in <bits/type_traits.h>. In particular, they
43// can be used in control structures and the optimizer hopefully will do
44// the obvious thing.
45//
46// Why integral expressions, and not functions nor types?
47// Firstly, these compile-time entities are used as template-arguments
48// so function return values won't work: We need compile-time entities.
49// We're left with types and constant integral expressions.
50// Secondly, from the point of view of ease of use, type-based compile-time
51// information is -not- *that* convenient. On has to write lots of
52// overloaded functions and to hope that the compiler will select the right
53// one. As a net effect, the overall structure isn't very clear at first
54// glance.
55// Thirdly, partial ordering and overload resolution (of function templates)
56// is highly costly in terms of compiler-resource. It is a Good Thing to
57// keep these resource consumption as least as possible.
58//
59// See valarray_array.h for a case use.
60//
61// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
62//
63// Update 2005: types are also provided and <bits/type_traits.h> has been
64// removed.
65//
66
67// Forward declaration hack, should really include this from somewhere.
68namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
69{
70_GLIBCXX_BEGIN_NAMESPACE_VERSION
71
72 template<typename _Iterator, typename _Container>
73 class __normal_iterator;
74
75_GLIBCXX_END_NAMESPACE_VERSION
76} // namespace
77
78namespace std _GLIBCXX_VISIBILITY(default)
79{
80_GLIBCXX_BEGIN_NAMESPACE_VERSION
81
82 struct __true_type { };
83 struct __false_type { };
84
85 template<bool>
86 struct __truth_type
87 { typedef __false_type __type; };
88
89 template<>
90 struct __truth_type<true>
91 { typedef __true_type __type; };
92
93 // N.B. The conversions to bool are needed due to the issue
94 // explained in c++/19404.
95 template<class _Sp, class _Tp>
96 struct __traitor
97 {
98 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
99 typedef typename __truth_type<__value>::__type __type;
100 };
101
102 // Compare for equality of types.
103 template<typename, typename>
104 struct __are_same
105 {
106 enum { __value = 0 };
107 typedef __false_type __type;
108 };
109
110 template<typename _Tp>
111 struct __are_same<_Tp, _Tp>
112 {
113 enum { __value = 1 };
114 typedef __true_type __type;
115 };
116
117 // Holds if the template-argument is a void type.
118 template<typename _Tp>
119 struct __is_void
120 {
121 enum { __value = 0 };
122 typedef __false_type __type;
123 };
124
125 template<>
126 struct __is_void<void>
127 {
128 enum { __value = 1 };
129 typedef __true_type __type;
130 };
131
132 //
133 // Integer types
134 //
135 template<typename _Tp>
136 struct __is_integer
137 {
138 enum { __value = 0 };
139 typedef __false_type __type;
140 };
141
142 // Thirteen specializations (yes there are eleven standard integer
143 // types; <em>long long</em> and <em>unsigned long long</em> are
144 // supported as extensions). Up to four target-specific __int<N>
145 // types are supported as well.
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#if __cplusplus >= 201103L
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#define __INT_N(TYPE) \
256 template<> \
257 struct __is_integer<TYPE> \
258 { \
259 enum { __value = 1 }; \
260 typedef __true_type __type; \
261 }; \
262 template<> \
263 struct __is_integer<unsigned TYPE> \
264 { \
265 enum { __value = 1 }; \
266 typedef __true_type __type; \
267 };
268
269#ifdef __GLIBCXX_TYPE_INT_N_0
270__INT_N(__GLIBCXX_TYPE_INT_N_0)
271#endif
272#ifdef __GLIBCXX_TYPE_INT_N_1
273__INT_N(__GLIBCXX_TYPE_INT_N_1)
274#endif
275#ifdef __GLIBCXX_TYPE_INT_N_2
276__INT_N(__GLIBCXX_TYPE_INT_N_2)
277#endif
278#ifdef __GLIBCXX_TYPE_INT_N_3
279__INT_N(__GLIBCXX_TYPE_INT_N_3)
280#endif
281
282#undef __INT_N
283
284 //
285 // Floating point types
286 //
287 template<typename _Tp>
288 struct __is_floating
289 {
290 enum { __value = 0 };
291 typedef __false_type __type;
292 };
293
294 // three specializations (float, double and 'long double')
295 template<>
296 struct __is_floating<float>
297 {
298 enum { __value = 1 };
299 typedef __true_type __type;
300 };
301
302 template<>
303 struct __is_floating<double>
304 {
305 enum { __value = 1 };
306 typedef __true_type __type;
307 };
308
309 template<>
310 struct __is_floating<long double>
311 {
312 enum { __value = 1 };
313 typedef __true_type __type;
314 };
315
316 //
317 // Pointer types
318 //
319 template<typename _Tp>
320 struct __is_pointer
321 {
322 enum { __value = 0 };
323 typedef __false_type __type;
324 };
325
326 template<typename _Tp>
327 struct __is_pointer<_Tp*>
328 {
329 enum { __value = 1 };
330 typedef __true_type __type;
331 };
332
333 //
334 // Normal iterator type
335 //
336 template<typename _Tp>
337 struct __is_normal_iterator
338 {
339 enum { __value = 0 };
340 typedef __false_type __type;
341 };
342
343 template<typename _Iterator, typename _Container>
344 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
345 _Container> >
346 {
347 enum { __value = 1 };
348 typedef __true_type __type;
349 };
350
351 //
352 // An arithmetic type is an integer type or a floating point type
353 //
354 template<typename _Tp>
355 struct __is_arithmetic
356 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
357 { };
358
359 //
360 // A scalar type is an arithmetic type or a pointer type
361 //
362 template<typename _Tp>
363 struct __is_scalar
364 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
365 { };
366
367 //
368 // For use in std::copy and std::find overloads for streambuf iterators.
369 //
370 template<typename _Tp>
371 struct __is_char
372 {
373 enum { __value = 0 };
374 typedef __false_type __type;
375 };
376
377 template<>
378 struct __is_char<char>
379 {
380 enum { __value = 1 };
381 typedef __true_type __type;
382 };
383
384#ifdef _GLIBCXX_USE_WCHAR_T
385 template<>
386 struct __is_char<wchar_t>
387 {
388 enum { __value = 1 };
389 typedef __true_type __type;
390 };
391#endif
392
393 template<typename _Tp>
394 struct __is_byte
395 {
396 enum { __value = 0 };
397 typedef __false_type __type;
398 };
399
400 template<>
401 struct __is_byte<char>
402 {
403 enum { __value = 1 };
404 typedef __true_type __type;
405 };
406
407 template<>
408 struct __is_byte<signed char>
409 {
410 enum { __value = 1 };
411 typedef __true_type __type;
412 };
413
414 template<>
415 struct __is_byte<unsigned char>
416 {
417 enum { __value = 1 };
418 typedef __true_type __type;
419 };
420
421 //
422 // Move iterator type
423 //
424 template<typename _Tp>
425 struct __is_move_iterator
426 {
427 enum { __value = 0 };
428 typedef __false_type __type;
429 };
430
431#if __cplusplus >= 201103L
432 template<typename _Iterator>
433 class move_iterator;
434
435 template<typename _Iterator>
436 struct __is_move_iterator< move_iterator<_Iterator> >
437 {
438 enum { __value = 1 };
439 typedef __true_type __type;
440 };
441#endif
442
443_GLIBCXX_END_NAMESPACE_VERSION
444} // namespace
445
446#endif //_CPP_TYPE_TRAITS_H
447