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. |
69 | namespace __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 | |
79 | namespace 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 | |