1// The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000-2015 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).  Up to four target-specific __int<N>
145  // types are supported as well.
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#if __cplusplus >= 201103L
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#define __INT_N(TYPE) 			\
256  template<>				\
257    struct __is_integer<TYPE>		\
258    {					\
259      enum { __value = 1 };		\
260      typedef __true_type __type;	\
261    };					\
262  template<>				\
263    struct __is_integer<unsigned TYPE>	\
264    {					\
265      enum { __value = 1 };		\
266      typedef __true_type __type;	\
267    };
268
269#ifdef __GLIBCXX_TYPE_INT_N_0
270__INT_N(__GLIBCXX_TYPE_INT_N_0)
271#endif
272#ifdef __GLIBCXX_TYPE_INT_N_1
273__INT_N(__GLIBCXX_TYPE_INT_N_1)
274#endif
275#ifdef __GLIBCXX_TYPE_INT_N_2
276__INT_N(__GLIBCXX_TYPE_INT_N_2)
277#endif
278#ifdef __GLIBCXX_TYPE_INT_N_3
279__INT_N(__GLIBCXX_TYPE_INT_N_3)
280#endif
281
282#undef __INT_N
283
284  //
285  // Floating point types
286  //
287  template<typename _Tp>
288    struct __is_floating
289    {
290      enum { __value = 0 };
291      typedef __false_type __type;
292    };
293
294  // three specializations (float, double and 'long double')
295  template<>
296    struct __is_floating<float>
297    {
298      enum { __value = 1 };
299      typedef __true_type __type;
300    };
301
302  template<>
303    struct __is_floating<double>
304    {
305      enum { __value = 1 };
306      typedef __true_type __type;
307    };
308
309  template<>
310    struct __is_floating<long double>
311    {
312      enum { __value = 1 };
313      typedef __true_type __type;
314    };
315
316  //
317  // Pointer types
318  //
319  template<typename _Tp>
320    struct __is_pointer
321    {
322      enum { __value = 0 };
323      typedef __false_type __type;
324    };
325
326  template<typename _Tp>
327    struct __is_pointer<_Tp*>
328    {
329      enum { __value = 1 };
330      typedef __true_type __type;
331    };
332
333  //
334  // Normal iterator type
335  //
336  template<typename _Tp>
337    struct __is_normal_iterator
338    {
339      enum { __value = 0 };
340      typedef __false_type __type;
341    };
342
343  template<typename _Iterator, typename _Container>
344    struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
345							      _Container> >
346    {
347      enum { __value = 1 };
348      typedef __true_type __type;
349    };
350
351  //
352  // An arithmetic type is an integer type or a floating point type
353  //
354  template<typename _Tp>
355    struct __is_arithmetic
356    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
357    { };
358
359  //
360  // A scalar type is an arithmetic type or a pointer type
361  //
362  template<typename _Tp>
363    struct __is_scalar
364    : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
365    { };
366
367  //
368  // For use in std::copy and std::find overloads for streambuf iterators.
369  //
370  template<typename _Tp>
371    struct __is_char
372    {
373      enum { __value = 0 };
374      typedef __false_type __type;
375    };
376
377  template<>
378    struct __is_char<char>
379    {
380      enum { __value = 1 };
381      typedef __true_type __type;
382    };
383
384#ifdef _GLIBCXX_USE_WCHAR_T
385  template<>
386    struct __is_char<wchar_t>
387    {
388      enum { __value = 1 };
389      typedef __true_type __type;
390    };
391#endif
392
393  template<typename _Tp>
394    struct __is_byte
395    {
396      enum { __value = 0 };
397      typedef __false_type __type;
398    };
399
400  template<>
401    struct __is_byte<char>
402    {
403      enum { __value = 1 };
404      typedef __true_type __type;
405    };
406
407  template<>
408    struct __is_byte<signed char>
409    {
410      enum { __value = 1 };
411      typedef __true_type __type;
412    };
413
414  template<>
415    struct __is_byte<unsigned char>
416    {
417      enum { __value = 1 };
418      typedef __true_type __type;
419    };
420
421  //
422  // Move iterator type
423  //
424  template<typename _Tp>
425    struct __is_move_iterator
426    {
427      enum { __value = 0 };
428      typedef __false_type __type;
429    };
430
431#if __cplusplus >= 201103L
432  template<typename _Iterator>
433    class move_iterator;
434
435  template<typename _Iterator>
436    struct __is_move_iterator< move_iterator<_Iterator> >
437    {
438      enum { __value = 1 };
439      typedef __true_type __type;
440    };
441#endif
442
443_GLIBCXX_END_NAMESPACE_VERSION
444} // namespace
445
446#endif //_CPP_TYPE_TRAITS_H
447