1 | // The -*- C++ -*- type traits classes for internal use in libstdc++ |
2 | |
3 | // Copyright (C) 2000-2014 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. |
68 | namespace __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 | |
78 | namespace 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) |
145 | template<> |
146 | struct __is_integer<bool> |
147 | { |
148 | enum { __value = 1 }; |
149 | typedef __true_type __type; |
150 | }; |
151 | |
152 | template<> |
153 | struct __is_integer<char> |
154 | { |
155 | enum { __value = 1 }; |
156 | typedef __true_type __type; |
157 | }; |
158 | |
159 | template<> |
160 | struct __is_integer<signed char> |
161 | { |
162 | enum { __value = 1 }; |
163 | typedef __true_type __type; |
164 | }; |
165 | |
166 | template<> |
167 | struct __is_integer<unsigned char> |
168 | { |
169 | enum { __value = 1 }; |
170 | typedef __true_type __type; |
171 | }; |
172 | |
173 | # ifdef _GLIBCXX_USE_WCHAR_T |
174 | template<> |
175 | struct __is_integer<wchar_t> |
176 | { |
177 | enum { __value = 1 }; |
178 | typedef __true_type __type; |
179 | }; |
180 | # endif |
181 | |
182 | #if __cplusplus >= 201103L |
183 | template<> |
184 | struct __is_integer<char16_t> |
185 | { |
186 | enum { __value = 1 }; |
187 | typedef __true_type __type; |
188 | }; |
189 | |
190 | template<> |
191 | struct __is_integer<char32_t> |
192 | { |
193 | enum { __value = 1 }; |
194 | typedef __true_type __type; |
195 | }; |
196 | #endif |
197 | |
198 | template<> |
199 | struct __is_integer<short> |
200 | { |
201 | enum { __value = 1 }; |
202 | typedef __true_type __type; |
203 | }; |
204 | |
205 | template<> |
206 | struct __is_integer<unsigned short> |
207 | { |
208 | enum { __value = 1 }; |
209 | typedef __true_type __type; |
210 | }; |
211 | |
212 | template<> |
213 | struct __is_integer<int> |
214 | { |
215 | enum { __value = 1 }; |
216 | typedef __true_type __type; |
217 | }; |
218 | |
219 | template<> |
220 | struct __is_integer<unsigned int> |
221 | { |
222 | enum { __value = 1 }; |
223 | typedef __true_type __type; |
224 | }; |
225 | |
226 | template<> |
227 | struct __is_integer<long> |
228 | { |
229 | enum { __value = 1 }; |
230 | typedef __true_type __type; |
231 | }; |
232 | |
233 | template<> |
234 | struct __is_integer<unsigned long> |
235 | { |
236 | enum { __value = 1 }; |
237 | typedef __true_type __type; |
238 | }; |
239 | |
240 | template<> |
241 | struct __is_integer<long long> |
242 | { |
243 | enum { __value = 1 }; |
244 | typedef __true_type __type; |
245 | }; |
246 | |
247 | template<> |
248 | struct __is_integer<unsigned long long> |
249 | { |
250 | enum { __value = 1 }; |
251 | typedef __true_type __type; |
252 | }; |
253 | |
254 | // |
255 | // Floating point types |
256 | // |
257 | template<typename _Tp> |
258 | struct __is_floating |
259 | { |
260 | enum { __value = 0 }; |
261 | typedef __false_type __type; |
262 | }; |
263 | |
264 | // three specializations (float, double and 'long double') |
265 | template<> |
266 | struct __is_floating<float> |
267 | { |
268 | enum { __value = 1 }; |
269 | typedef __true_type __type; |
270 | }; |
271 | |
272 | template<> |
273 | struct __is_floating<double> |
274 | { |
275 | enum { __value = 1 }; |
276 | typedef __true_type __type; |
277 | }; |
278 | |
279 | template<> |
280 | struct __is_floating<long double> |
281 | { |
282 | enum { __value = 1 }; |
283 | typedef __true_type __type; |
284 | }; |
285 | |
286 | // |
287 | // Pointer types |
288 | // |
289 | template<typename _Tp> |
290 | struct __is_pointer |
291 | { |
292 | enum { __value = 0 }; |
293 | typedef __false_type __type; |
294 | }; |
295 | |
296 | template<typename _Tp> |
297 | struct __is_pointer<_Tp*> |
298 | { |
299 | enum { __value = 1 }; |
300 | typedef __true_type __type; |
301 | }; |
302 | |
303 | // |
304 | // Normal iterator type |
305 | // |
306 | template<typename _Tp> |
307 | struct __is_normal_iterator |
308 | { |
309 | enum { __value = 0 }; |
310 | typedef __false_type __type; |
311 | }; |
312 | |
313 | template<typename _Iterator, typename _Container> |
314 | struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, |
315 | _Container> > |
316 | { |
317 | enum { __value = 1 }; |
318 | typedef __true_type __type; |
319 | }; |
320 | |
321 | // |
322 | // An arithmetic type is an integer type or a floating point type |
323 | // |
324 | template<typename _Tp> |
325 | struct __is_arithmetic |
326 | : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > |
327 | { }; |
328 | |
329 | // |
330 | // A scalar type is an arithmetic type or a pointer type |
331 | // |
332 | template<typename _Tp> |
333 | struct __is_scalar |
334 | : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > |
335 | { }; |
336 | |
337 | // |
338 | // For use in std::copy and std::find overloads for streambuf iterators. |
339 | // |
340 | template<typename _Tp> |
341 | struct __is_char |
342 | { |
343 | enum { __value = 0 }; |
344 | typedef __false_type __type; |
345 | }; |
346 | |
347 | template<> |
348 | struct __is_char<char> |
349 | { |
350 | enum { __value = 1 }; |
351 | typedef __true_type __type; |
352 | }; |
353 | |
354 | #ifdef _GLIBCXX_USE_WCHAR_T |
355 | template<> |
356 | struct __is_char<wchar_t> |
357 | { |
358 | enum { __value = 1 }; |
359 | typedef __true_type __type; |
360 | }; |
361 | #endif |
362 | |
363 | template<typename _Tp> |
364 | struct __is_byte |
365 | { |
366 | enum { __value = 0 }; |
367 | typedef __false_type __type; |
368 | }; |
369 | |
370 | template<> |
371 | struct __is_byte<char> |
372 | { |
373 | enum { __value = 1 }; |
374 | typedef __true_type __type; |
375 | }; |
376 | |
377 | template<> |
378 | struct __is_byte<signed char> |
379 | { |
380 | enum { __value = 1 }; |
381 | typedef __true_type __type; |
382 | }; |
383 | |
384 | template<> |
385 | struct __is_byte<unsigned char> |
386 | { |
387 | enum { __value = 1 }; |
388 | typedef __true_type __type; |
389 | }; |
390 | |
391 | // |
392 | // Move iterator type |
393 | // |
394 | template<typename _Tp> |
395 | struct __is_move_iterator |
396 | { |
397 | enum { __value = 0 }; |
398 | typedef __false_type __type; |
399 | }; |
400 | |
401 | #if __cplusplus >= 201103L |
402 | template<typename _Iterator> |
403 | class move_iterator; |
404 | |
405 | template<typename _Iterator> |
406 | struct __is_move_iterator< move_iterator<_Iterator> > |
407 | { |
408 | enum { __value = 1 }; |
409 | typedef __true_type __type; |
410 | }; |
411 | #endif |
412 | |
413 | _GLIBCXX_END_NAMESPACE_VERSION |
414 | } // namespace |
415 | |
416 | #endif //_CPP_TYPE_TRAITS_H |
417 | |