diff options
Diffstat (limited to 'boost/spirit/home/qi/numeric/detail/numeric_utils.hpp')
-rw-r--r-- | boost/spirit/home/qi/numeric/detail/numeric_utils.hpp | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp b/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp index f1154dc92a..f6bd889037 100644 --- a/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp +++ b/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp @@ -15,7 +15,6 @@ #pragma once #endif -#include <boost/detail/iterator.hpp> #include <boost/spirit/home/support/unused.hpp> #include <boost/spirit/home/qi/detail/attributes.hpp> #include <boost/spirit/home/support/char_encoding/ascii.hpp> @@ -31,7 +30,8 @@ #include <boost/mpl/bool.hpp> #include <boost/mpl/and.hpp> #include <boost/limits.hpp> -#include <boost/integer_traits.hpp> +#include <boost/static_assert.hpp> +#include <iterator> // for std::iterator_traits #if defined(BOOST_MSVC) # pragma warning(push) @@ -56,6 +56,9 @@ namespace boost { namespace spirit { namespace qi { namespace detail template <typename T, unsigned Radix> struct digits_traits; + template <int Digits, unsigned Radix> + struct digits2_to_n; + // lookup table for log2(x) : 2 <= x <= 36 #define BOOST_SPIRIT_LOG2 (#error)(#error) \ (1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \ @@ -67,11 +70,10 @@ namespace boost { namespace spirit { namespace qi { namespace detail /***/ #define BOOST_PP_LOCAL_MACRO(Radix) \ - template <typename T> struct digits_traits<T, Radix> \ + template <int Digits> struct digits2_to_n<Digits, Radix> \ { \ - typedef std::numeric_limits<T> numeric_limits_type; \ BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \ - (numeric_limits_type::digits * 1000000) / \ + (Digits * 1000000) / \ BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_LOG2))); \ }; \ /***/ @@ -81,6 +83,18 @@ namespace boost { namespace spirit { namespace qi { namespace detail #undef BOOST_SPIRIT_LOG2 + template <typename T, unsigned Radix> + struct digits_traits : digits2_to_n<std::numeric_limits<T>::digits, Radix> + { + BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix == 2); + }; + + template <typename T> + struct digits_traits<T, 10> + { + static int const value = std::numeric_limits<T>::digits10; + }; + /////////////////////////////////////////////////////////////////////////// // // Traits class for radix specific number conversion @@ -114,12 +128,6 @@ namespace boost { namespace spirit { namespace qi { namespace detail return spirit::char_encoding::ascii::tolower(ch) - 'a' + 10; } }; - - template <typename T, T Val> - struct constexpr_int - { - BOOST_STATIC_CONSTEXPR T value = Val; - }; /////////////////////////////////////////////////////////////////////////// // positive_accumulator/negative_accumulator: Accumulator policies for @@ -140,20 +148,20 @@ namespace boost { namespace spirit { namespace qi { namespace detail inline static bool add(T& n, Char ch, mpl::true_) // checked add { // Ensure n *= Radix will not overflow - typedef constexpr_int<T, boost::integer_traits<T>::const_max> max; - typedef constexpr_int<T, max::value / Radix> val; + T const max = (std::numeric_limits<T>::max)(); + T const val = max / Radix; - if (n > val::value) + if (n > val) return false; - n *= Radix; + T tmp = n * Radix; // Ensure n += digit will not overflow const int digit = radix_traits<Radix>::digit(ch); - if (n > max::value - digit) + if (tmp > max - digit) return false; - n += static_cast<T>(digit); + n = tmp + static_cast<T>(digit); return true; } }; @@ -172,20 +180,20 @@ namespace boost { namespace spirit { namespace qi { namespace detail inline static bool add(T& n, Char ch, mpl::true_) // checked subtract { // Ensure n *= Radix will not underflow - typedef constexpr_int<T, boost::integer_traits<T>::const_min> min; - typedef constexpr_int<T, (min::value + 1) / T(Radix)> val; + T const min = (std::numeric_limits<T>::min)(); + T const val = min / T(Radix); - if (n < val::value) + if (n < val) return false; - n *= Radix; + T tmp = n * Radix; // Ensure n -= digit will not underflow int const digit = radix_traits<Radix>::digit(ch); - if (n < min::value + digit) + if (tmp < min + digit) return false; - n -= static_cast<T>(digit); + n = tmp - static_cast<T>(digit); return true; } }; @@ -200,9 +208,9 @@ namespace boost { namespace spirit { namespace qi { namespace detail inline static bool call(Char ch, std::size_t count, T& n, mpl::true_) { - typedef constexpr_int<std::size_t, digits_traits<T, Radix>::value - 1> overflow_free; + std::size_t const overflow_free = digits_traits<T, Radix>::value - 1; - if (!AlwaysCheckOverflow && (count < overflow_free::value)) + if (!AlwaysCheckOverflow && (count < overflow_free)) { Accumulator::add(n, ch, mpl::false_()); } @@ -318,9 +326,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail { typedef radix_traits<Radix> radix_check; typedef int_extractor<Radix, Accumulator, MaxDigits, Accumulate> extractor; - typedef typename - boost::detail::iterator_traits<Iterator>::value_type - char_type; + typedef typename std::iterator_traits<Iterator>::value_type char_type; Iterator it = first; std::size_t leading_zeros = 0; @@ -423,9 +429,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail { typedef radix_traits<Radix> radix_check; typedef int_extractor<Radix, Accumulator, -1, Accumulate> extractor; - typedef typename - boost::detail::iterator_traits<Iterator>::value_type - char_type; + typedef typename std::iterator_traits<Iterator>::value_type char_type; Iterator it = first; std::size_t count = 0; |