📄 numerics.ipp
字号:
return hit;
}
///////////////////////////////////////////////////////////////////////////////
//
// uint_parser class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, const int Radix>
inline uint_parser<T, Radix>::uint_parser(T n_)
: n(n_) {}
//////////////////////////////////
template <typename T, const int Radix>
template <typename IteratorT>
inline match
uint_parser<T, Radix>::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 = 0;
if (!impl::radix_traits<Radix>::isok(*i1))
return match();
if (impl::extract<Radix>::uint(i1, i2, n, count)) {
first = i1;
return match(count);
}
return match(); // return non-match if uint overflows
}
//////////////////////////////////
template <typename T, const int Radix>
template <typename IteratorT, typename MatchTraitsT>
inline typename MatchTraitsT::match_t
uint_parser<T, Radix>::ast_parse(IteratorT& first, IteratorT const& last,
MatchTraitsT const& mt) const
{
n = 0;
if (first == last)
return MatchTraitsT::no_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 = 0;
if (!impl::radix_traits<Radix>::isok(*i1))
return MatchTraitsT::no_match;
if (impl::extract<Radix>::uint(i1, i2, n, count)) {
IteratorT s = first;
first = i1;
return MatchTraitsT::create_match(count, s, i1);
}
return MatchTraitsT::no_match; // return non-match if uint overflows
}
///////////////////////////////////////////////////////////////////////////////
//
// int_parser class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, const int Radix>
inline int_parser<T, Radix>::int_parser(T n_)
: n(n_) {}
//////////////////////////////////
template <typename T, const int Radix>
template <typename IteratorT>
inline match
int_parser<T, Radix>::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();
}
//////////////////////////////////
template <typename T, const int Radix>
template <typename IteratorT, typename MatchTraitsT>
inline typename MatchTraitsT::match_t
int_parser<T, Radix>::ast_parse(IteratorT& first, IteratorT const& last,
MatchTraitsT const& mt) const
{
n = 0;
if (first == last)
return MatchTraitsT::no_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);
typename MatchTraitsT::match_t hit =
MatchTraitsT::create_match(count, first, i1);
if (matched && hit)
{
if (neg) n = -n;
IteratorT s = first;
first = i1;
return hit;
}
return MatchTraitsT::no_match;
}
///////////////////////////////////////////////////////////////////////////////
namespace impl {
template <typename T> struct real_traits {};
template <typename T> struct real_traits<T&> : public real_traits<T> {};
#ifdef __MWERKS__
//////////////////////////////////
template <> struct real_traits<float> {
static float pow(float x, float y)
{ return std::powf(x, y); }
};
//////////////////////////////////
template <> struct real_traits<double> {
static double pow(double x, double y)
{ return std::pow(x, y); }
};
//////////////////////////////////
template <> struct real_traits<long double> {
static double pow(long double x, long double y)
{ return std::powl(x, y); }
};
#else
//////////////////////////////////
template <> struct real_traits<float> {
static float pow(float x, float y)
{ return static_cast<float>(std::pow(x, y)); }
};
//////////////////////////////////
template <> struct real_traits<double> {
static double pow(double x, double y)
{ return std::pow(x, y); }
};
//////////////////////////////////
template <> struct real_traits<long double> {
static double pow(long double x, long double y)
{ return std::pow(x, y); }
};
#endif
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// ureal_parser class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename TraitsT>
inline ureal_parser<T, TraitsT>::ureal_parser(T n_)
: n(n_) {}
//////////////////////////////////
template <typename FloatT, typename TraitsT>
template <typename IteratorT>
match
ureal_parser<FloatT, TraitsT>::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 remove_ref<FloatT>::type ref_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;
}
//////////////////////////////////
template <typename FloatT, typename TraitsT>
template <typename IteratorT, typename MatchTraitsT>
inline typename MatchTraitsT::match_t
ureal_parser<FloatT, TraitsT>::ast_parse(IteratorT& first,
IteratorT const& last, MatchTraitsT const& mt) const
{
n = 0;
if (first == last)
return MatchTraitsT::no_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 MatchTraitsT::no_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 MatchTraitsT::no_match;
if (i1 == i2)
{
typename MatchTraitsT::match_t rval =
MatchTraitsT::create_match(count, first, i1);
first = i1;
return rval;
}
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 MatchTraitsT::no_match;
count += frac;
}
// Extract the exponent
typename MatchTraitsT::match_t hit =
MatchTraitsT::create_match(count, first, i1);
int exp = 0;
if (impl::traits_cmp<TraitsT>::is_exp(i1, i2, count)) {
typename MatchTraitsT::match_t temphit =
MatchTraitsT::create_match(count, first, i1);
MatchTraitsT::extend(hit, temphit);
if (typename MatchTraitsT::match_t mexp =
int_p[ref(exp)].ast_parse(i1, i2, mt))
{
MatchTraitsT::extend(hit, mexp);
}
}
typedef typename remove_ref<FloatT>::type ref_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;
}
///////////////////////////////////////////////////////////////////////////////
//
// real_parser class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename FloatT, typename TraitsT>
inline real_parser<FloatT, TraitsT>::real_parser(FloatT n_)
: n(n_) {}
//////////////////////////////////
template <typename FloatT, typename TraitsT>
template <typename IteratorT>
inline match
real_parser<FloatT, TraitsT>::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();
}
//////////////////////////////////
template <typename FloatT, typename TraitsT>
template <typename IteratorT, typename MatchTraitsT>
inline typename MatchTraitsT::match_t
real_parser<FloatT, TraitsT>::ast_parse(IteratorT& first,
IteratorT const& last, MatchTraitsT const& mt) const
{
n = 0;
if (first == last)
return MatchTraitsT::no_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 (typename MatchTraitsT::match_t hit =
parse_ureal[ref(n)].ast_parse(i1, i2, mt))
{
if (neg) n = -n;
first = i1;
return hit;
}
return MatchTraitsT::no_match;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -