cpp_type_traits.h revision 169691
197403Sobrien// The  -*- C++ -*- type traits classes for internal use in libstdc++
297403Sobrien
3169691Skan// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169691Skan// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/** @file cpp_type_traits.h
3297403Sobrien *  This is an internal header file, included by other library headers.
3397403Sobrien *  You should not attempt to use it directly.
3497403Sobrien */
3597403Sobrien
36169691Skan// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
37169691Skan
38132720Skan#ifndef _CPP_TYPE_TRAITS_H
39132720Skan#define _CPP_TYPE_TRAITS_H 1
4097403Sobrien
4197403Sobrien#pragma GCC system_header
4297403Sobrien
43169691Skan#include <bits/c++config.h>
44169691Skan
4597403Sobrien//
4697403Sobrien// This file provides some compile-time information about various types.
4797403Sobrien// These representations were designed, on purpose, to be constant-expressions
48169691Skan// and not types as found in <bits/type_traits.h>.  In particular, they
4997403Sobrien// can be used in control structures and the optimizer hopefully will do
5097403Sobrien// the obvious thing.
5197403Sobrien//
5297403Sobrien// Why integral expressions, and not functions nor types?
5397403Sobrien// Firstly, these compile-time entities are used as template-arguments
5497403Sobrien// so function return values won't work:  We need compile-time entities.
5597403Sobrien// We're left with types and constant  integral expressions.
5697403Sobrien// Secondly, from the point of view of ease of use, type-based compile-time
5797403Sobrien// information is -not- *that* convenient.  On has to write lots of
5897403Sobrien// overloaded functions and to hope that the compiler will select the right
5997403Sobrien// one. As a net effect, the overall structure isn't very clear at first
6097403Sobrien// glance.
6197403Sobrien// Thirdly, partial ordering and overload resolution (of function templates)
6297403Sobrien// is highly costly in terms of compiler-resource.  It is a Good Thing to
6397403Sobrien// keep these resource consumption as least as possible.
6497403Sobrien//
6597403Sobrien// See valarray_array.h for a case use.
6697403Sobrien//
6797403Sobrien// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
6897403Sobrien//
69169691Skan// Update 2005: types are also provided and <bits/type_traits.h> has been
70169691Skan// removed.
71169691Skan//
7297403Sobrien
73169691Skan// Forward declaration hack, should really include this from somewhere.
74169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75169691Skan
76169691Skan  template<typename _Iterator, typename _Container>
77169691Skan    class __normal_iterator;
78169691Skan
79169691Skan_GLIBCXX_END_NAMESPACE
80169691Skan
81169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
82169691Skan
83169691Skannamespace __detail
84132720Skan{
85169691Skan  // NB: g++ can not compile these if declared within the class
86169691Skan  // __is_pod itself.
87132720Skan  typedef char __one;
88132720Skan  typedef char __two[2];
89132720Skan
90169691Skan  template<typename _Tp>
91169691Skan  __one __test_type(int _Tp::*);
92169691Skan  template<typename _Tp>
93169691Skan  __two& __test_type(...);
94169691Skan} // namespace __detail
95132720Skan
96169691Skan
97169691Skan  struct __true_type { };
98169691Skan  struct __false_type { };
99169691Skan
100169691Skan  template<bool>
101169691Skan    struct __truth_type
102169691Skan    { typedef __false_type __type; };
103169691Skan
104169691Skan  template<>
105169691Skan    struct __truth_type<true>
106169691Skan    { typedef __true_type __type; };
107169691Skan
108169691Skan  // N.B. The conversions to bool are needed due to the issue
109169691Skan  // explained in c++/19404.
110169691Skan  template<class _Sp, class _Tp>
111169691Skan    struct __traitor
112169691Skan    {
113169691Skan      enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
114169691Skan      typedef typename __truth_type<__value>::__type __type;
115169691Skan    };
116169691Skan
117132720Skan  // Compare for equality of types.
118132720Skan  template<typename, typename>
119132720Skan    struct __are_same
120132720Skan    {
121169691Skan      enum { __value = 0 };
122169691Skan      typedef __false_type __type;
123132720Skan    };
124132720Skan
12597403Sobrien  template<typename _Tp>
126132720Skan    struct __are_same<_Tp, _Tp>
127132720Skan    {
128169691Skan      enum { __value = 1 };
129169691Skan      typedef __true_type __type;
130132720Skan    };
131132720Skan
132132720Skan  // Holds if the template-argument is a void type.
133132720Skan  template<typename _Tp>
13497403Sobrien    struct __is_void
13597403Sobrien    {
136169691Skan      enum { __value = 0 };
137169691Skan      typedef __false_type __type;
13897403Sobrien    };
13997403Sobrien
14097403Sobrien  template<>
14197403Sobrien    struct __is_void<void>
14297403Sobrien    {
143169691Skan      enum { __value = 1 };
144169691Skan      typedef __true_type __type;
14597403Sobrien    };
14697403Sobrien
14797403Sobrien  //
14897403Sobrien  // Integer types
14997403Sobrien  //
15097403Sobrien  template<typename _Tp>
15197403Sobrien    struct __is_integer
15297403Sobrien    {
153169691Skan      enum { __value = 0 };
154169691Skan      typedef __false_type __type;
15597403Sobrien    };
15697403Sobrien
15797403Sobrien  // Thirteen specializations (yes there are eleven standard integer
15897403Sobrien  // types; 'long long' and 'unsigned long long' are supported as
15997403Sobrien  // extensions)
16097403Sobrien  template<>
16197403Sobrien    struct __is_integer<bool>
16297403Sobrien    {
163169691Skan      enum { __value = 1 };
164169691Skan      typedef __true_type __type;
16597403Sobrien    };
166132720Skan
16797403Sobrien  template<>
16897403Sobrien    struct __is_integer<char>
16997403Sobrien    {
170169691Skan      enum { __value = 1 };
171169691Skan      typedef __true_type __type;
17297403Sobrien    };
17397403Sobrien
17497403Sobrien  template<>
17597403Sobrien    struct __is_integer<signed char>
17697403Sobrien    {
177169691Skan      enum { __value = 1 };
178169691Skan      typedef __true_type __type;
17997403Sobrien    };
180132720Skan
18197403Sobrien  template<>
182132720Skan    struct __is_integer<unsigned char>
18397403Sobrien    {
184169691Skan      enum { __value = 1 };
185169691Skan      typedef __true_type __type;
18697403Sobrien    };
18797403Sobrien
188132720Skan# ifdef _GLIBCXX_USE_WCHAR_T
18997403Sobrien  template<>
190132720Skan    struct __is_integer<wchar_t>
19197403Sobrien    {
192169691Skan      enum { __value = 1 };
193169691Skan      typedef __true_type __type;
19497403Sobrien    };
19597403Sobrien# endif
196132720Skan
19797403Sobrien  template<>
198132720Skan    struct __is_integer<short>
19997403Sobrien    {
200169691Skan      enum { __value = 1 };
201169691Skan      typedef __true_type __type;
20297403Sobrien    };
20397403Sobrien
20497403Sobrien  template<>
205132720Skan    struct __is_integer<unsigned short>
20697403Sobrien    {
207169691Skan      enum { __value = 1 };
208169691Skan      typedef __true_type __type;
20997403Sobrien    };
21097403Sobrien
21197403Sobrien  template<>
212132720Skan    struct __is_integer<int>
21397403Sobrien    {
214169691Skan      enum { __value = 1 };
215169691Skan      typedef __true_type __type;
21697403Sobrien    };
21797403Sobrien
21897403Sobrien  template<>
219132720Skan    struct __is_integer<unsigned int>
22097403Sobrien    {
221169691Skan      enum { __value = 1 };
222169691Skan      typedef __true_type __type;
22397403Sobrien    };
22497403Sobrien
22597403Sobrien  template<>
226132720Skan    struct __is_integer<long>
22797403Sobrien    {
228169691Skan      enum { __value = 1 };
229169691Skan      typedef __true_type __type;
23097403Sobrien    };
23197403Sobrien
23297403Sobrien  template<>
233132720Skan    struct __is_integer<unsigned long>
23497403Sobrien    {
235169691Skan      enum { __value = 1 };
236169691Skan      typedef __true_type __type;
23797403Sobrien    };
23897403Sobrien
23997403Sobrien  template<>
240132720Skan    struct __is_integer<long long>
24197403Sobrien    {
242169691Skan      enum { __value = 1 };
243169691Skan      typedef __true_type __type;
24497403Sobrien    };
24597403Sobrien
24697403Sobrien  template<>
247132720Skan    struct __is_integer<unsigned long long>
24897403Sobrien    {
249169691Skan      enum { __value = 1 };
250169691Skan      typedef __true_type __type;
25197403Sobrien    };
25297403Sobrien
25397403Sobrien  //
25497403Sobrien  // Floating point types
25597403Sobrien  //
25697403Sobrien  template<typename _Tp>
257132720Skan    struct __is_floating
25897403Sobrien    {
259169691Skan      enum { __value = 0 };
260169691Skan      typedef __false_type __type;
26197403Sobrien    };
26297403Sobrien
26397403Sobrien  // three specializations (float, double and 'long double')
26497403Sobrien  template<>
265132720Skan    struct __is_floating<float>
26697403Sobrien    {
267169691Skan      enum { __value = 1 };
268169691Skan      typedef __true_type __type;
26997403Sobrien    };
27097403Sobrien
27197403Sobrien  template<>
272132720Skan    struct __is_floating<double>
27397403Sobrien    {
274169691Skan      enum { __value = 1 };
275169691Skan      typedef __true_type __type;
27697403Sobrien    };
27797403Sobrien
27897403Sobrien  template<>
279132720Skan    struct __is_floating<long double>
28097403Sobrien    {
281169691Skan      enum { __value = 1 };
282169691Skan      typedef __true_type __type;
28397403Sobrien    };
28497403Sobrien
28597403Sobrien  //
286169691Skan  // Pointer types
28797403Sobrien  //
28897403Sobrien  template<typename _Tp>
289169691Skan    struct __is_pointer
29097403Sobrien    {
291169691Skan      enum { __value = 0 };
292169691Skan      typedef __false_type __type;
29397403Sobrien    };
294169691Skan
295169691Skan  template<typename _Tp>
296169691Skan    struct __is_pointer<_Tp*>
297169691Skan    {
298169691Skan      enum { __value = 1 };
299169691Skan      typedef __true_type __type;
300169691Skan    };
301169691Skan
30297403Sobrien  //
303169691Skan  // Normal iterator type
304169691Skan  //
305169691Skan  template<typename _Tp>
306169691Skan    struct __is_normal_iterator
307169691Skan    {
308169691Skan      enum { __value = 0 };
309169691Skan      typedef __false_type __type;
310169691Skan    };
311169691Skan
312169691Skan  template<typename _Iterator, typename _Container>
313169691Skan    struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
314169691Skan							      _Container> >
315169691Skan    {
316169691Skan      enum { __value = 1 };
317169691Skan      typedef __true_type __type;
318169691Skan    };
319169691Skan
320169691Skan  //
321169691Skan  // An arithmetic type is an integer type or a floating point type
322169691Skan  //
323169691Skan  template<typename _Tp>
324169691Skan    struct __is_arithmetic
325169691Skan    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
326169691Skan    { };
327169691Skan
328169691Skan  //
32997403Sobrien  // A fundamental type is `void' or and arithmetic type
33097403Sobrien  //
33197403Sobrien  template<typename _Tp>
332132720Skan    struct __is_fundamental
333169691Skan    : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
334169691Skan    { };
335169691Skan
336169691Skan  //
337169691Skan  // A scalar type is an arithmetic type or a pointer type
338169691Skan  //
339169691Skan  template<typename _Tp>
340169691Skan    struct __is_scalar
341169691Skan    : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
342169691Skan    { };
343169691Skan
344169691Skan  // For the immediate use, the following is a good approximation.
345169691Skan  template<typename _Tp>
346169691Skan    struct __is_pod
34797403Sobrien    {
348132720Skan      enum
349132720Skan	{
350169691Skan	  __value = (sizeof(__detail::__test_type<_Tp>(0))
351169691Skan		     != sizeof(__detail::__one))
352132720Skan	};
35397403Sobrien    };
35497403Sobrien
35597403Sobrien  //
356169691Skan  // A stripped-down version of std::tr1::is_empty
35797403Sobrien  //
35897403Sobrien  template<typename _Tp>
359169691Skan    struct __is_empty
360169691Skan    {
361169691Skan    private:
362169691Skan      template<typename>
363169691Skan        struct __first { };
364169691Skan      template<typename _Up>
365169691Skan        struct __second
366169691Skan        : public _Up { };
367169691Skan
368169691Skan    public:
369132720Skan      enum
370132720Skan	{
371169691Skan	  __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
372132720Skan	};
37397403Sobrien    };
37497403Sobrien
375169691Skan  //
376169691Skan  // For use in std::copy and std::find overloads for streambuf iterators.
377169691Skan  //
378169691Skan  template<typename _Tp>
379169691Skan    struct __is_char
380169691Skan    {
381169691Skan      enum { __value = 0 };
382169691Skan      typedef __false_type __type;
383169691Skan    };
38497403Sobrien
385169691Skan  template<>
386169691Skan    struct __is_char<char>
387169691Skan    {
388169691Skan      enum { __value = 1 };
389169691Skan      typedef __true_type __type;
390169691Skan    };
391169691Skan
392169691Skan#ifdef _GLIBCXX_USE_WCHAR_T
393169691Skan  template<>
394169691Skan    struct __is_char<wchar_t>
395169691Skan    {
396169691Skan      enum { __value = 1 };
397169691Skan      typedef __true_type __type;
398169691Skan    };
399169691Skan#endif
400169691Skan
401169691Skan_GLIBCXX_END_NAMESPACE
402169691Skan
403132720Skan#endif //_CPP_TYPE_TRAITS_H
404