1// The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
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; <em>long long</em> and <em>unsigned long long</em> are
140  // supported as 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  template<typename _Tp>
418    class __is_iterator_helper
419    {
420      typedef char __one;
421      typedef struct { char __arr[2]; } __two;
422
423      template<typename _Up>
424        struct _Wrap_type
425	{ };
426
427      template<typename _Up>
428        static __one __test(_Wrap_type<typename _Up::iterator_category>*);
429
430      template<typename _Up>
431        static __two __test(...);
432
433    public:
434      static const bool __value = (sizeof(__test<_Tp>(0)) == 1
435				   || __is_pointer<_Tp>::__value);
436    };
437
438  template<typename _Tp>
439    struct __is_iterator
440    {
441      enum { __value = __is_iterator_helper<_Tp>::__value };
442      typedef typename __truth_type<__value>::__type __type;
443    };
444
445_GLIBCXX_END_NAMESPACE
446
447#endif //_CPP_TYPE_TRAITS_H
448