libstdc++
cpp_type_traits.h
Go to the documentation of this file.
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 <[email protected]>
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 ([email protected]) 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). 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>
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
GNU extensions for public use.
ISO C++ entities toplevel namespace is std.