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
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 cpp_type_traits.h
27  * This is an internal header file, included by other library headers.
28  * You should not attempt to use it directly.
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 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
70 
71  template<typename _Iterator, typename _Container>
72  class __normal_iterator;
73 
74 _GLIBCXX_END_NAMESPACE
75 
76 _GLIBCXX_BEGIN_NAMESPACE(std)
77 
78  struct __true_type { };
79  struct __false_type { };
80 
81  template<bool>
82  struct __truth_type
83  { typedef __false_type __type; };
84 
85  template<>
86  struct __truth_type<true>
87  { typedef __true_type __type; };
88 
89  // N.B. The conversions to bool are needed due to the issue
90  // explained in c++/19404.
91  template<class _Sp, class _Tp>
92  struct __traitor
93  {
94  enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
95  typedef typename __truth_type<__value>::__type __type;
96  };
97 
98  // Compare for equality of types.
99  template<typename, typename>
100  struct __are_same
101  {
102  enum { __value = 0 };
103  typedef __false_type __type;
104  };
105 
106  template<typename _Tp>
107  struct __are_same<_Tp, _Tp>
108  {
109  enum { __value = 1 };
110  typedef __true_type __type;
111  };
112 
113  // Holds if the template-argument is a void type.
114  template<typename _Tp>
115  struct __is_void
116  {
117  enum { __value = 0 };
118  typedef __false_type __type;
119  };
120 
121  template<>
122  struct __is_void<void>
123  {
124  enum { __value = 1 };
125  typedef __true_type __type;
126  };
127 
128  //
129  // Integer types
130  //
131  template<typename _Tp>
132  struct __is_integer
133  {
134  enum { __value = 0 };
135  typedef __false_type __type;
136  };
137 
138  // Thirteen specializations (yes there are eleven standard integer
139  // types; 'long long' and 'unsigned long long' are supported as
140  // extensions)
141  template<>
142  struct __is_integer<bool>
143  {
144  enum { __value = 1 };
145  typedef __true_type __type;
146  };
147 
148  template<>
149  struct __is_integer<char>
150  {
151  enum { __value = 1 };
152  typedef __true_type __type;
153  };
154 
155  template<>
156  struct __is_integer<signed char>
157  {
158  enum { __value = 1 };
159  typedef __true_type __type;
160  };
161 
162  template<>
163  struct __is_integer<unsigned char>
164  {
165  enum { __value = 1 };
166  typedef __true_type __type;
167  };
168 
169 # ifdef _GLIBCXX_USE_WCHAR_T
170  template<>
171  struct __is_integer<wchar_t>
172  {
173  enum { __value = 1 };
174  typedef __true_type __type;
175  };
176 # endif
177 
178 #ifdef __GXX_EXPERIMENTAL_CXX0X__
179  template<>
180  struct __is_integer<char16_t>
181  {
182  enum { __value = 1 };
183  typedef __true_type __type;
184  };
185 
186  template<>
187  struct __is_integer<char32_t>
188  {
189  enum { __value = 1 };
190  typedef __true_type __type;
191  };
192 #endif
193 
194  template<>
195  struct __is_integer<short>
196  {
197  enum { __value = 1 };
198  typedef __true_type __type;
199  };
200 
201  template<>
202  struct __is_integer<unsigned short>
203  {
204  enum { __value = 1 };
205  typedef __true_type __type;
206  };
207 
208  template<>
209  struct __is_integer<int>
210  {
211  enum { __value = 1 };
212  typedef __true_type __type;
213  };
214 
215  template<>
216  struct __is_integer<unsigned int>
217  {
218  enum { __value = 1 };
219  typedef __true_type __type;
220  };
221 
222  template<>
223  struct __is_integer<long>
224  {
225  enum { __value = 1 };
226  typedef __true_type __type;
227  };
228 
229  template<>
230  struct __is_integer<unsigned long>
231  {
232  enum { __value = 1 };
233  typedef __true_type __type;
234  };
235 
236  template<>
237  struct __is_integer<long long>
238  {
239  enum { __value = 1 };
240  typedef __true_type __type;
241  };
242 
243  template<>
244  struct __is_integer<unsigned long long>
245  {
246  enum { __value = 1 };
247  typedef __true_type __type;
248  };
249 
250  //
251  // Floating point types
252  //
253  template<typename _Tp>
254  struct __is_floating
255  {
256  enum { __value = 0 };
257  typedef __false_type __type;
258  };
259 
260  // three specializations (float, double and 'long double')
261  template<>
262  struct __is_floating<float>
263  {
264  enum { __value = 1 };
265  typedef __true_type __type;
266  };
267 
268  template<>
269  struct __is_floating<double>
270  {
271  enum { __value = 1 };
272  typedef __true_type __type;
273  };
274 
275  template<>
276  struct __is_floating<long double>
277  {
278  enum { __value = 1 };
279  typedef __true_type __type;
280  };
281 
282  //
283  // Pointer types
284  //
285  template<typename _Tp>
286  struct __is_pointer
287  {
288  enum { __value = 0 };
289  typedef __false_type __type;
290  };
291 
292  template<typename _Tp>
293  struct __is_pointer<_Tp*>
294  {
295  enum { __value = 1 };
296  typedef __true_type __type;
297  };
298 
299  //
300  // Normal iterator type
301  //
302  template<typename _Tp>
303  struct __is_normal_iterator
304  {
305  enum { __value = 0 };
306  typedef __false_type __type;
307  };
308 
309  template<typename _Iterator, typename _Container>
310  struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
311  _Container> >
312  {
313  enum { __value = 1 };
314  typedef __true_type __type;
315  };
316 
317  //
318  // An arithmetic type is an integer type or a floating point type
319  //
320  template<typename _Tp>
321  struct __is_arithmetic
322  : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
323  { };
324 
325  //
326  // A fundamental type is `void' or and arithmetic type
327  //
328  template<typename _Tp>
329  struct __is_fundamental
330  : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
331  { };
332 
333  //
334  // A scalar type is an arithmetic type or a pointer type
335  //
336  template<typename _Tp>
337  struct __is_scalar
338  : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
339  { };
340 
341  //
342  // For use in std::copy and std::find overloads for streambuf iterators.
343  //
344  template<typename _Tp>
345  struct __is_char
346  {
347  enum { __value = 0 };
348  typedef __false_type __type;
349  };
350 
351  template<>
352  struct __is_char<char>
353  {
354  enum { __value = 1 };
355  typedef __true_type __type;
356  };
357 
358 #ifdef _GLIBCXX_USE_WCHAR_T
359  template<>
360  struct __is_char<wchar_t>
361  {
362  enum { __value = 1 };
363  typedef __true_type __type;
364  };
365 #endif
366 
367  template<typename _Tp>
368  struct __is_byte
369  {
370  enum { __value = 0 };
371  typedef __false_type __type;
372  };
373 
374  template<>
375  struct __is_byte<char>
376  {
377  enum { __value = 1 };
378  typedef __true_type __type;
379  };
380 
381  template<>
382  struct __is_byte<signed char>
383  {
384  enum { __value = 1 };
385  typedef __true_type __type;
386  };
387 
388  template<>
389  struct __is_byte<unsigned char>
390  {
391  enum { __value = 1 };
392  typedef __true_type __type;
393  };
394 
395  //
396  // Move iterator type
397  //
398  template<typename _Tp>
399  struct __is_move_iterator
400  {
401  enum { __value = 0 };
402  typedef __false_type __type;
403  };
404 
405 #ifdef __GXX_EXPERIMENTAL_CXX0X__
406  template<typename _Iterator>
407  class move_iterator;
408 
409  template<typename _Iterator>
410  struct __is_move_iterator< move_iterator<_Iterator> >
411  {
412  enum { __value = 1 };
413  typedef __true_type __type;
414  };
415 #endif
416 
417 _GLIBCXX_END_NAMESPACE
418 
419 #endif //_CPP_TYPE_TRAITS_H