📄 numerics.hpp
字号:
///////////////////////////////////////////////////////////////////////////////
// predefined unsigned integer parsers
const uint_parser_gen<2> ubin_p = uint_parser_gen<2>();
const uint_parser_gen<8> uoct_p = uint_parser_gen<8>();
const uint_parser_gen<10> uint_p = uint_parser_gen<10>();
const uint_parser_gen<16> uhex_p = uint_parser_gen<16>();
///////////////////////////////////////////////////////////////////////////////
//
// int_parser class
//
// Parses signed integers. An int_parser is never directly
// instantiated. An instance of the int_parser_gen, int_p,
// generates an int_parser through its [] operator:
//
// int_p[f]
//
// where f is a semantic action which may be a function or a
// functor. A function should be compatible with the interface:
//
// void f(NumT num);
//
// A functor should have a member operator() with a compatible
// signature as above. The matching number is passed into the
// function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename T = int, const int Radix = 10>
struct int_parser : public parser<int_parser<T, Radix> > {
typedef typename impl::IF<is_reference_wrapper<T>::value,
typename unwrap_reference_wrapper<T>::type&,
T>::RET actual_type;
int_parser(actual_type n_)
: n(n_) {}
template <typename IteratorT>
match
parse(IteratorT& first, IteratorT const& last) const
{
n = 0;
if (first == last)
return match();
typedef typename impl::strip_scanner<IteratorT>
::iterator_type plain_iter;
plain_iter i1 = impl::strip_scanner<IteratorT>::get(first);
plain_iter i2 = impl::strip_scanner<IteratorT>::get(last);
unsigned count;
bool neg = impl::extract_sign(i1, count);
bool matched = impl::extract<Radix>::sint(i1, i2, n, count, neg);
match hit = match(count);
if (matched && hit)
{
if (neg) n = -n;
first = i1;
return match(hit.length() + count);
}
return match();
}
mutable actual_type n;
};
///////////////////////////////////////////////////////////////////////////////
template <const int Radix>
struct int_parser_gen : public int_parser<int, Radix> {
int_parser_gen()
: int_parser<int, Radix>(0) {}
template <typename T>
typename int_numeric_action_traits<T, void (*)(T), Radix>::int_action
operator [] (void (*actor)(T)) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename int_numeric_action_traits<T, void(*)(T), Radix>::int_action
action_t;
return action_t(actor);
}
template <typename T>
typename int_numeric_action_traits<typename unwrap_reference_wrapper<T>::type,
T, Radix>::int_action
operator [] (T const& actor) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename int_numeric_action_traits<unwrap_reference_wrapper<T>::type,
T, Radix>::int_action action_t;
return action_t(actor);
}
};
///////////////////////////////////////////////////////////////////////////////
// predefined signed integer parsers
const int_parser_gen<2> bin_p = int_parser_gen<2>();
const int_parser_gen<8> oct_p = int_parser_gen<8>();
const int_parser_gen<10> int_p = int_parser_gen<10>();
const int_parser_gen<16> hex_p = int_parser_gen<16>();
///////////////////////////////////////////////////////////////////////////////
//
// ureal_parser class
//
// Parses unsigned reals. A ureal_parser is never directly
// instantiated. An instance of the ureal_parser_gen, ureal_p,
// generates a ureal_parser through its [] operator:
//
// ureal_p[f]
//
// where f is a semantic action which may be a function or a
// functor. A function should be compatible with the interface:
//
// void f(NumT num);
//
// A functor should have a member operator() with a compatible
// signature as above. The matching number is passed into the
// function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename FloatT = double, typename TraitsT = numeric_parser_traits<> >
struct ureal_parser :
public parser<
ureal_parser< FloatT, TraitsT >
>
{
typedef typename impl::IF<is_reference_wrapper<FloatT>::value,
typename unwrap_reference_wrapper<FloatT>::type&,
FloatT>::RET actual_type;
ureal_parser(actual_type n_)
: n(n_) {}
template <typename IteratorT>
match
parse(IteratorT& first, IteratorT const& last) const
{
n = 0;
if (first == last)
return match();
typedef typename impl::strip_scanner<IteratorT>
::iterator_type plain_iter;
plain_iter i1 = impl::strip_scanner<IteratorT>::get(first);
plain_iter i2 = impl::strip_scanner<IteratorT>::get(last);
plain_iter ittemp = i1;
unsigned counttemp = 0;
if (!(isdigit(*ittemp) ||
impl::traits_cmp<TraitsT>::is_ds(ittemp, i2, counttemp)))
return match();
unsigned count = 0;
unsigned frac = 0;
ittemp = i1;
if (!impl::traits_cmp<TraitsT>::is_ds(ittemp, i2, count))
{
assert(0 == count);
assert(ittemp == i1);
// Extract the digits before the decimal point: nnn.
if (!impl::extract<10, TraitsT>::uint(ittemp, i2, n, count))
return match(); // overflow, return non-match
if (i1 == i2)
{
first = i1;
return match(count);
}
i1 = ittemp; // advance start position
}
else
count = 0;
if (impl::traits_cmp<TraitsT>::is_ds(i1, i2, count))
{
// Extract the digits after the decimal point .nnn
if (!impl::extract<10>::uint(i1, i2, n, frac))
return match(); // overflow, return non-match
count += frac;
}
// Extract the exponent
match hit(count);
int exp = 0;
if (impl::traits_cmp<TraitsT>::is_exp(i1, i2, count)) {
hit = match(count);
if (match mexp = int_p[ref(exp)].parse(i1, i2))
hit += mexp;
}
typedef typename boost::remove_reference<FloatT>::type ref_type;
typedef typename unwrap_reference_wrapper<ref_type>::type non_ref_type;
typedef typename remove_wrap<non_ref_type>::type arg_type;
//typedef typename remove_wrap<ref_type>::type arg_type;
n *= impl::real_traits<arg_type>::pow(10, exp - int(frac));
first = i1;
return hit;
}
mutable actual_type n;
};
///////////////////////////////////////////////////////////////////////////////
//
template <typename TraitsT = numeric_parser_traits<> >
struct ureal_parser_gen :
public ureal_parser<double, TraitsT>
{
ureal_parser_gen()
: ureal_parser<double, TraitsT>(0) {}
template <typename T>
typename real_numeric_action_traits<T, void (*)(T), TraitsT>::ureal_action
operator [] (void (*actor)(T)) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename real_numeric_action_traits<T, void(*)(T), TraitsT>::ureal_action
action_t;
return action_t(actor);
}
template <typename T>
typename real_numeric_action_traits< typename unwrap_reference_wrapper<T>::type,
T, TraitsT>::ureal_action
operator [] (T const& actor) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename real_numeric_action_traits<
unwrap_reference_wrapper<T>::type,T, TraitsT
>::ureal_action action_t ;
return action_t(actor);
}
// Helper function for specifying a numeric_parser_traits type when using
// the predefined parser ureal_p. Now we could write ureal_p(mytraits())[...],
// where 'mytraits' is a class, which defines the same names as the
// 'numeric_parser_traits' template.
template <typename NewTraitsT>
ureal_parser_gen<NewTraitsT>
operator ()(NewTraitsT) const
{
return ureal_parser_gen<NewTraitsT>();
}
};
///////////////////////////////////////////////////////////////////////////////
// Predefined unsigned floating point parser
//
// The underlying base type (float, double etc.) is selected automatically at
// compile time through the type accociated with the attached semantic action.
// If no sematic action is used, double will be selected.
const ureal_parser_gen<> ureal_p = ureal_parser_gen<>();
///////////////////////////////////////////////////////////////////////////////
//
// real_parser class
//
// Parses signed reals. A real_parser is never directly
// instantiated. An instance of the real_parser_gen, real_p,
// generates a real_parser through its [] operator:
//
// real_p[f]
//
// where f is a semantic action which may be a function or a
// functor. A function should be compatible with the interface:
//
// void f(NumT num);
//
// A functor should have a member operator() with a compatible
// signature as above. The matching number is passed into the
// function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename FloatT = double , typename TraitsT = numeric_parser_traits<> >
struct real_parser :
public parser<
real_parser< FloatT, TraitsT>
>
{
typedef typename impl::IF<is_reference_wrapper<FloatT>::value,
typename unwrap_reference_wrapper<FloatT>::type&,
FloatT>::RET actual_type;
real_parser(actual_type n_)
: n(n_) {}
template <typename IteratorT>
match
parse(IteratorT& first, IteratorT const& last) const
{
n = 0;
if (first == last)
return match();
typedef typename impl::strip_scanner<IteratorT>
::iterator_type plain_iter;
plain_iter i1 = impl::strip_scanner<IteratorT>::get(first);
plain_iter i2 = impl::strip_scanner<IteratorT>::get(last);
unsigned count;
bool neg = impl::extract_sign(i1, count);
ureal_parser_gen<TraitsT> parse_ureal;
if (match hit = parse_ureal[ref(n)].parse(i1, i2))
{
if (neg) n = -n;
first = i1;
return match(hit.length() + count);
}
return match();
}
mutable actual_type n;
//mutable FloatT n;
};
///////////////////////////////////////////////////////////////////////////////
template <typename TraitsT = numeric_parser_traits<> >
struct real_parser_gen :
public real_parser<double, TraitsT>
{
real_parser_gen()
: real_parser<double, TraitsT>(0) {}
template <typename T>
typename real_numeric_action_traits<T, void (*)(T), TraitsT>::real_action
operator [] (void (*actor)(T)) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename real_numeric_action_traits<T, void(*)(T) ,TraitsT>::real_action
action_t;
return action_t(actor);
}
template <typename T>
typename real_numeric_action_traits<typename unwrap_reference_wrapper<T>::type,
T, TraitsT>::real_action
operator [] (T const& actor) const
{
//functors and reference_wrappers will fall through here
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
typedef typename real_numeric_action_traits<
unwrap_reference_wrapper<T>::type, T, TraitsT
>::real_action action_t ;
return action_t(actor);
}
// Helper function for specifying a numeric_parser_traits type when using
// the predefined parser real_p. Now we could write real_p(mytraits())[...],
// where 'mytraits' is a class, which defines the same names as the
// 'numeric_parser_traits' template.
template <typename NewTraitsT>
real_parser_gen<NewTraitsT>
operator ()(NewTraitsT) const
{
return real_parser_gen<NewTraitsT>();
}
};
///////////////////////////////////////////////////////////////////////////////
// Predefined signed floating point parser
//
// The underlying base type (float, double etc.) is selected automatically at
// compile time through the type associated with the attached semantic action.
// If no sematic action is used, double will be selected.
const real_parser_gen<> real_p = real_parser_gen<>();
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -