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, 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>
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