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-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 <[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)
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>
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