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 <dosreis@cmla.ens-cachan.fr>
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 (dosreis@cmla.ens-cachan.fr) 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.
68namespace __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
78namespace 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>
403    class move_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
417