From 4bfd4da65005c70ac90b632d771cd2d494fdf580 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 24 Jan 2001 01:44:05 +0000 Subject: [PATCH] Fixed logic of difference_type selection, which was completely wack. In the process, added digit_traits<> to compute the number of digits in intmax_t even when not supplied by numeric_limits<>. [SVN r8747] --- include/boost/detail/numeric_traits.hpp | 66 ++++++++++++++++++++----- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/include/boost/detail/numeric_traits.hpp b/include/boost/detail/numeric_traits.hpp index 0a96f06..9701ec6 100644 --- a/include/boost/detail/numeric_traits.hpp +++ b/include/boost/detail/numeric_traits.hpp @@ -49,6 +49,10 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 23 Jan 2001 - Fixed logic of difference_type selection, which was +// completely wack. In the process, added digit_traits<> +// to compute the number of digits in intmax_t even when +// not supplied by numeric_limits<>. // 21 Jan 2001 - Created #ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901 @@ -93,6 +97,43 @@ namespace boost { namespace detail { enum { value = (Number(-1) < Number(0)) }; }; +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + // digit_traits - compute the number of digits in a built-in integer + // type. Needed for implementations on which numeric_limits is not specialized + // for intmax_t (e.g. VC6). + template struct digit_traits_select; + + // numeric_limits is specialized; just select that version of digits + template <> struct digit_traits_select + { + template struct traits + { + enum { digits = std::numeric_limits::digits }; + }; + }; + + // numeric_limits is not specialized; compute digits from sizeof(T) + template <> struct digit_traits_select + { + template struct traits + { + enum { digits = sizeof(T) * std::numeric_limits::digits + - (is_signed::value ? 1 : 0) + }; + }; + }; + + // here's the "usable" template + template struct digit_traits + { + enum { + digits = digit_traits_select< + std::numeric_limits::is_specialized + >::template traits::digits + }; + }; +#endif + // Template class integer_traits -- traits of various integer types // This should probably be rolled into boost::integer_traits one day, but I // need it to work without @@ -104,24 +145,27 @@ namespace boost { namespace detail { typedef Integer integer_type; typedef std::numeric_limits x; # ifdef BOOST_MSVC - enum { is_integer = x::is_integer }; + // for some reason, MSVC asserts when it shouldn't unless we make these + // local definitions + enum { + is_integer = x::is_integer, + is_specialized = x::is_specialized + }; + BOOST_STATIC_ASSERT(is_integer); + BOOST_STATIC_ASSERT(is_specialized); # endif public: -# ifndef BOOST_MSVC // for some reason, this asserts when it shouldn't - BOOST_STATIC_ASSERT(x::is_integer); -# else - BOOST_STATIC_ASSERT(is_integer); -# endif typedef typename - if_true= std::numeric_limits::digits)>::template then< + if_true<(x::is_signed + && (!x::is_bounded + // digits is the number of no-sign bits + || (x::digits + 1 >= digit_traits::digits)))>::template then< Integer, - typename if_true<(x::digits < std::numeric_limits::digits)>::template then< + typename if_true<(x::digits + 1 < digit_traits::digits)>::template then< signed int, - typename if_true<(x::digits < std::numeric_limits::digits)>::template then< + typename if_true<(x::digits + 1 < digit_traits::digits)>::template then< signed long, // else