cpp_type_traits.h revision 302408
1// The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
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 2, 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// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31/** @file cpp_type_traits.h
32 *  This is an internal header file, included by other library headers.
33 *  You should not attempt to use it directly.
34 */
35
36// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
37
38#ifndef _CPP_TYPE_TRAITS_H
39#define _CPP_TYPE_TRAITS_H 1
40
41#pragma GCC system_header
42
43#include <bits/c++config.h>
44
45//
46// This file provides some compile-time information about various types.
47// These representations were designed, on purpose, to be constant-expressions
48// and not types as found in <bits/type_traits.h>.  In particular, they
49// can be used in control structures and the optimizer hopefully will do
50// the obvious thing.
51//
52// Why integral expressions, and not functions nor types?
53// Firstly, these compile-time entities are used as template-arguments
54// so function return values won't work:  We need compile-time entities.
55// We're left with types and constant  integral expressions.
56// Secondly, from the point of view of ease of use, type-based compile-time
57// information is -not- *that* convenient.  On has to write lots of
58// overloaded functions and to hope that the compiler will select the right
59// one. As a net effect, the overall structure isn't very clear at first
60// glance.
61// Thirdly, partial ordering and overload resolution (of function templates)
62// is highly costly in terms of compiler-resource.  It is a Good Thing to
63// keep these resource consumption as least as possible.
64//
65// See valarray_array.h for a case use.
66//
67// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
68//
69// Update 2005: types are also provided and <bits/type_traits.h> has been
70// removed.
71//
72
73// Forward declaration hack, should really include this from somewhere.
74_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75
76  template<typename _Iterator, typename _Container>
77    class __normal_iterator;
78
79_GLIBCXX_END_NAMESPACE
80
81_GLIBCXX_BEGIN_NAMESPACE(std)
82
83#ifdef __clang__
84// When using clang, suppress warnings about possible keywords (such as
85// __is_void, __is_pod, etc) being used as identifiers.
86#pragma clang diagnostic push
87#pragma clang diagnostic ignored "-Wkeyword-compat"
88#endif
89
90namespace __detail
91{
92  // NB: g++ can not compile these if declared within the class
93  // __is_pod itself.
94  typedef char __one;
95  typedef char __two[2];
96
97  template<typename _Tp>
98  __one __test_type(int _Tp::*);
99  template<typename _Tp>
100  __two& __test_type(...);
101} // namespace __detail
102
103
104  struct __true_type { };
105  struct __false_type { };
106
107  template<bool>
108    struct __truth_type
109    { typedef __false_type __type; };
110
111  template<>
112    struct __truth_type<true>
113    { typedef __true_type __type; };
114
115  // N.B. The conversions to bool are needed due to the issue
116  // explained in c++/19404.
117  template<class _Sp, class _Tp>
118    struct __traitor
119    {
120      enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
121      typedef typename __truth_type<__value>::__type __type;
122    };
123
124  // Compare for equality of types.
125  template<typename, typename>
126    struct __are_same
127    {
128      enum { __value = 0 };
129      typedef __false_type __type;
130    };
131
132  template<typename _Tp>
133    struct __are_same<_Tp, _Tp>
134    {
135      enum { __value = 1 };
136      typedef __true_type __type;
137    };
138
139  // Holds if the template-argument is a void type.
140  template<typename _Tp>
141    struct __is_void
142    {
143      enum { __value = 0 };
144      typedef __false_type __type;
145    };
146
147  template<>
148    struct __is_void<void>
149    {
150      enum { __value = 1 };
151      typedef __true_type __type;
152    };
153
154  //
155  // Integer types
156  //
157  template<typename _Tp>
158    struct __is_integer
159    {
160      enum { __value = 0 };
161      typedef __false_type __type;
162    };
163
164  // Thirteen specializations (yes there are eleven standard integer
165  // types; 'long long' and 'unsigned long long' are supported as
166  // extensions)
167  template<>
168    struct __is_integer<bool>
169    {
170      enum { __value = 1 };
171      typedef __true_type __type;
172    };
173
174  template<>
175    struct __is_integer<char>
176    {
177      enum { __value = 1 };
178      typedef __true_type __type;
179    };
180
181  template<>
182    struct __is_integer<signed char>
183    {
184      enum { __value = 1 };
185      typedef __true_type __type;
186    };
187
188  template<>
189    struct __is_integer<unsigned char>
190    {
191      enum { __value = 1 };
192      typedef __true_type __type;
193    };
194
195# ifdef _GLIBCXX_USE_WCHAR_T
196  template<>
197    struct __is_integer<wchar_t>
198    {
199      enum { __value = 1 };
200      typedef __true_type __type;
201    };
202# endif
203
204  template<>
205    struct __is_integer<short>
206    {
207      enum { __value = 1 };
208      typedef __true_type __type;
209    };
210
211  template<>
212    struct __is_integer<unsigned short>
213    {
214      enum { __value = 1 };
215      typedef __true_type __type;
216    };
217
218  template<>
219    struct __is_integer<int>
220    {
221      enum { __value = 1 };
222      typedef __true_type __type;
223    };
224
225  template<>
226    struct __is_integer<unsigned int>
227    {
228      enum { __value = 1 };
229      typedef __true_type __type;
230    };
231
232  template<>
233    struct __is_integer<long>
234    {
235      enum { __value = 1 };
236      typedef __true_type __type;
237    };
238
239  template<>
240    struct __is_integer<unsigned long>
241    {
242      enum { __value = 1 };
243      typedef __true_type __type;
244    };
245
246  template<>
247    struct __is_integer<long long>
248    {
249      enum { __value = 1 };
250      typedef __true_type __type;
251    };
252
253  template<>
254    struct __is_integer<unsigned long long>
255    {
256      enum { __value = 1 };
257      typedef __true_type __type;
258    };
259
260  //
261  // Floating point types
262  //
263  template<typename _Tp>
264    struct __is_floating
265    {
266      enum { __value = 0 };
267      typedef __false_type __type;
268    };
269
270  // three specializations (float, double and 'long double')
271  template<>
272    struct __is_floating<float>
273    {
274      enum { __value = 1 };
275      typedef __true_type __type;
276    };
277
278  template<>
279    struct __is_floating<double>
280    {
281      enum { __value = 1 };
282      typedef __true_type __type;
283    };
284
285  template<>
286    struct __is_floating<long double>
287    {
288      enum { __value = 1 };
289      typedef __true_type __type;
290    };
291
292  //
293  // Pointer types
294  //
295  template<typename _Tp>
296    struct __is_pointer
297    {
298      enum { __value = 0 };
299      typedef __false_type __type;
300    };
301
302  template<typename _Tp>
303    struct __is_pointer<_Tp*>
304    {
305      enum { __value = 1 };
306      typedef __true_type __type;
307    };
308
309  //
310  // Normal iterator type
311  //
312  template<typename _Tp>
313    struct __is_normal_iterator
314    {
315      enum { __value = 0 };
316      typedef __false_type __type;
317    };
318
319  template<typename _Iterator, typename _Container>
320    struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
321							      _Container> >
322    {
323      enum { __value = 1 };
324      typedef __true_type __type;
325    };
326
327  //
328  // An arithmetic type is an integer type or a floating point type
329  //
330  template<typename _Tp>
331    struct __is_arithmetic
332    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
333    { };
334
335  //
336  // A fundamental type is `void' or and arithmetic type
337  //
338  template<typename _Tp>
339    struct __is_fundamental
340    : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
341    { };
342
343  //
344  // A scalar type is an arithmetic type or a pointer type
345  //
346  template<typename _Tp>
347    struct __is_scalar
348    : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
349    { };
350
351  // For the immediate use, the following is a good approximation.
352  template<typename _Tp>
353    struct __is_pod
354    {
355      enum
356	{
357	  __value = (sizeof(__detail::__test_type<_Tp>(0))
358		     != sizeof(__detail::__one))
359	};
360    };
361
362  //
363  // A stripped-down version of std::tr1::is_empty
364  //
365  template<typename _Tp>
366    struct __is_empty
367    {
368    private:
369      template<typename>
370        struct __first { };
371      template<typename _Up>
372        struct __second
373        : public _Up { };
374
375    public:
376      enum
377	{
378	  __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
379	};
380    };
381
382  //
383  // For use in std::copy and std::find overloads for streambuf iterators.
384  //
385  template<typename _Tp>
386    struct __is_char
387    {
388      enum { __value = 0 };
389      typedef __false_type __type;
390    };
391
392  template<>
393    struct __is_char<char>
394    {
395      enum { __value = 1 };
396      typedef __true_type __type;
397    };
398
399#ifdef _GLIBCXX_USE_WCHAR_T
400  template<>
401    struct __is_char<wchar_t>
402    {
403      enum { __value = 1 };
404      typedef __true_type __type;
405    };
406#endif
407
408#ifdef __clang__
409#pragma clang diagnostic pop
410#endif
411
412_GLIBCXX_END_NAMESPACE
413
414#endif //_CPP_TYPE_TRAITS_H
415