summaryrefslogtreecommitdiff
path: root/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/qi/numeric/detail/numeric_utils.hpp')
-rw-r--r--boost/spirit/home/qi/numeric/detail/numeric_utils.hpp66
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;