Line data Source code
1 : // The -*- C++ -*- type traits classes for internal use in libstdc++
2 :
3 : // Copyright (C) 2000-2016 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 : extern "C++" {
68 :
69 : namespace 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 : //
395 : // Move iterator type
396 : //
397 : template<typename _Tp>
398 : struct __is_move_iterator
399 : {
400 : enum { __value = 0 };
401 : typedef __false_type __type;
402 : };
403 :
404 : // Fallback implementation of the function in bits/stl_iterator.h used to
405 : // remove the move_iterator wrapper.
406 : template<typename _Iterator>
407 : inline _Iterator
408 11354 : __miter_base(_Iterator __it)
409 11354 : { return __it; }
410 :
411 : _GLIBCXX_END_NAMESPACE_VERSION
412 : } // namespace
413 : } // extern "C++"
414 :
415 : #endif //_CPP_TYPE_TRAITS_H
|