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]
This commit is contained in:
Dave Abrahams
2001-01-24 01:44:05 +00:00
parent 37d08acea1
commit 4bfd4da650

View File

@@ -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 <bool is_specialized> struct digit_traits_select;
// numeric_limits is specialized; just select that version of digits
template <> struct digit_traits_select<true>
{
template <class T> struct traits
{
enum { digits = std::numeric_limits<T>::digits };
};
};
// numeric_limits is not specialized; compute digits from sizeof(T)
template <> struct digit_traits_select<false>
{
template <class T> struct traits
{
enum { digits = sizeof(T) * std::numeric_limits<unsigned char>::digits
- (is_signed<T>::value ? 1 : 0)
};
};
};
// here's the "usable" template
template <class T> struct digit_traits
{
enum {
digits = digit_traits_select<
std::numeric_limits<T>::is_specialized
>::template traits<T>::digits
};
};
#endif
// Template class integer_traits<Integer> -- traits of various integer types
// This should probably be rolled into boost::integer_traits one day, but I
// need it to work without <limits>
@@ -104,24 +145,27 @@ namespace boost { namespace detail {
typedef Integer integer_type;
typedef std::numeric_limits<integer_type> 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<x::is_signed
& !(x::is_bounded
| x::digits >= std::numeric_limits<boost::intmax_t>::digits)>::template then<
if_true<(x::is_signed
&& (!x::is_bounded
// digits is the number of no-sign bits
|| (x::digits + 1 >= digit_traits<boost::intmax_t>::digits)))>::template then<
Integer,
typename if_true<(x::digits < std::numeric_limits<signed int>::digits)>::template then<
typename if_true<(x::digits + 1 < digit_traits<signed int>::digits)>::template then<
signed int,
typename if_true<(x::digits < std::numeric_limits<signed long>::digits)>::template then<
typename if_true<(x::digits + 1 < digit_traits<signed long>::digits)>::template then<
signed long,
// else