Imported existing code
This commit is contained in:
@@ -0,0 +1,504 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
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(SPIRIT_NUMERIC_UTILS_APR_17_2006_0816AM)
|
||||
#define SPIRIT_NUMERIC_UTILS_APR_17_2006_0816AM
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/char_class/ascii.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
|
||||
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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);
|
||||
//
|
||||
// The maximum radix digits that can be represented without
|
||||
// overflow:
|
||||
//
|
||||
// template<typename T> struct digits::value;
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix>
|
||||
struct radix_traits;
|
||||
|
||||
// Binary
|
||||
template <>
|
||||
struct radix_traits<2>
|
||||
{
|
||||
template<typename Char>
|
||||
static bool is_valid(Char ch)
|
||||
{
|
||||
return ('0' == ch || '1' == ch);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
static unsigned digit(Char ch)
|
||||
{
|
||||
return ch - '0';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct digits
|
||||
{
|
||||
typedef std::numeric_limits<T> numeric_limits_;
|
||||
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits);
|
||||
};
|
||||
};
|
||||
|
||||
// Octal
|
||||
template <>
|
||||
struct radix_traits<8>
|
||||
{
|
||||
template<typename Char>
|
||||
static bool is_valid(Char ch)
|
||||
{
|
||||
return ch >= '0' && ch <= '7';
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
static unsigned digit(Char ch)
|
||||
{
|
||||
return ch - '0';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct digits
|
||||
{
|
||||
typedef std::numeric_limits<T> numeric_limits_;
|
||||
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 3);
|
||||
};
|
||||
};
|
||||
|
||||
// Decimal
|
||||
template <>
|
||||
struct radix_traits<10>
|
||||
{
|
||||
template<typename Char>
|
||||
static bool is_valid(Char ch)
|
||||
{
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
static unsigned digit(Char ch)
|
||||
{
|
||||
return ch - '0';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct digits
|
||||
{
|
||||
typedef std::numeric_limits<T> numeric_limits_;
|
||||
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits10);
|
||||
};
|
||||
};
|
||||
|
||||
// Hexadecimal
|
||||
template <>
|
||||
struct radix_traits<16>
|
||||
{
|
||||
template<typename Char>
|
||||
static bool is_valid(Char ch)
|
||||
{
|
||||
return (ch >= '0' && ch <= '9')
|
||||
|| (ch >= 'a' && ch <= 'f')
|
||||
|| (ch >= 'A' && ch <= 'F');
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
static unsigned digit(Char ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
return spirit::char_class::ascii::tolower(ch) - 'a' + 10;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct digits
|
||||
{
|
||||
typedef std::numeric_limits<T> numeric_limits_;
|
||||
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 4);
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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>
|
||||
static void add(T& n, Char ch, mpl::false_) // unchecked add
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * Radix + digit;
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
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 - 1) / 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 += digit;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned Radix>
|
||||
struct negative_accumulator
|
||||
{
|
||||
template <typename T, typename Char>
|
||||
static void add(T& n, Char ch, mpl::false_) // unchecked subtract
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * Radix - digit;
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
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 -= 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>
|
||||
static bool
|
||||
call(Char ch, std::size_t count, T& n, mpl::true_)
|
||||
{
|
||||
static std::size_t const
|
||||
overflow_free = radix_traits<Radix>::template digits<T>::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>
|
||||
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>
|
||||
static bool
|
||||
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
static bool
|
||||
call(Char ch, std::size_t count, T& n)
|
||||
{
|
||||
return call(ch, count, n
|
||||
, mpl::bool_<
|
||||
( (MaxDigits < 0)
|
||||
|| (MaxDigits > radix_traits<Radix>::template digits<T>::value)
|
||||
)
|
||||
&& std::numeric_limits<T>::is_modulo
|
||||
>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
{
|
||||
static bool
|
||||
call(std::size_t count)
|
||||
{
|
||||
return count < MaxDigits; // bounded
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct check_max_digits<-1>
|
||||
{
|
||||
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>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Attribute val = Accumulate ? attr : 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)
|
||||
{
|
||||
attr = val;
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
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>
|
||||
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) || !extractor::call(ch, count, val)) \
|
||||
break; \
|
||||
++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>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Attribute val = Accumulate ? attr : 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;
|
||||
attr = val;
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
++it;
|
||||
while (true)
|
||||
{
|
||||
BOOST_PP_REPEAT(
|
||||
SPIRIT_NUMERICS_LOOP_UNROLL
|
||||
, SPIRIT_NUMERIC_INNER_LOOP, _)
|
||||
}
|
||||
|
||||
attr = val;
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
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>
|
||||
static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
return parse_main(first, last, attr);
|
||||
}
|
||||
};
|
||||
|
||||
#undef SPIRIT_NUMERIC_INNER_LOOP
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,225 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
Copyright (c) 2001-2009 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_REAL_IMPL_APR_18_2006_0901AM)
|
||||
#define SPIRIT_REAL_IMPL_APR_18_2006_0901AM
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
inline void
|
||||
scale_number(T const& exp, T& n)
|
||||
{
|
||||
using namespace std; // allow for ADL to find the correct overload
|
||||
n *= pow(T(10), exp);
|
||||
}
|
||||
|
||||
inline void
|
||||
scale_number(unused_type /*exp*/, unused_type /*n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
scale_number(T const& exp, int frac, T& n)
|
||||
{
|
||||
scale_number(exp - T(frac), n);
|
||||
}
|
||||
|
||||
inline void
|
||||
scale_number(unused_type /*exp*/, int /*frac*/, unused_type /*n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T
|
||||
negate_number(bool neg, T const& n)
|
||||
{
|
||||
return neg ? -n : n;
|
||||
}
|
||||
|
||||
inline unused_type
|
||||
negate_number(bool /*neg*/, unused_type n)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
number_equal_to_one(T const& value)
|
||||
{
|
||||
return value == 1.0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
number_equal_to_one(unused_type)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_impl
|
||||
{
|
||||
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
|
||||
Attribute 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, attr) ||
|
||||
p.parse_inf(first, last, attr))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
attr = negate_number(neg, 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.
|
||||
Attribute exp = 0;
|
||||
if (p.parse_exp_n(first, last, exp))
|
||||
{
|
||||
// Got the exponent value. Scale the number by
|
||||
// exp-frac_digits.
|
||||
scale_number(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.
|
||||
scale_number(Attribute(-frac_digits), n);
|
||||
}
|
||||
else if (number_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, attr) ||
|
||||
p.parse_inf(first, last, attr))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
attr = negate_number(neg, attr);
|
||||
return true; // got a NaN or Inf, return immediately
|
||||
}
|
||||
}
|
||||
|
||||
// If we got a negative sign, negate the number
|
||||
attr = negate_number(neg, n);
|
||||
|
||||
// Success!!!
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
53
libraries/include/boost/spirit/home/qi/numeric/int.hpp
Normal file
53
libraries/include/boost/spirit/home/qi/numeric/int.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_INT_APR_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_INT_APR_17_2006_0830AM
|
||||
|
||||
#include <boost/spirit/home/qi/skip.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct int_parser
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Component
|
||||
, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
static bool parse(
|
||||
Component const& /*component*/
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr)
|
||||
{
|
||||
qi::skip(first, last, skipper);
|
||||
return extract_int<T, Radix, MinDigits, MaxDigits>
|
||||
::call(first, last, attr);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "integer";
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
312
libraries/include/boost/spirit/home/qi/numeric/meta_grammar.hpp
Normal file
312
libraries/include/boost/spirit/home/qi/numeric/meta_grammar.hpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_META_GRAMMAR_FEB_05_2007_0951AM)
|
||||
#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0951AM
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/placeholders.hpp>
|
||||
#include <boost/spirit/home/support/meta_grammar.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/real_policies.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace qi
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct int_tag;
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct uint_tag;
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_tag;
|
||||
}
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct is_int_tag<qi::int_tag<T, Radix, MinDigits, MaxDigits>, qi::domain>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct is_int_tag<qi::uint_tag<T, Radix, MinDigits, MaxDigits>, qi::domain>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct is_real_tag<qi::real_tag<T, RealPolicies>, qi::domain>
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forwards
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct int_parser;
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct uint_parser;
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_parser;
|
||||
|
||||
template <typename Expr, typename Enable>
|
||||
struct is_valid_expr;
|
||||
|
||||
template <typename Expr, typename Enable>
|
||||
struct expr_transform;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// numeric tags
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct int_tag
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct uint_tag
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_tag
|
||||
{
|
||||
RealPolicies policies;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// numeric specs
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = int
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1
|
||||
>
|
||||
struct int_spec
|
||||
: proto::terminal<
|
||||
int_tag<T, Radix, MinDigits, MaxDigits>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <
|
||||
typename T = int
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1
|
||||
>
|
||||
struct uint_spec
|
||||
: proto::terminal<
|
||||
uint_tag<T, Radix, MinDigits, MaxDigits>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = double,
|
||||
typename RealPolicies = real_policies<T>
|
||||
>
|
||||
struct real_spec
|
||||
: proto::terminal<
|
||||
real_tag<T, RealPolicies>
|
||||
>::type
|
||||
{
|
||||
private:
|
||||
typedef typename
|
||||
proto::terminal<real_tag<T, RealPolicies> >::type
|
||||
base_type;
|
||||
|
||||
base_type make_tag(RealPolicies const& p) const
|
||||
{
|
||||
base_type xpr = {{p}};
|
||||
return xpr;
|
||||
}
|
||||
|
||||
public:
|
||||
real_spec(RealPolicies const& p = RealPolicies())
|
||||
: base_type(make_tag(p))
|
||||
{}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename RealPolicies>
|
||||
struct real_policy
|
||||
{
|
||||
template <typename Tag>
|
||||
static RealPolicies get(Tag) { return RealPolicies(); }
|
||||
|
||||
template <typename T>
|
||||
static RealPolicies const& get(real_tag<T, RealPolicies> const& p)
|
||||
{ return p.policies; }
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of an int tag
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct extract_int_director;
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::bin>
|
||||
{
|
||||
typedef uint_parser<unsigned, 2, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::oct>
|
||||
{
|
||||
typedef uint_parser<unsigned, 8, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::hex>
|
||||
{
|
||||
typedef uint_parser<unsigned, 16, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::ushort>
|
||||
{
|
||||
typedef uint_parser<unsigned short, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::ulong>
|
||||
{
|
||||
typedef uint_parser<unsigned long, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::uint>
|
||||
{
|
||||
typedef uint_parser<unsigned int, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::short_>
|
||||
{
|
||||
typedef int_parser<short, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::long_>
|
||||
{
|
||||
typedef int_parser<long, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::int_>
|
||||
{
|
||||
typedef int_parser<int, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <>
|
||||
struct extract_int_director<tag::ulong_long>
|
||||
{
|
||||
typedef uint_parser<unsigned long long, 10, 1, -1> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_int_director<tag::long_long>
|
||||
{
|
||||
typedef int_parser<long long, 10, 1, -1> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct extract_int_director<int_tag<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef int_parser<T, Radix, MinDigits, MaxDigits> type;
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct extract_int_director<uint_tag<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef uint_parser<T, Radix, MinDigits, MaxDigits> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of a real tag
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct extract_real_director;
|
||||
|
||||
template <>
|
||||
struct extract_real_director<tag::float_>
|
||||
{
|
||||
typedef real_parser<float, real_policies<float> > type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_real_director<tag::double_>
|
||||
{
|
||||
typedef real_parser<double, real_policies<double> > type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_real_director<tag::long_double>
|
||||
{
|
||||
typedef real_parser<long double, real_policies<long double> > type;
|
||||
};
|
||||
|
||||
template <typename T, typename RealPolicies>
|
||||
struct extract_real_director<real_tag<T, RealPolicies> >
|
||||
{
|
||||
typedef real_parser<T, RealPolicies> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// numeric parser meta-grammar
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct int_meta_grammar
|
||||
: meta_grammar::compose_empty<
|
||||
proto::if_<is_int_tag<proto::_child, qi::domain>()>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_int_director<mpl::_> >
|
||||
>
|
||||
{};
|
||||
|
||||
struct real_meta_grammar
|
||||
: meta_grammar::compose_single<
|
||||
proto::if_<is_real_tag<proto::_child, qi::domain>()>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_real_director<mpl::_> >
|
||||
>
|
||||
{};
|
||||
|
||||
struct numeric_meta_grammar
|
||||
: proto::or_<int_meta_grammar, real_meta_grammar>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These specializations non-intrusively hooks into the RD meta-grammar.
|
||||
// (see qi/meta_grammar.hpp)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct is_valid_expr<Expr
|
||||
, typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct expr_transform<Expr
|
||||
, typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
|
||||
: mpl::identity<numeric_meta_grammar>
|
||||
{
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
111
libraries/include/boost/spirit/home/qi/numeric/numeric_utils.hpp
Normal file
111
libraries/include/boost/spirit/home/qi/numeric/numeric_utils.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_NUMERIC_UTILS_APR_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_NUMERIC_UTILS_APR_17_2006_0830AM
|
||||
|
||||
#include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Extract the prefix sign (- or +), return true if a '-' was found
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
inline bool
|
||||
extract_sign(Iterator& first, Iterator const& last)
|
||||
{
|
||||
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
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool call(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
typedef detail::extract_int<
|
||||
T
|
||||
, Radix
|
||||
, MinDigits
|
||||
, MaxDigits
|
||||
, detail::positive_accumulator<Radix>
|
||||
, Accumulate>
|
||||
extract_type;
|
||||
|
||||
Iterator save = first;
|
||||
if (!extract_type::parse(first, last, attr))
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Low level signed integer parser
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct extract_int
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool call(Iterator& first, Iterator const& last, Attribute& 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;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
60
libraries/include/boost/spirit/home/qi/numeric/real.hpp
Normal file
60
libraries/include/boost/spirit/home/qi/numeric/real.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_REAL_APR_18_2006_0850AM)
|
||||
#define BOOST_SPIRIT_REAL_APR_18_2006_0850AM
|
||||
|
||||
#include <boost/spirit/home/qi/skip.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/real_policies.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/detail/real_impl.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename RealPolicies>
|
||||
struct real_policy;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T = double,
|
||||
typename RealPolicies = real_policies<T>
|
||||
>
|
||||
struct real_parser
|
||||
{
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Component
|
||||
, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
static bool parse(
|
||||
Component const& component
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr)
|
||||
{
|
||||
RealPolicies const& p = detail::real_policy<RealPolicies>::get(
|
||||
fusion::at_c<0>(component.elements));
|
||||
|
||||
qi::skip(first, last, skipper);
|
||||
return detail::real_impl<T, RealPolicies>::parse(first, last, attr, p);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "real number";
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
182
libraries/include/boost/spirit/home/qi/numeric/real_policies.hpp
Normal file
182
libraries/include/boost/spirit/home/qi/numeric/real_policies.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_REAL_POLICIES_APR_17_2006_1158PM)
|
||||
#define SPIRIT_REAL_POLICIES_APR_17_2006_1158PM
|
||||
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
||||
#include <boost/detail/iterator.hpp> // boost::iterator_traits<>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default (unsigned) real number policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct ureal_policies
|
||||
{
|
||||
// trailing dot policy suggested by Gustavo Guerra
|
||||
static bool const allow_leading_dot = true;
|
||||
static bool const allow_trailing_dot = true;
|
||||
static bool const expect_dot = false;
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_n(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
return extract_uint<T, 10, 1, -1>::call(first, last, attr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_dot(Iterator& first, Iterator const& last)
|
||||
{
|
||||
if (first == last || *first != '.')
|
||||
return false;
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
return extract_uint<T, 10, 1, -1, true>::call(first, last, attr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_exp(Iterator& first, Iterator const& last)
|
||||
{
|
||||
if (first == last || (*first != 'e' && *first != 'E'))
|
||||
return false;
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_exp_n(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
return extract_int<T, 10, 1, -1>::call(first, last, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// The parse_nan() and parse_inf() functions get called whenever:
|
||||
//
|
||||
// - a number to parse does not start with a digit (after having
|
||||
// successfully parsed an optional sign)
|
||||
//
|
||||
// or
|
||||
//
|
||||
// - after a floating point number of the value 1 (having no
|
||||
// exponential part and a fractional part value of 0) has been
|
||||
// parsed.
|
||||
//
|
||||
// The first call allows to recognize representations of NaN or Inf
|
||||
// starting with a non-digit character (such as NaN, Inf, QNaN etc.).
|
||||
//
|
||||
// The second call allows to recognize representation formats starting
|
||||
// with a 1.0 (such as 1.0#QNAN or 1.0#INF etc.).
|
||||
//
|
||||
// The functions should return true if a Nan or Inf has been found. In
|
||||
// this case the attr should be set to the matched value (NaN or
|
||||
// Inf). The optional sign will be automatically applied afterwards.
|
||||
//
|
||||
// The default implementation below recognizes representations of NaN
|
||||
// and Inf as mandated by the C99 Standard and as proposed for
|
||||
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
|
||||
// (the matching is performed case-insensitively).
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_nan(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
if (first == last)
|
||||
return false; // end of input reached
|
||||
|
||||
if (*first != 'n' && *first != 'N')
|
||||
return false; // not "nan"
|
||||
|
||||
// nan[(...)] ?
|
||||
if (detail::string_parse("nan", "NAN", first, last, unused))
|
||||
{
|
||||
if (*first == '(')
|
||||
{
|
||||
// skip trailing (...) part
|
||||
Iterator i = first;
|
||||
|
||||
while (++i != last && *i != ')')
|
||||
;
|
||||
if (i == last)
|
||||
return false; // no trailing ')' found, give up
|
||||
|
||||
first = ++i;
|
||||
}
|
||||
attr = std::numeric_limits<T>::quiet_NaN();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_inf(Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
if (first == last)
|
||||
return false; // end of input reached
|
||||
|
||||
if (*first != 'i' && *first != 'I')
|
||||
return false; // not "inf"
|
||||
|
||||
// inf or infinity ?
|
||||
if (detail::string_parse("inf", "INF", first, last, unused))
|
||||
{
|
||||
// skip allowed 'inity' part of infinity
|
||||
detail::string_parse("inity", "INITY", first, last, unused);
|
||||
attr = std::numeric_limits<T>::infinity();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default (signed) real number policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct real_policies : ureal_policies<T>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_sign(Iterator& first, Iterator const& last)
|
||||
{
|
||||
return extract_sign(first, last);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct strict_ureal_policies : ureal_policies<T>
|
||||
{
|
||||
static bool const expect_dot = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct strict_real_policies : real_policies<T>
|
||||
{
|
||||
static bool const expect_dot = true;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
53
libraries/include/boost/spirit/home/qi/numeric/uint.hpp
Normal file
53
libraries/include/boost/spirit/home/qi/numeric/uint.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
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_UINT_APR_17_2006_0901AM)
|
||||
#define SPIRIT_UINT_APR_17_2006_0901AM
|
||||
|
||||
#include <boost/spirit/home/qi/skip.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct uint_parser
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Component
|
||||
, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
static bool parse(
|
||||
Component const& /*component*/
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr)
|
||||
{
|
||||
qi::skip(first, last, skipper);
|
||||
return extract_uint<T, Radix, MinDigits, MaxDigits>
|
||||
::call(first, last, attr);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "unsigned integer";
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user