forked from boostorg/detail
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:
@@ -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
|
||||
|
Reference in New Issue
Block a user