summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/support/numeric_utils
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/support/numeric_utils')
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp512
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_int.hpp147
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_real.hpp271
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/pow10.hpp116
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/sign.hpp48
5 files changed, 1094 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
new file mode 100644
index 0000000000..73770c87d0
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
@@ -0,0 +1,512 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Jan Frederick Eick
+ Copyright (c) 2011 Christopher Jefferson
+ Copyright (c) 2006 Stephen Nutt
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
+#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/comparison/less.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+
+#include <boost/detail/iterator.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/limits.hpp>
+
+#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
+# define SPIRIT_NUMERICS_LOOP_UNROLL 3
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The maximum radix digits that can be represented without
+ // overflow:
+ //
+ // template<typename T, unsigned Radix>
+ // struct digits_traits::value;
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix>
+ struct digits_traits;
+
+// lookup table for log2(x) : 2 <= x <= 36
+#define BOOST_SPIRIT_X3_LOG2 (#error)(#error) \
+ (1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
+ (3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
+ (3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
+ (4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
+ (4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
+ (5000000)(5044390)(5087460)(5129280)(5169925) \
+ /***/
+
+#define BOOST_PP_LOCAL_MACRO(Radix) \
+ template <typename T> struct digits_traits<T, Radix> \
+ { \
+ typedef std::numeric_limits<T> numeric_limits_type; \
+ BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
+ (numeric_limits_type::digits * 1000000) / \
+ BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2))); \
+ }; \
+ /***/
+
+#define BOOST_PP_LOCAL_LIMITS (2, 36)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#undef BOOST_SPIRIT_X3_LOG2
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Traits class for radix specific number conversion
+ //
+ // Test the validity of a single character:
+ //
+ // template<typename Char> static bool is_valid(Char ch);
+ //
+ // Convert a digit from character representation to binary
+ // representation:
+ //
+ // template<typename Char> static int digit(Char ch);
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct radix_traits
+ {
+ template <typename Char>
+ inline static bool is_valid(Char ch)
+ {
+ if (Radix <= 10)
+ return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
+ return (ch >= '0' && ch <= '9')
+ || (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
+ || (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
+ }
+
+ template <typename Char>
+ inline static unsigned digit(Char ch)
+ {
+ if (Radix <= 10 || (ch >= '0' && ch <= '9'))
+ return ch - '0';
+ return char_encoding::ascii::tolower(ch) - 'a' + 10;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // positive_accumulator/negative_accumulator: Accumulator policies for
+ // extracting integers. Use positive_accumulator if number is positive.
+ // Use negative_accumulator if number is negative.
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct positive_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked add
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) + T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked add
+ {
+ // Ensure n *= Radix will not overflow
+ static T const max = (std::numeric_limits<T>::max)();
+ static T const val = max / Radix;
+ if (n > val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n += digit will not overflow
+ const int digit = radix_traits<Radix>::digit(ch);
+ if (n > max - digit)
+ return false;
+
+ n += static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ template <unsigned Radix>
+ struct negative_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) - T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
+ {
+ // Ensure n *= Radix will not underflow
+ static T const min = (std::numeric_limits<T>::min)();
+ static T const val = (min + 1) / T(Radix);
+ if (n < val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n -= digit will not underflow
+ int const digit = radix_traits<Radix>::digit(ch);
+ if (n < min + digit)
+ return false;
+
+ n -= static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Common code for extract_int::parse specializations
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix, typename Accumulator, int MaxDigits>
+ struct int_extractor
+ {
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n, mpl::true_)
+ {
+ static std::size_t const
+ overflow_free = digits_traits<T, Radix>::value - 1;
+
+ if (count < overflow_free)
+ {
+ Accumulator::add(n, ch, mpl::false_());
+ }
+ else
+ {
+ if (!Accumulator::add(n, ch, mpl::true_()))
+ return false; // over/underflow!
+ }
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
+ {
+ // no need to check for overflow
+ Accumulator::add(n, ch, mpl::false_());
+ return true;
+ }
+
+ template <typename Char>
+ inline static bool
+ call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
+ {
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n)
+ {
+ return call(ch, count, n
+ , mpl::bool_<
+ ( (MaxDigits < 0)
+ || (MaxDigits > digits_traits<T, Radix>::value)
+ )
+ && traits::check_overflow<T>::value
+ >()
+ );
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // End of loop checking: check if the number of digits
+ // being parsed exceeds MaxDigits. Note: if MaxDigits == -1
+ // we don't do any checking.
+ ///////////////////////////////////////////////////////////////////////////
+ template <int MaxDigits>
+ struct check_max_digits
+ {
+ inline static bool
+ call(std::size_t count)
+ {
+ return count < MaxDigits; // bounded
+ }
+ };
+
+ template <>
+ struct check_max_digits<-1>
+ {
+ inline static bool
+ call(std::size_t /*count*/)
+ {
+ return true; // unbounded
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
+ || it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
+ break; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <
+ typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , typename Accumulator = positive_accumulator<Radix>
+ , bool Accumulate = false
+ >
+ struct extract_int
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t leading_zeros = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0' && leading_zeros < MaxDigits)
+ {
+ ++it;
+ ++leading_zeros;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ std::size_t count = 0;
+ char_type ch;
+
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ if (count + leading_zeros >= MinDigits)
+ {
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+ return false;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ // common case where MinDigits == 1 and MaxDigits = -1
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch)) \
+ break; \
+ if (!extractor::call(ch, count, val)) \
+ return false; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
+ struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, -1> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t count = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0')
+ {
+ ++it;
+ ++count;
+ }
+
+ if (it == last)
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ attr = 0;
+ first = it;
+ return true;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ char_type ch = *it;
+
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+
+ count = 0;
+ ++it;
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Cast an signed integer to an unsigned integer
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T,
+ bool force_unsigned
+ = mpl::and_<is_integral<T>, is_signed<T> >::value>
+ struct cast_unsigned;
+
+ template <typename T>
+ struct cast_unsigned<T, true>
+ {
+ typedef typename make_unsigned<T>::type unsigned_type;
+ typedef typename make_unsigned<T>::type& unsigned_type_ref;
+
+ inline static unsigned_type_ref call(T& n)
+ {
+ return unsigned_type_ref(n);
+ }
+ };
+
+ template <typename T>
+ struct cast_unsigned<T, false>
+ {
+ inline static T& call(T& n)
+ {
+ return n;
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
new file mode 100644
index 0000000000..aa80cdd6ea
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2011 Jan Frederick Eick
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM)
+#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Extract the prefix sign (- or +), return true if a '-' was found
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ inline bool
+ extract_sign(Iterator& first, Iterator const& last)
+ {
+ (void)last; // silence unused warnings
+ BOOST_ASSERT(first != last); // precondition
+
+ // Extract the sign
+ bool neg = *first == '-';
+ if (neg || (*first == '+'))
+ {
+ ++first;
+ return neg;
+ }
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level unsigned integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , bool Accumulate = false>
+ struct extract_uint
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix >= 2 && Radix <= 36),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T
+ , Radix
+ , MinDigits
+ , MaxDigits
+ , detail::positive_accumulator<Radix>
+ , Accumulate>
+ extract_type;
+
+ Iterator save = first;
+ if (!extract_type::parse(first, last,
+ detail::cast_unsigned<T>::call(attr)))
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level signed integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+ struct extract_int
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits>
+ extract_pos_type;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
+ extract_neg_type;
+
+ Iterator save = first;
+ bool hit = extract_sign(first, last);
+ if (hit)
+ hit = extract_neg_type::parse(first, last, attr);
+ else
+ hit = extract_pos_type::parse(first, last, attr);
+
+ if (!hit)
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
new file mode 100644
index 0000000000..fb30f02306
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
@@ -0,0 +1,271 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM)
+#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <cmath>
+#include <boost/limits.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/pow10.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/sign.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/assert.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace extension
+{
+ using x3::traits::pow10;
+
+ template <typename T>
+ inline void
+ scale(int exp, T& n)
+ {
+ if (exp >= 0)
+ {
+ // $$$ Why is this failing for boost.math.concepts ? $$$
+ //~ int nn = std::numeric_limits<T>::max_exponent10;
+ //~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
+ n *= pow10<T>(exp);
+ }
+ else
+ {
+ if (exp < std::numeric_limits<T>::min_exponent10)
+ {
+ n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
+ n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
+ }
+ else
+ {
+ n /= pow10<T>(-exp);
+ }
+ }
+ }
+
+ inline void
+ scale(int /*exp*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ template <typename T>
+ inline void
+ scale(int exp, int frac, T& n)
+ {
+ scale(exp - frac, n);
+ }
+
+ inline void
+ scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ inline float
+ negate(bool neg, float n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline double
+ negate(bool neg, double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline long double
+ negate(bool neg, long double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ template <typename T>
+ inline T
+ negate(bool neg, T const& n)
+ {
+ return neg ? -n : n;
+ }
+
+ inline unused_type
+ negate(bool /*neg*/, unused_type n)
+ {
+ // no-op for unused_type
+ return n;
+ }
+
+ template <typename T>
+ inline bool
+ is_equal_to_one(T const& value)
+ {
+ return value == 1.0;
+ }
+
+ inline bool
+ is_equal_to_one(unused_type)
+ {
+ // no-op for unused_type
+ return false;
+ }
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, typename RealPolicies>
+ struct extract_real
+ {
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse(Iterator& first, Iterator const& last, Attribute& attr,
+ RealPolicies const& p)
+ {
+ if (first == last)
+ return false;
+ Iterator save = first;
+
+ // Start by parsing the sign. neg will be true if
+ // we got a "-" sign, false otherwise.
+ bool neg = p.parse_sign(first, last);
+
+ // Now attempt to parse an integer
+ T n = 0;
+ bool got_a_number = p.parse_n(first, last, n);
+
+ // If we did not get a number it might be a NaN, Inf or a leading
+ // dot.
+ if (!got_a_number)
+ {
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return early
+ }
+
+ // If we did not get a number and our policies do not
+ // allow a leading dot, fail and return early (no-match)
+ if (!p.allow_leading_dot)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ bool e_hit = false;
+ int frac_digits = 0;
+
+ // Try to parse the dot ('.' decimal point)
+ if (p.parse_dot(first, last))
+ {
+ // We got the decimal point. Now we will try to parse
+ // the fraction if it is there. If not, it defaults
+ // to zero (0) only if we already got a number.
+ Iterator savef = first;
+ if (p.parse_frac_n(first, last, n))
+ {
+ // Optimization note: don't compute frac_digits if T is
+ // an unused_type. This should be optimized away by the compiler.
+ if (!is_same<T, unused_type>::value)
+ frac_digits =
+ static_cast<int>(std::distance(savef, first));
+ }
+ else if (!got_a_number || !p.allow_trailing_dot)
+ {
+ // We did not get a fraction. If we still haven't got a
+ // number and our policies do not allow a trailing dot,
+ // return no-match.
+ first = save;
+ return false;
+ }
+
+ // Now, let's see if we can parse the exponent prefix
+ e_hit = p.parse_exp(first, last);
+ }
+ else
+ {
+ // No dot and no number! Return no-match.
+ if (!got_a_number)
+ {
+ first = save;
+ return false;
+ }
+
+ // If we must expect a dot and we didn't see an exponent
+ // prefix, return no-match.
+ e_hit = p.parse_exp(first, last);
+ if (p.expect_dot && !e_hit)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ if (e_hit)
+ {
+ // We got the exponent prefix. Now we will try to parse the
+ // actual exponent. It is an error if it is not there.
+ int exp = 0;
+ if (p.parse_exp_n(first, last, exp))
+ {
+ // Got the exponent value. Scale the number by
+ // exp-frac_digits.
+ extension::scale(exp, frac_digits, n);
+ }
+ else
+ {
+ // Oops, no exponent, return no-match.
+ first = save;
+ return false;
+ }
+ }
+ else if (frac_digits)
+ {
+ // No exponent found. Scale the number by -frac_digits.
+ extension::scale(-frac_digits, n);
+ }
+ else if (extension::is_equal_to_one(n))
+ {
+ // There is a chance of having to parse one of the 1.0#...
+ // styles some implementations use for representing NaN or Inf.
+
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return immediately
+ }
+ }
+
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+
+ // Success!!!
+ return true;
+ }
+ };
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/pow10.hpp b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
new file mode 100644
index 0000000000..f51d29fba8
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM)
+#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/limits.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ namespace detail
+ {
+ template <typename T, typename Enable = void>
+ struct pow10_helper
+ {
+ static T call(unsigned dim)
+ {
+ using namespace std; // allow for ADL to find the correct overload
+ return pow(T(10), T(dim));
+ }
+ };
+
+ template <>
+ struct pow10_helper<unused_type>
+ {
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+#if (DBL_MAX_10_EXP == 308) // for IEEE-754
+ template <>
+ struct pow10_helper<double>
+ {
+ static double call(unsigned dim)
+ {
+ static double const exponents[] =
+ {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
+ 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
+ 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
+ 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
+ 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
+ 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
+ 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
+ 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
+ };
+ BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
+ return exponents[dim];
+ }
+ };
+
+ template <>
+ struct pow10_helper<float>
+ {
+ static float call(unsigned dim)
+ {
+ return pow10_helper<double>::call(dim);
+ }
+ };
+#endif // for IEEE-754
+ }
+
+ template <typename T>
+ inline T pow10(unsigned dim)
+ {
+ return detail::pow10_helper<T>::call(dim);
+ }
+}}}}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/sign.hpp b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
new file mode 100644
index 0000000000..fe2feceeed
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SIGN_MAR_11_2009_0734PM)
+#define SPIRIT_SIGN_MAR_11_2009_0734PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template<typename T>
+ inline bool (signbit)(T x)
+ {
+ return (boost::math::signbit)(x) ? true : false;
+ }
+
+ // This routine has been taken and adapted from Johan Rade's fp_traits
+ // library
+ template<typename T>
+ inline T (changesign)(T x)
+ {
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
+ return -x;
+#else
+ typedef typename math::detail::fp_traits<T>::type traits_type;
+
+ typename traits_type::bits a;
+ traits_type::get_bits(x, a);
+ a ^= traits_type::sign;
+ traits_type::set_bits(x, a);
+ return x;
+#endif
+ }
+
+}}}
+
+#endif