diff --git a/include/boost/detail/extended_integer.hpp b/include/boost/detail/extended_integer.hpp new file mode 100644 index 0000000..c69636c --- /dev/null +++ b/include/boost/detail/extended_integer.hpp @@ -0,0 +1,177 @@ +// Boost detail/extended_integer.hpp header file ----------------------------// + +// (C) Copyright Daryle Walker 2008. Distributed under the Boost Software +// License, Version 1.0. (See the accompanying file LICENSE_1_0.txt or a copy +// at .) + +// Encapsulates the double-long and __int64 type families as a single family, +// as they are mutually exclusive. + +/** \file + \brief Common definition of extended integer types. + + Instead of other Boost headers making separate \#defines for the double-long + and __int64 type families, since they're mutually exclusive, make a single + set of types and macros for the family that exists (if either). + */ + +#ifndef BOOST_DETAIL_EXTENDED_INTEGER_HPP +#define BOOST_DETAIL_EXTENDED_INTEGER_HPP + +#include // for BOOST_HAS_LONG_LONG and BOOST_HAS_MS_INT64 + +#include // for CHAR_BIT, etc. + + +namespace boost +{ +namespace detail +{ + + +// Extended integer type macro and alias definitions -----------------------// + +// (Unsigned) long long family +#ifdef BOOST_HAS_LONG_LONG + +// Existence +#define BOOST_HAS_XINT 1 + +// Extents +#ifdef ULLONG_MAX +#define BOOST_XINT_MAX LLONG_MAX +#define BOOST_XINT_MIN LLONG_MIN +#define BOOST_UXINT_MAX ULLONG_MAX +#elif defined(ULONG_LONG_MAX) +#define BOOST_XINT_MAX LONG_LONG_MAX +#define BOOST_XINT_MIN LONG_LONG_MIN +#define BOOST_UXINT_MAX ULONG_LONG_MAX +#elif defined(ULONGLONG_MAX) +#define BOOST_XINT_MAX LONGLONG_MAX +#define BOOST_XINT_MIN LONGLONG_MIN +#define BOOST_UXINT_MAX ULONGLONG_MAX +#elif defined(_LLONG_MAX) && defined(_C2) +#define BOOST_XINT_MAX _LLONG_MAX +#define BOOST_XINT_MIN (-_LLONG_MAX - _C2) +#define BOOST_UXINT_MAX _ULLONG_MAX +#else // guess +// Sometimes we get the double-long types without the corresponding constants, +// e.g. GCC in "-ansi" mode. In this case, we'll just have to work out the +// values ourselves. (Here we assume a two's complement representation.) +#define BOOST_XINT_MIN (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)) +#define BOOST_XINT_MAX (~ BOOST_XINT_MIN) +#define BOOST_UXINT_MAX (~ 0uLL) +#endif + +// Types +typedef ::boost:: long_long_type xint_t; +typedef ::boost::ulong_long_type uxint_t; + +// (Unsigned) __int64 family +#elif defined(BOOST_HAS_MS_INT64) + +// Existence +#define BOOST_HAS_XINT 1 + +// Extents +#ifdef _UI64_MAX +#define BOOST_XINT_MAX _I64_MAX +#define BOOST_XINT_MIN _I64_MIN +#define BOOST_UXINT_MAX _UI64_MAX +#else // guess +// The types are exactly 2's-compl. 64-bit, so we'll enter the values directly. +#define BOOST_XINT_MAX 0x7FFFFFFFFFFFFFFFi64 +#define BOOST_XINT_MIN 0x8000000000000000i64 +#define BOOST_UXINT_MAX 0xFFFFFFFFFFFFFFFFui64 +#endif + +// Types +typedef __int64 xint_t; +typedef unsigned __int64 uxint_t; + +// Neither +#else + +// Non-existence +#define BOOST_HAS_XINT 0 + +// Dummy extents +#define BOOST_XINT_MAX LONG_MAX +#define BOOST_XINT_MIN LONG_MIN +#define BOOST_UXINT_MAX ULONG_MAX + +// Dummy types +typedef signed long xint_t; +typedef unsigned long uxint_t; + +#endif // defined(BOOST_HAS_LONG_LONG)/defined(BOOST_HAS_MS_INT64)/else + +/** \def BOOST_HAS_XINT + + \brief Flag for extended integer types. + + Indicates the presence of one of the two common extended integer type + families, either (unsigned) long long or + (unsigned) __int64. \c BOOST_HAS_XINT is \c 1 if + either type family is defined, and \c 0 if neither is. + */ + +/** \def BOOST_XINT_MAX + + \brief Maximum value for the signed extended integer type. + + \pre \c BOOST_HAS_XINT is \c \#defined to be \c 1. + + Macro constant representing the largest value the signed extended integer + type supports. Its composition may be another macro, an expression, or a + literal. Defaulted to \c LONG_MAX if \c BOOST_HAS_XINT is zero. + */ +/** \def BOOST_XINT_MIN + + \brief Minimum value for the signed extended integer type. + + \pre \c BOOST_HAS_XINT is \c \#defined to be \c 1. + + Macro constant representing the smallest value the signed extended integer + type supports. Its composition may be another macro, an expression, or a + literal. Defaulted to \c LONG_MIN if \c BOOST_HAS_XINT is zero. + */ +/** \def BOOST_UXINT_MAX + + \brief Maximum value for the unsigned extended integer type. + + \pre \c BOOST_HAS_XINT is \c \#defined to be \c 1. + + Macro constant representing the largest value the unsigned extended integer + type supports. Its composition may be another macro, an expression, or a + literal. Defaulted to \c ULONG_MAX if \c BOOST_HAS_XINT is zero. (Use + \c 0u for the type's minimum value.) + */ + +/** \typedef signed long boost::detail::xint_t + + \brief Alias for the signed extended integer type. + + \pre \c BOOST_HAS_XINT is \c \#defined to be \c 1. + + Alias representing the signed extended integer type, no matter which type + family it came from. Defaulted to signed long if + \c BOOST_HAS_XINT is zero. + */ +/** \typedef unsigned long ::boost::detail::uxint_t + + \brief Alias for the signed extended integer type. + + \pre \c BOOST_HAS_XINT is \c \#defined to be \c 1. + + Alias representing the unsigned extended integer type, no matter which type + family it came from. Defaulted to unsigned long if + \c BOOST_HAS_XINT is zero. + */ + + +} // namespace detail +} // namespace boost + + +#endif // BOOST_DETAIL_EXTENDED_INTEGER_HPP diff --git a/include/boost/integer.hpp b/include/boost/integer.hpp index 7e0b86c..531b405 100644 --- a/include/boost/integer.hpp +++ b/include/boost/integer.hpp @@ -29,6 +29,8 @@ #include // for std::numeric_limits #include // for boost::enable_if_c +#include // for BOOST_HAS_XINT, etc. + #include // for UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, etc. namespace boost @@ -64,15 +66,9 @@ namespace detail // 3=unsigned/int, 4=(unsigned) short, 5=(un)signed char // no specializations for 0: requests for a type > (unsigned) (long) long are // in error -#ifdef BOOST_HAS_LONG_LONG - template<> struct int_least_helper<1, signed> - { typedef long_long_type least; }; - template<> struct int_least_helper<1, unsigned> - { typedef ulong_long_type least; }; -#elif defined(BOOST_HAS_MS_INT64) - template<> struct int_least_helper<1, signed> { typedef __int64 least; }; - template<> struct int_least_helper<1, unsigned> - { typedef unsigned __int64 least; }; +#if BOOST_HAS_XINT + template<> struct int_least_helper<1, signed> { typedef xint_t least; }; + template<> struct int_least_helper<1, unsigned> { typedef uxint_t least; }; #endif template<> struct int_least_helper<2, signed> { typedef long least; }; template<> struct int_least_helper<2, unsigned> @@ -90,7 +86,7 @@ namespace detail // category bounds enum { -#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64) +#if BOOST_HAS_XINT lowest_integral_rank = 1, #else lowest_integral_rank = 2, @@ -103,12 +99,9 @@ namespace detail struct int_rank_helper { BOOST_STATIC_CONSTANT( int, mantissa = BitsIncludingSign - 1 ); -#ifdef BOOST_HAS_LONG_LONG +#if BOOST_HAS_XINT BOOST_STATIC_CONSTANT( int, extended_ = (mantissa <= std::numeric_limits< - long_long_type >::digits) ); -#elif defined(BOOST_HAS_MS_INT64) - BOOST_STATIC_CONSTANT( int, extended_ = (mantissa <= std::numeric_limits< - __int64 >::digits) ); + xint_t >::digits) ); #else BOOST_STATIC_CONSTANT( int, extended_ = 1 ); #endif @@ -122,12 +115,9 @@ namespace detail template < int Bits > struct uint_rank_helper { -#ifdef BOOST_HAS_LONG_LONG +#if BOOST_HAS_XINT BOOST_STATIC_CONSTANT( int, extended_ = (Bits <= std::numeric_limits< - ulong_long_type >::digits) ); -#elif defined(BOOST_HAS_MS_INT64) - BOOST_STATIC_CONSTANT( int, extended_ = (Bits <= std::numeric_limits< - unsigned __int64 >::digits) ); + uxint_t >::digits) ); #else BOOST_STATIC_CONSTANT( int, extended_ = 1 ); #endif @@ -152,12 +142,9 @@ namespace detail struct uint_exact_rank_helper::digits> \ { BOOST_STATIC_CONSTANT( int, rank = Rank ); } -#if defined(BOOST_HAS_LONG_LONG) && ((ULLONG_MAX > ULONG_MAX) || (ULONGLONG_MAX > ULONG_MAX)) - BOOST_PRIVATE_INT_EXACT_BUILDER( long_long_type, 1 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( ulong_long_type, 1 ); -#elif defined(BOOST_HAS_MS_INT64) && (0xFFFFFFFFFFFFFFFFui64 > ULONG_MAX) - BOOST_PRIVATE_INT_EXACT_BUILDER( __int64, 1 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned __int64, 1 ); +#if BOOST_HAS_XINT && (BOOST_UXINT_MAX > ULONG_MAX) + BOOST_PRIVATE_INT_EXACT_BUILDER( xint_t, 1 ); + BOOST_PRIVATE_UINT_EXACT_BUILDER( uxint_t, 1 ); #endif #if ULONG_MAX > UINT_MAX BOOST_PRIVATE_INT_EXACT_BUILDER( long, 2 ); @@ -181,12 +168,9 @@ namespace detail template < intmax_t MaxValue > struct int_max_rank_helper { -#ifdef BOOST_HAS_LONG_LONG - BOOST_STATIC_CONSTANT( int, extended_ = (MaxValue <= boost::integer_traits< - long_long_type >::const_max) ); -#elif defined(BOOST_HAS_MS_INT64) - BOOST_STATIC_CONSTANT( int, extended_ = (MaxValue <= boost::integer_traits< - __int64 >::const_max) ); +#if BOOST_HAS_XINT + BOOST_STATIC_CONSTANT( int, extended_ = (MaxValue <= + boost::integer_traits< xint_t >::const_max) ); #else BOOST_STATIC_CONSTANT( int, extended_ = 1 ); #endif @@ -200,12 +184,9 @@ namespace detail template < intmax_t MinValue > struct int_min_rank_helper { -#ifdef BOOST_HAS_LONG_LONG - BOOST_STATIC_CONSTANT( int, extended_ = (MinValue >= boost::integer_traits< - long_long_type >::const_min) ); -#elif defined(BOOST_HAS_MS_INT64) - BOOST_STATIC_CONSTANT( int, extended_ = (MinValue >= boost::integer_traits< - __int64 >::const_min) ); +#if BOOST_HAS_XINT + BOOST_STATIC_CONSTANT( int, extended_ = (MinValue >= + boost::integer_traits< xint_t >::const_min) ); #else BOOST_STATIC_CONSTANT( int, extended_ = 1 ); #endif @@ -219,12 +200,9 @@ namespace detail template < uintmax_t Value > struct uint_max_rank_helper { -#ifdef BOOST_HAS_LONG_LONG +#if BOOST_HAS_XINT BOOST_STATIC_CONSTANT( int, extended_ = (Value <= boost::integer_traits< - ulong_long_type >::const_max) ); -#elif defined(BOOST_HAS_MS_INT64) - BOOST_STATIC_CONSTANT( int, extended_ = (Value <= boost::integer_traits< unsigned - __int64 >::const_max) ); + uxint_t >::const_max) ); #else BOOST_STATIC_CONSTANT( int, extended_ = 1 ); #endif diff --git a/include/boost/integer_fwd.hpp b/include/boost/integer_fwd.hpp index 1cc1ce1..446ad66 100644 --- a/include/boost/integer_fwd.hpp +++ b/include/boost/integer_fwd.hpp @@ -16,6 +16,8 @@ #include // for boost::uintmax_t, intmax_t #include // for std::numeric_limits +#include // for BOOST_HAS_XINT, etc. + namespace boost { @@ -73,12 +75,12 @@ template < > template < > class integer_traits< unsigned long >; -#ifdef ULLONG_MAX +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT template < > - class integer_traits< ::boost::long_long_type>; + class integer_traits< ::boost::detail::xint_t >; template < > - class integer_traits< ::boost::ulong_long_type >; + class integer_traits< ::boost::detail::uxint_t >; #endif diff --git a/include/boost/integer_traits.hpp b/include/boost/integer_traits.hpp index 96b3526..4cdc817 100644 --- a/include/boost/integer_traits.hpp +++ b/include/boost/integer_traits.hpp @@ -27,6 +27,8 @@ #include #endif +#include // for BOOST_HAS_XINT, etc. + namespace boost { template @@ -155,77 +157,18 @@ class integer_traits public detail::integer_traits_base { }; -#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) -#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) - +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT template<> -class integer_traits< ::boost::long_long_type> - : public std::numeric_limits< ::boost::long_long_type>, - public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> +class integer_traits< detail::xint_t > + : public std::numeric_limits< detail::xint_t >, + public detail::integer_traits_base< detail::xint_t, BOOST_XINT_MIN, BOOST_XINT_MAX > { }; template<> -class integer_traits< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +class integer_traits< detail::uxint_t > + : public std::numeric_limits< detail::uxint_t >, + public detail::integer_traits_base< detail::uxint_t, 0u, BOOST_UXINT_MAX > { }; - -#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) - -template<> -class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; -template<> -class integer_traits< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> -{ }; - -#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) - -template<> -class integer_traits< ::boost::long_long_type> - : public std::numeric_limits< ::boost::long_long_type>, - public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> -{ }; - -template<> -class integer_traits< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> -{ }; - -#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) - -template<> -class integer_traits< ::boost::long_long_type> - : public std::numeric_limits< ::boost::long_long_type>, - public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> -{ }; - -template<> -class integer_traits< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> -{ }; - -#elif defined(BOOST_HAS_LONG_LONG) -// -// we have long long but no constants, this happens for example with gcc in -ansi mode, -// we'll just have to work out the values for ourselves (assumes 2's compliment representation): -// -template<> -class integer_traits< ::boost::long_long_type> - : public std::numeric_limits< ::boost::long_long_type>, - public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) - 1)), ~(1LL << (sizeof(::boost::long_long_type) - 1))> -{ }; - -template<> -class integer_traits< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> -{ }; - -#endif #endif } // namespace boost diff --git a/test/integer_test.cpp b/test/integer_test.cpp index 4e32cc1..63bb4ff 100644 --- a/test/integer_test.cpp +++ b/test/integer_test.cpp @@ -30,6 +30,8 @@ #include // for boost::integer_traits #include // for std::numeric_limits +#include // for BOOST_HAS_XINT, etc. + #include // for boost::mpl::plus, divides #include // for BOOST_MPL_ASSERT_RELATION, etc. #include // for boost::mpl::back @@ -110,10 +112,8 @@ typedef boost::mpl::vector< #if ULONG_MAX > UINT_MAX , unsigned long #endif -#if defined(BOOST_HAS_LONG_LONG) && ((ULLONG_MAX > ULONG_MAX) || (ULONGLONG_MAX > ULONG_MAX)) - , boost::ulong_long_type -#elif defined(BOOST_HAS_MS_INT64) && (0xFFFFFFFFFFFFFFFFui64 > ULONG_MAX) - , unsigned __int64 +#if BOOST_HAS_XINT && (BOOST_UXINT_MAX > ULONG_MAX) + , boost::detail::uxint_t #endif > distinct_unsigned_types; @@ -210,10 +210,8 @@ int const integral_bit_lengths[] = { #if ULONG_MAX > UINT_MAX , std::numeric_limits< unsigned long >::digits #endif -#if defined(BOOST_HAS_LONG_LONG) && ((ULLONG_MAX > ULONG_MAX) || (ULONGLONG_MAX > ULONG_MAX)) - , std::numeric_limits< boost::ulong_long_type >::digits -#elif defined(BOOST_HAS_MS_INT64) && (0xFFFFFFFFFFFFFFFFui64 > ULONG_MAX) - , std::numeric_limits< unsigned __int64 >::digits +#if BOOST_HAS_XINT && (BOOST_UXINT_MAX > ULONG_MAX) + , std::numeric_limits< boost::detail::uxint_t >::digits #endif };