1// The -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000-2018 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
67extern "C++" {
68
69namespace std _GLIBCXX_VISIBILITY(default)
70{
71_GLIBCXX_BEGIN_NAMESPACE_VERSION
72
73 struct __true_type { };
74 struct __false_type { };
75
76 template<bool>
77 struct __truth_type
78 { typedef __false_type __type; };
79
80 template<>
81 struct __truth_type<true>
82 { typedef __true_type __type; };
83
84 // N.B. The conversions to bool are needed due to the issue
85 // explained in c++/19404.
86 template<class _Sp, class _Tp>
87 struct __traitor
88 {
89 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
90 typedef typename __truth_type<__value>::__type __type;
91 };
92
93 // Compare for equality of types.
94 template<typename, typename>
95 struct __are_same
96 {
97 enum { __value = 0 };
98 typedef __false_type __type;
99 };
100
101 template<typename _Tp>
102 struct __are_same<_Tp, _Tp>
103 {
104 enum { __value = 1 };
105 typedef __true_type __type;
106 };
107
108 // Holds if the template-argument is a void type.
109 template<typename _Tp>
110 struct __is_void
111 {
112 enum { __value = 0 };
113 typedef __false_type __type;
114 };
115
116 template<>
117 struct __is_void<void>
118 {
119 enum { __value = 1 };
120 typedef __true_type __type;
121 };
122
123 //
124 // Integer types
125 //
126 template<typename _Tp>
127 struct __is_integer
128 {
129 enum { __value = 0 };
130 typedef __false_type __type;
131 };
132
133 // Thirteen specializations (yes there are eleven standard integer
134 // types; <em>long long</em> and <em>unsigned long long</em> are
135 // supported as extensions). Up to four target-specific __int<N>
136 // types are supported as well.
137 template<>
138 struct __is_integer<bool>
139 {
140 enum { __value = 1 };
141 typedef __true_type __type;
142 };
143
144 template<>
145 struct __is_integer<char>
146 {
147 enum { __value = 1 };
148 typedef __true_type __type;
149 };
150
151 template<>
152 struct __is_integer<signed char>
153 {
154 enum { __value = 1 };
155 typedef __true_type __type;
156 };
157
158 template<>
159 struct __is_integer<unsigned char>
160 {
161 enum { __value = 1 };
162 typedef __true_type __type;
163 };
164
165# ifdef _GLIBCXX_USE_WCHAR_T
166 template<>
167 struct __is_integer<wchar_t>
168 {
169 enum { __value = 1 };
170 typedef __true_type __type;
171 };
172# endif
173
174#if __cplusplus >= 201103L
175 template<>
176 struct __is_integer<char16_t>
177 {
178 enum { __value = 1 };
179 typedef __true_type __type;
180 };
181
182 template<>
183 struct __is_integer<char32_t>
184 {
185 enum { __value = 1 };
186 typedef __true_type __type;
187 };
188#endif
189
190 template<>
191 struct __is_integer<short>
192 {
193 enum { __value = 1 };
194 typedef __true_type __type;
195 };
196
197 template<>
198 struct __is_integer<unsigned short>
199 {
200 enum { __value = 1 };
201 typedef __true_type __type;
202 };
203
204 template<>
205 struct __is_integer<int>
206 {
207 enum { __value = 1 };
208 typedef __true_type __type;
209 };
210
211 template<>
212 struct __is_integer<unsigned int>
213 {
214 enum { __value = 1 };
215 typedef __true_type __type;
216 };
217
218 template<>
219 struct __is_integer<long>
220 {
221 enum { __value = 1 };
222 typedef __true_type __type;
223 };
224
225 template<>
226 struct __is_integer<unsigned long>
227 {
228 enum { __value = 1 };
229 typedef __true_type __type;
230 };
231
232 template<>
233 struct __is_integer<long long>
234 {
235 enum { __value = 1 };
236 typedef __true_type __type;
237 };
238
239 template<>
240 struct __is_integer<unsigned long long>
241 {
242 enum { __value = 1 };
243 typedef __true_type __type;
244 };
245
246#define __INT_N(TYPE) \
247 template<> \
248 struct __is_integer<TYPE> \
249 { \
250 enum { __value = 1 }; \
251 typedef __true_type __type; \
252 }; \
253 template<> \
254 struct __is_integer<unsigned TYPE> \
255 { \
256 enum { __value = 1 }; \
257 typedef __true_type __type; \
258 };
259
260#ifdef __GLIBCXX_TYPE_INT_N_0
261__INT_N(__GLIBCXX_TYPE_INT_N_0)
262#endif
263#ifdef __GLIBCXX_TYPE_INT_N_1
264__INT_N(__GLIBCXX_TYPE_INT_N_1)
265#endif
266#ifdef __GLIBCXX_TYPE_INT_N_2
267__INT_N(__GLIBCXX_TYPE_INT_N_2)
268#endif
269#ifdef __GLIBCXX_TYPE_INT_N_3
270__INT_N(__GLIBCXX_TYPE_INT_N_3)
271#endif
272
273#undef __INT_N
274
275 //
276 // Floating point types
277 //
278 template<typename _Tp>
279 struct __is_floating
280 {
281 enum { __value = 0 };
282 typedef __false_type __type;
283 };
284
285 // three specializations (float, double and 'long double')
286 template<>
287 struct __is_floating<float>
288 {
289 enum { __value = 1 };
290 typedef __true_type __type;
291 };
292
293 template<>
294 struct __is_floating<double>
295 {
296 enum { __value = 1 };
297 typedef __true_type __type;
298 };
299
300 template<>
301 struct __is_floating<long double>
302 {
303 enum { __value = 1 };
304 typedef __true_type __type;
305 };
306
307 //
308 // Pointer types
309 //
310 template<typename _Tp>
311 struct __is_pointer
312 {
313 enum { __value = 0 };
314 typedef __false_type __type;
315 };
316
317 template<typename _Tp>
318 struct __is_pointer<_Tp*>
319 {
320 enum { __value = 1 };
321 typedef __true_type __type;
322 };
323
324 //
325 // An arithmetic type is an integer type or a floating point type
326 //
327 template<typename _Tp>
328 struct __is_arithmetic
329 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
330 { };
331
332 //
333 // A scalar type is an arithmetic type or a pointer type
334 //
335 template<typename _Tp>
336 struct __is_scalar
337 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
338 { };
339
340 //
341 // For use in std::copy and std::find overloads for streambuf iterators.
342 //
343 template<typename _Tp>
344 struct __is_char
345 {
346 enum { __value = 0 };
347 typedef __false_type __type;
348 };
349
350 template<>
351 struct __is_char<char>
352 {
353 enum { __value = 1 };
354 typedef __true_type __type;
355 };
356
357#ifdef _GLIBCXX_USE_WCHAR_T
358 template<>
359 struct __is_char<wchar_t>
360 {
361 enum { __value = 1 };
362 typedef __true_type __type;
363 };
364#endif
365
366 template<typename _Tp>
367 struct __is_byte
368 {
369 enum { __value = 0 };
370 typedef __false_type __type;
371 };
372
373 template<>
374 struct __is_byte<char>
375 {
376 enum { __value = 1 };
377 typedef __true_type __type;
378 };
379
380 template<>
381 struct __is_byte<signed char>
382 {
383 enum { __value = 1 };
384 typedef __true_type __type;
385 };
386
387 template<>
388 struct __is_byte<unsigned char>
389 {
390 enum { __value = 1 };
391 typedef __true_type __type;
392 };
393
394#if __cplusplus >= 201703L
395 enum class byte : unsigned char;
396
397 template<>
398 struct __is_byte<byte>
399 {
400 enum { __value = 1 };
401 typedef __true_type __type;
402 };
403#endif // C++17
404
405 //
406 // Move iterator type
407 //
408 template<typename _Tp>
409 struct __is_move_iterator
410 {
411 enum { __value = 0 };
412 typedef __false_type __type;
413 };
414
415 // Fallback implementation of the function in bits/stl_iterator.h used to
416 // remove the move_iterator wrapper.
417 template<typename _Iterator>
418 inline _Iterator
419 __miter_base(_Iterator __it)
420 { return __it; }
421
422_GLIBCXX_END_NAMESPACE_VERSION
423} // namespace
424} // extern "C++"
425
426#endif //_CPP_TYPE_TRAITS_H
427