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
83namespace __detail
84{
85  // NB: g++ can not compile these if declared within the class
86  // __is_pod itself.
87  typedef char __one;
88  typedef char __two[2];
89
90  template<typename _Tp>
91  __one __test_type(int _Tp::*);
92  template<typename _Tp>
93  __two& __test_type(...);
94} // namespace __detail
95
96
97  struct __true_type { };
98  struct __false_type { };
99
100  template<bool>
101    struct __truth_type
102    { typedef __false_type __type; };
103
104  template<>
105    struct __truth_type<true>
106    { typedef __true_type __type; };
107
108  // N.B. The conversions to bool are needed due to the issue
109  // explained in c++/19404.
110  template<class _Sp, class _Tp>
111    struct __traitor
112    {
113      enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
114      typedef typename __truth_type<__value>::__type __type;
115    };
116
117  // Compare for equality of types.
118  template<typename, typename>
119    struct __are_same
120    {
121      enum { __value = 0 };
122      typedef __false_type __type;
123    };
124
125  template<typename _Tp>
126    struct __are_same<_Tp, _Tp>
127    {
128      enum { __value = 1 };
129      typedef __true_type __type;
130    };
131
132  // Holds if the template-argument is a void type.
133  template<typename _Tp>
134    struct __is_void
135    {
136      enum { __value = 0 };
137      typedef __false_type __type;
138    };
139
140  template<>
141    struct __is_void<void>
142    {
143      enum { __value = 1 };
144      typedef __true_type __type;
145    };
146
147  //
148  // Integer types
149  //
150  template<typename _Tp>
151    struct __is_integer
152    {
153      enum { __value = 0 };
154      typedef __false_type __type;
155    };
156
157  // Thirteen specializations (yes there are eleven standard integer
158  // types; 'long long' and 'unsigned long long' are supported as
159  // extensions)
160  template<>
161    struct __is_integer<bool>
162    {
163      enum { __value = 1 };
164      typedef __true_type __type;
165    };
166
167  template<>
168    struct __is_integer<char>
169    {
170      enum { __value = 1 };
171      typedef __true_type __type;
172    };
173
174  template<>
175    struct __is_integer<signed char>
176    {
177      enum { __value = 1 };
178      typedef __true_type __type;
179    };
180
181  template<>
182    struct __is_integer<unsigned char>
183    {
184      enum { __value = 1 };
185      typedef __true_type __type;
186    };
187
188# ifdef _GLIBCXX_USE_WCHAR_T
189  template<>
190    struct __is_integer<wchar_t>
191    {
192      enum { __value = 1 };
193      typedef __true_type __type;
194    };
195# endif
196
197  template<>
198    struct __is_integer<short>
199    {
200      enum { __value = 1 };
201      typedef __true_type __type;
202    };
203
204  template<>
205    struct __is_integer<unsigned short>
206    {
207      enum { __value = 1 };
208      typedef __true_type __type;
209    };
210
211  template<>
212    struct __is_integer<int>
213    {
214      enum { __value = 1 };
215      typedef __true_type __type;
216    };
217
218  template<>
219    struct __is_integer<unsigned int>
220    {
221      enum { __value = 1 };
222      typedef __true_type __type;
223    };
224
225  template<>
226    struct __is_integer<long>
227    {
228      enum { __value = 1 };
229      typedef __true_type __type;
230    };
231
232  template<>
233    struct __is_integer<unsigned long>
234    {
235      enum { __value = 1 };
236      typedef __true_type __type;
237    };
238
239  template<>
240    struct __is_integer<long long>
241    {
242      enum { __value = 1 };
243      typedef __true_type __type;
244    };
245
246  template<>
247    struct __is_integer<unsigned long long>
248    {
249      enum { __value = 1 };
250      typedef __true_type __type;
251    };
252
253  //
254  // Floating point types
255  //
256  template<typename _Tp>
257    struct __is_floating
258    {
259      enum { __value = 0 };
260      typedef __false_type __type;
261    };
262
263  // three specializations (float, double and 'long double')
264  template<>
265    struct __is_floating<float>
266    {
267      enum { __value = 1 };
268      typedef __true_type __type;
269    };
270
271  template<>
272    struct __is_floating<double>
273    {
274      enum { __value = 1 };
275      typedef __true_type __type;
276    };
277
278  template<>
279    struct __is_floating<long double>
280    {
281      enum { __value = 1 };
282      typedef __true_type __type;
283    };
284
285  //
286  // Pointer types
287  //
288  template<typename _Tp>
289    struct __is_pointer
290    {
291      enum { __value = 0 };
292      typedef __false_type __type;
293    };
294
295  template<typename _Tp>
296    struct __is_pointer<_Tp*>
297    {
298      enum { __value = 1 };
299      typedef __true_type __type;
300    };
301
302  //
303  // Normal iterator type
304  //
305  template<typename _Tp>
306    struct __is_normal_iterator
307    {
308      enum { __value = 0 };
309      typedef __false_type __type;
310    };
311
312  template<typename _Iterator, typename _Container>
313    struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
314							      _Container> >
315    {
316      enum { __value = 1 };
317      typedef __true_type __type;
318    };
319
320  //
321  // An arithmetic type is an integer type or a floating point type
322  //
323  template<typename _Tp>
324    struct __is_arithmetic
325    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
326    { };
327
328  //
329  // A fundamental type is `void' or and arithmetic type
330  //
331  template<typename _Tp>
332    struct __is_fundamental
333    : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
334    { };
335
336  //
337  // A scalar type is an arithmetic type or a pointer type
338  //
339  template<typename _Tp>
340    struct __is_scalar
341    : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
342    { };
343
344#if defined(__has_feature)
345#if __has_feature(objc_arc) && !defined(_GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR)
346  /// Objective-C++ Automatic Reference Counting uses qualified pointers
347  /// that are pointer types but are *not* scalar types because they are not
348  /// POD types. When _GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR is defined,
349  /// the compiler itself is providing these definitions. Otherwise, we
350  /// provide them.
351  template<typename _Tp>
352  struct __is_scalar<__strong _Tp> {
353    enum { __value = 0 };
354    typedef __false_type __type;
355  };
356
357  #if __has_feature(objc_arc_weak)
358  template<typename _Tp>
359  struct __is_scalar<__weak _Tp> {
360    enum { __value = 0 };
361    typedef __false_type __type;
362  };
363  #endif
364
365  template<typename _Tp>
366  struct __is_scalar<__autoreleasing _Tp> {
367    enum { __value = 0 };
368    typedef __false_type __type;
369  };
370
371  template<typename _Tp>
372  struct __is_scalar<__unsafe_unretained _Tp> {
373    enum { __value = 0 };
374    typedef __false_type __type;
375  };
376#endif
377#endif
378
379  // For the immediate use, the following is a good approximation.
380  template<typename _Tp>
381    struct __is_pod
382    {
383      enum
384	{
385	  __value = (sizeof(__detail::__test_type<_Tp>(0))
386		     != sizeof(__detail::__one))
387	};
388    };
389
390  //
391  // A stripped-down version of std::tr1::is_empty
392  //
393  template<typename _Tp>
394    struct __is_empty
395    {
396    private:
397      template<typename>
398        struct __first { };
399      template<typename _Up>
400        struct __second
401        : public _Up { };
402
403    public:
404      enum
405	{
406	  __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
407	};
408    };
409
410  //
411  // For use in std::copy and std::find overloads for streambuf iterators.
412  //
413  template<typename _Tp>
414    struct __is_char
415    {
416      enum { __value = 0 };
417      typedef __false_type __type;
418    };
419
420  template<>
421    struct __is_char<char>
422    {
423      enum { __value = 1 };
424      typedef __true_type __type;
425    };
426
427#ifdef _GLIBCXX_USE_WCHAR_T
428  template<>
429    struct __is_char<wchar_t>
430    {
431      enum { __value = 1 };
432      typedef __true_type __type;
433    };
434#endif
435
436_GLIBCXX_END_NAMESPACE
437
438#endif //_CPP_TYPE_TRAITS_H
439