mirror of
https://github.com/boostorg/detail.git
synced 2025-08-02 13:54:27 +02:00
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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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
|
// 21 Jan 2001 - Created
|
||||||
|
|
||||||
#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901
|
#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901
|
||||||
@@ -93,6 +97,43 @@ namespace boost { namespace detail {
|
|||||||
enum { value = (Number(-1) < Number(0)) };
|
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
|
// Template class integer_traits<Integer> -- traits of various integer types
|
||||||
// This should probably be rolled into boost::integer_traits one day, but I
|
// This should probably be rolled into boost::integer_traits one day, but I
|
||||||
// need it to work without <limits>
|
// need it to work without <limits>
|
||||||
@@ -104,24 +145,27 @@ namespace boost { namespace detail {
|
|||||||
typedef Integer integer_type;
|
typedef Integer integer_type;
|
||||||
typedef std::numeric_limits<integer_type> x;
|
typedef std::numeric_limits<integer_type> x;
|
||||||
# ifdef BOOST_MSVC
|
# 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
|
# endif
|
||||||
public:
|
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
|
typedef typename
|
||||||
if_true<x::is_signed
|
if_true<(x::is_signed
|
||||||
& !(x::is_bounded
|
&& (!x::is_bounded
|
||||||
| x::digits >= std::numeric_limits<boost::intmax_t>::digits)>::template then<
|
// digits is the number of no-sign bits
|
||||||
|
|| (x::digits + 1 >= digit_traits<boost::intmax_t>::digits)))>::template then<
|
||||||
Integer,
|
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,
|
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,
|
signed long,
|
||||||
|
|
||||||
// else
|
// else
|
||||||
|
Reference in New Issue
Block a user