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