home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / cpp_type_traits.h < prev    next >
C/C++ Source or Header  |  2005-01-29  |  7KB  |  346 lines

  1. // The  -*- C++ -*- type traits classes for internal use in libstdc++
  2.  
  3. // Copyright (C) 2000, 2001, 2002, 2003, 2004 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 2, 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. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
  31.  
  32. /** @file cpp_type_traits.h
  33.  *  This is an internal header file, included by other library headers.
  34.  *  You should not attempt to use it directly.
  35.  */
  36.  
  37. #ifndef _CPP_TYPE_TRAITS_H
  38. #define _CPP_TYPE_TRAITS_H 1
  39.  
  40. #pragma GCC system_header
  41.  
  42. //
  43. // This file provides some compile-time information about various types.
  44. // These representations were designed, on purpose, to be constant-expressions
  45. // and not types as found in <stl/bits/type_traits.h>.  In particular, they
  46. // can be used in control structures and the optimizer hopefully will do
  47. // the obvious thing.
  48. //
  49. // Why integral expressions, and not functions nor types?
  50. // Firstly, these compile-time entities are used as template-arguments
  51. // so function return values won't work:  We need compile-time entities.
  52. // We're left with types and constant  integral expressions.
  53. // Secondly, from the point of view of ease of use, type-based compile-time
  54. // information is -not- *that* convenient.  On has to write lots of
  55. // overloaded functions and to hope that the compiler will select the right
  56. // one. As a net effect, the overall structure isn't very clear at first
  57. // glance.
  58. // Thirdly, partial ordering and overload resolution (of function templates)
  59. // is highly costly in terms of compiler-resource.  It is a Good Thing to
  60. // keep these resource consumption as least as possible.
  61. //
  62. // See valarray_array.h for a case use.
  63. //
  64. // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
  65. //
  66.  
  67. // NB: g++ can not compile these if declared within the class
  68. // __is_pod itself.
  69. namespace __gnu_internal
  70. {
  71.   typedef char __one;
  72.   typedef char __two[2];
  73.  
  74.   template <typename _Tp>
  75.   __one __test_type (int _Tp::*);
  76.   template <typename _Tp>
  77.   __two& __test_type (...);
  78. } // namespace __gnu_internal
  79.  
  80. namespace std
  81. {
  82.   // Compare for equality of types.
  83.   template<typename, typename>
  84.     struct __are_same
  85.     {
  86.       enum
  87.     {
  88.       _M_type = 0
  89.     };
  90.     };
  91.  
  92.   template<typename _Tp>
  93.     struct __are_same<_Tp, _Tp>
  94.     {
  95.       enum
  96.     {
  97.       _M_type = 1
  98.     };
  99.     };
  100.  
  101.   // Define a nested type if some predicate holds.
  102.   template<typename, bool>
  103.     struct __enable_if
  104.     {
  105.     };
  106.  
  107.   template<typename _Tp>
  108.     struct __enable_if<_Tp, true>
  109.     {
  110.       typedef _Tp _M_type;
  111.     };
  112.  
  113.   // Holds if the template-argument is a void type.
  114.   template<typename _Tp>
  115.     struct __is_void
  116.     {
  117.       enum
  118.     {
  119.       _M_type = 0
  120.     };
  121.     };
  122.  
  123.   template<>
  124.     struct __is_void<void>
  125.     {
  126.       enum
  127.     {
  128.       _M_type = 1
  129.     };
  130.     };
  131.  
  132.   //
  133.   // Integer types
  134.   //
  135.   template<typename _Tp>
  136.     struct __is_integer
  137.     {
  138.       enum
  139.     {
  140.       _M_type = 0
  141.     };
  142.     };
  143.  
  144.   // Thirteen specializations (yes there are eleven standard integer
  145.   // types; 'long long' and 'unsigned long long' are supported as
  146.   // extensions)
  147.   template<>
  148.     struct __is_integer<bool>
  149.     {
  150.       enum
  151.     {
  152.       _M_type = 1
  153.     };
  154.     };
  155.  
  156.   template<>
  157.     struct __is_integer<char>
  158.     {
  159.       enum
  160.     {
  161.       _M_type = 1
  162.     };
  163.     };
  164.  
  165.   template<>
  166.     struct __is_integer<signed char>
  167.     {
  168.       enum
  169.     {
  170.       _M_type = 1
  171.     };
  172.     };
  173.  
  174.   template<>
  175.     struct __is_integer<unsigned char>
  176.     {
  177.       enum
  178.     {
  179.       _M_type = 1
  180.     };
  181.     };
  182.  
  183. # ifdef _GLIBCXX_USE_WCHAR_T
  184.   template<>
  185.     struct __is_integer<wchar_t>
  186.     {
  187.       enum
  188.     {
  189.       _M_type = 1
  190.     };
  191.     };
  192. # endif
  193.  
  194.   template<>
  195.     struct __is_integer<short>
  196.     {
  197.       enum
  198.     {
  199.       _M_type = 1
  200.     };
  201.     };
  202.  
  203.   template<>
  204.     struct __is_integer<unsigned short>
  205.     {
  206.       enum
  207.     {
  208.       _M_type = 1
  209.     };
  210.     };
  211.  
  212.   template<>
  213.     struct __is_integer<int>
  214.     {
  215.       enum
  216.     {
  217.       _M_type = 1
  218.     };
  219.     };
  220.  
  221.   template<>
  222.     struct __is_integer<unsigned int>
  223.     {
  224.       enum
  225.     {
  226.       _M_type = 1
  227.     };
  228.     };
  229.  
  230.   template<>
  231.     struct __is_integer<long>
  232.     {
  233.       enum
  234.     {
  235.       _M_type = 1
  236.     };
  237.     };
  238.  
  239.   template<>
  240.     struct __is_integer<unsigned long>
  241.     {
  242.       enum
  243.     {
  244.       _M_type = 1
  245.     };
  246.     };
  247.  
  248.   template<>
  249.     struct __is_integer<long long>
  250.     {
  251.       enum
  252.     {
  253.       _M_type = 1
  254.     };
  255.     };
  256.  
  257.   template<>
  258.     struct __is_integer<unsigned long long>
  259.     {
  260.       enum
  261.     {
  262.       _M_type = 1
  263.     };
  264.     };
  265.  
  266.   //
  267.   // Floating point types
  268.   //
  269.   template<typename _Tp>
  270.     struct __is_floating
  271.     {
  272.       enum
  273.     {
  274.       _M_type = 0
  275.     };
  276.     };
  277.  
  278.   // three specializations (float, double and 'long double')
  279.   template<>
  280.     struct __is_floating<float>
  281.     {
  282.       enum
  283.     {
  284.       _M_type = 1
  285.     };
  286.     };
  287.  
  288.   template<>
  289.     struct __is_floating<double>
  290.     {
  291.       enum
  292.     {
  293.       _M_type = 1
  294.     };
  295.     };
  296.  
  297.   template<>
  298.     struct __is_floating<long double>
  299.     {
  300.       enum
  301.     {
  302.       _M_type = 1
  303.     };
  304.     };
  305.  
  306.   //
  307.   // An arithmetic type is an integer type or a floating point type
  308.   //
  309.   template<typename _Tp>
  310.     struct __is_arithmetic
  311.     {
  312.       enum
  313.     {
  314.       _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
  315.     };
  316.     };
  317.   
  318.   //
  319.   // A fundamental type is `void' or and arithmetic type
  320.   //
  321.   template<typename _Tp>
  322.     struct __is_fundamental
  323.     {
  324.       enum
  325.     {
  326.       _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
  327.     };
  328.     };
  329.  
  330.   //
  331.   // For the immediate use, the following is a good approximation
  332.   //
  333.   template<typename _Tp>
  334.     struct __is_pod
  335.     {
  336.       enum
  337.     {
  338.       _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0))
  339.              != sizeof(__gnu_internal::__one))
  340.     };
  341.     };
  342.  
  343. } // namespace std
  344.  
  345. #endif //_CPP_TYPE_TRAITS_H
  346.