epoc32/include/stdapis/boost/detail/numeric_traits.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     1 // (C) Copyright David Abrahams 2001, Howard Hinnant 2001.
       
     2 //
       
     3 // Distributed under the Boost Software License, Version 1.0. (See
       
     4 // accompanying file LICENSE_1_0.txt or copy at
       
     5 // http://www.boost.org/LICENSE_1_0.txt)
       
     6 //
       
     7 // Template class numeric_traits<Number> --
       
     8 //
       
     9 //    Supplies:
       
    10 //
       
    11 //      typedef difference_type -- a type used to represent the difference
       
    12 //      between any two values of Number.
       
    13 //
       
    14 //    Support:
       
    15 //      1. Not all specializations are supplied
       
    16 //
       
    17 //      2. Use of specializations that are not supplied will cause a
       
    18 //      compile-time error
       
    19 //
       
    20 //      3. Users are free to specialize numeric_traits for any type.
       
    21 //
       
    22 //      4. Right now, specializations are only supplied for integer types.
       
    23 //
       
    24 //      5. On implementations which do not supply compile-time constants in
       
    25 //      std::numeric_limits<>, only specializations for built-in integer types
       
    26 //      are supplied.
       
    27 //
       
    28 //      6. Handling of numbers whose range of representation is at least as
       
    29 //      great as boost::intmax_t can cause some differences to be
       
    30 //      unrepresentable in difference_type:
       
    31 //
       
    32 //        Number    difference_type
       
    33 //        ------    ---------------
       
    34 //        signed    Number
       
    35 //        unsigned  intmax_t
       
    36 //
       
    37 // template <class Number> typename numeric_traits<Number>::difference_type
       
    38 // numeric_distance(Number x, Number y)
       
    39 //    computes (y - x), attempting to avoid overflows.
       
    40 //
       
    41 
       
    42 // See http://www.boost.org for most recent version including documentation.
       
    43 
       
    44 // Revision History
       
    45 // 11 Feb 2001 - Use BOOST_STATIC_CONSTANT (David Abrahams)
       
    46 // 11 Feb 2001 - Rolled back ineffective Borland-specific code
       
    47 //               (David Abrahams)
       
    48 // 10 Feb 2001 - Rolled in supposed Borland fixes from John Maddock, but
       
    49 //               not seeing any improvement yet (David Abrahams)
       
    50 // 06 Feb 2001 - Factored if_true out into boost/detail/select_type.hpp
       
    51 //               (David Abrahams)
       
    52 // 23 Jan 2001 - Fixed logic of difference_type selection, which was
       
    53 //               completely wack. In the process, added digit_traits<>
       
    54 //               to compute the number of digits in intmax_t even when
       
    55 //               not supplied by numeric_limits<>. (David Abrahams)
       
    56 // 21 Jan 2001 - Created (David Abrahams)
       
    57 
       
    58 #ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901
       
    59 # define BOOST_NUMERIC_TRAITS_HPP_DWA20001901
       
    60 
       
    61 # include <boost/config.hpp>
       
    62 # include <boost/cstdint.hpp>
       
    63 # include <boost/static_assert.hpp>
       
    64 # include <boost/type_traits.hpp>
       
    65 # include <boost/detail/select_type.hpp>
       
    66 # include <boost/limits.hpp>
       
    67 
       
    68 namespace boost { namespace detail {
       
    69 
       
    70   // Template class is_signed -- determine whether a numeric type is signed
       
    71   // Requires that T is constructable from the literals -1 and 0.  Compile-time
       
    72   // error results if that requirement is not met (and thus signedness is not
       
    73   // likely to have meaning for that type).
       
    74   template <class Number>
       
    75   struct is_signed
       
    76   {
       
    77 #if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300
       
    78     BOOST_STATIC_CONSTANT(bool, value = (Number(-1) < Number(0)));
       
    79 #else
       
    80     BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<Number>::is_signed);
       
    81 #endif
       
    82   };
       
    83 
       
    84 # ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       
    85   // digit_traits - compute the number of digits in a built-in integer
       
    86   // type. Needed for implementations on which numeric_limits is not specialized
       
    87   // for intmax_t (e.g. VC6).
       
    88   template <bool is_specialized> struct digit_traits_select;
       
    89 
       
    90   // numeric_limits is specialized; just select that version of digits
       
    91   template <> struct digit_traits_select<true>
       
    92   {
       
    93       template <class T> struct traits
       
    94       {
       
    95           BOOST_STATIC_CONSTANT(int, digits = std::numeric_limits<T>::digits);
       
    96       };
       
    97   };
       
    98 
       
    99   // numeric_limits is not specialized; compute digits from sizeof(T)
       
   100   template <> struct digit_traits_select<false>
       
   101   {
       
   102       template <class T> struct traits
       
   103       {
       
   104           BOOST_STATIC_CONSTANT(int, digits = (
       
   105               sizeof(T) * std::numeric_limits<unsigned char>::digits
       
   106               - (is_signed<T>::value ? 1 : 0))
       
   107               );
       
   108       };
       
   109   };
       
   110 
       
   111   // here's the "usable" template
       
   112   template <class T> struct digit_traits
       
   113   {
       
   114       typedef digit_traits_select<
       
   115                 ::std::numeric_limits<T>::is_specialized> selector;
       
   116       typedef typename selector::template traits<T> traits;
       
   117       BOOST_STATIC_CONSTANT(int, digits = traits::digits);
       
   118   };
       
   119 #endif
       
   120 
       
   121   // Template class integer_traits<Integer> -- traits of various integer types
       
   122   // This should probably be rolled into boost::integer_traits one day, but I
       
   123   // need it to work without <limits>
       
   124   template <class Integer>
       
   125   struct integer_traits
       
   126   {
       
   127 # ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       
   128    private:
       
   129       typedef Integer integer_type;
       
   130       typedef std::numeric_limits<integer_type> x;
       
   131 #   if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
       
   132       // for some reason, MSVC asserts when it shouldn't unless we make these
       
   133       // local definitions
       
   134       BOOST_STATIC_CONSTANT(bool, is_integer = x::is_integer);
       
   135       BOOST_STATIC_CONSTANT(bool, is_specialized = x::is_specialized);
       
   136       
       
   137       BOOST_STATIC_ASSERT(is_integer);
       
   138       BOOST_STATIC_ASSERT(is_specialized);
       
   139 #   endif
       
   140    public:
       
   141       typedef typename
       
   142       if_true<(int(x::is_signed)
       
   143               && (!int(x::is_bounded)
       
   144                  // digits is the number of no-sign bits
       
   145                   || (int(x::digits) + 1 >= digit_traits<boost::intmax_t>::digits)))>::template then<
       
   146         Integer,
       
   147           
       
   148       typename if_true<(int(x::digits) + 1 < digit_traits<signed int>::digits)>::template then<
       
   149         signed int,
       
   150 
       
   151       typename if_true<(int(x::digits) + 1 < digit_traits<signed long>::digits)>::template then<
       
   152         signed long,
       
   153 
       
   154    // else
       
   155         intmax_t
       
   156       >::type>::type>::type difference_type;
       
   157 #else
       
   158       BOOST_STATIC_ASSERT(boost::is_integral<Integer>::value);
       
   159 
       
   160       typedef typename
       
   161       if_true<(sizeof(Integer) >= sizeof(intmax_t))>::template then<
       
   162                
       
   163         typename if_true<(is_signed<Integer>::value)>::template then<
       
   164           Integer,
       
   165           intmax_t
       
   166         >::type,
       
   167 
       
   168         typename if_true<(sizeof(Integer) < sizeof(std::ptrdiff_t))>::template then<
       
   169           std::ptrdiff_t,
       
   170           intmax_t
       
   171         >::type
       
   172       >::type difference_type;
       
   173 # endif
       
   174   };
       
   175 
       
   176   // Right now, only supports integers, but should be expanded.
       
   177   template <class Number>
       
   178   struct numeric_traits
       
   179   {
       
   180       typedef typename integer_traits<Number>::difference_type difference_type;
       
   181   };
       
   182 
       
   183   template <class Number>
       
   184   typename numeric_traits<Number>::difference_type numeric_distance(Number x, Number y)
       
   185   {
       
   186       typedef typename numeric_traits<Number>::difference_type difference_type;
       
   187       return difference_type(y) - difference_type(x);
       
   188   }
       
   189 }}
       
   190 
       
   191 #endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901