📄 numerics.ipp
字号:
{
#if defined (BOOST_MSVC)
typedef typename spirit::iterator_traits<IteratorT>::value_type CharT;
#else
typedef typename std::iterator_traits<IteratorT>::value_type CharT;
#endif
return strlit<CharT>(pch).parse(it1, it2);
}
static match parse2 (PointerT pch, IteratorT &it1,
IteratorT const &it2)
{
return parse (pch, it1, it2);
}
};
*/
template<typename TraitsT>
struct traits_cmp {
// tests for decimal separator
template<typename IteratorT>
static bool is_ds(IteratorT &it1, IteratorT const &it2, unsigned &count)
{
typedef trait_type_cmp<IteratorT>
trait_type;
match mexpr =
trait_type::parse(TraitsT::decimal_sep_char, it1, it2);
if (mexpr) {
count += mexpr.length();
return true;
}
return false;
}
// tests for thousands separator
template<typename IteratorT>
static bool is_ts(IteratorT &it1, IteratorT const &it2, unsigned &count)
{
if (TraitsT::thousands_sep_char != 0) {
typedef trait_type_cmp<IteratorT> trait_type;
match mexpr =
trait_type::parse(TraitsT::thousands_sep_char, it1, it2);
if (mexpr) {
count += mexpr.length();
return true;
}
}
return false;
}
// tests for delimiter before exponent
template<typename IteratorT>
static bool is_exp(IteratorT &it1, IteratorT const &it2,
unsigned &count)
{
typedef trait_type_cmp<IteratorT> trait_type;
match mexpr = trait_type::parse2(TraitsT::exponent_char, it1, it2);
if (mexpr) {
count += mexpr.length();
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////////
// Helper template functors for distinction of overflow testing for signed and
// unsigned data types. The template parameter T represents the parsed data type.
template<typename T>
struct nochange : std::unary_function<T, T>
{
T operator()(const T& x) const { return x; }
};
template<typename T>
struct decrement : std::unary_function<T, T>
{
T operator()(const T& x) const { return x-1; }
};
// Helper template for encapsulation of radix specific conversion of an input
// string to an integral integer-like value.
//
// The template parameter Radix represents the radix of the number contained
// in the parsed string
template <const int Radix, typename TraitsT = numeric_parser_traits<> >
struct extract {
// Extract a signed integer
// Returns a non-match, if the number to parse overflows the used integral
// type.
//
// BEWARE: the parameters 'n' and 'count' should be proper initialized
// before calling this function.
template <typename IteratorT, typename T>
static bool sint(IteratorT& first, IteratorT const& last, T& n,
unsigned& count, bool neg)
{
typedef typename remove_wrap<T>::type arg_type;
if (!neg)
return uint(first, last, n, count, nochange<arg_type>());
//RAGAV -- def intel
// Intel V5.0.1 chokes without explicit template parameters
//return uint<IteratorT, T, decrement<arg_type> >(first, last, n,
// count, decrement<arg_type>());
return uint(first, last, n,
count, decrement<arg_type>());
}
// Extract an unsigned integer
// Return a non-match, if the number to parse overflows the used integral
// type.
//
// BEWARE: the parameters 'n' and 'count' should be proper initialized
// before calling this functions.
template <typename IteratorT, typename T>
static bool uint(IteratorT& first, IteratorT const& last, T& n,
unsigned& count)
{
typedef typename remove_wrap<T>::type arg_type;
return uint(first, last, n, count, nochange<arg_type>());
}
template <typename IteratorT, typename T, typename PredT>
static bool uint(IteratorT& first, IteratorT const& last, T& n,
unsigned& count, const PredT &pred)
{
typedef remove_wrap<T>::type arg_type;
const arg_type lim = numeric_limits<arg_type>::max()/Radix;
for (/**/; first != last; ++first, ++count)
{
// skip thousands separator if required
unsigned ts = 0;
if (traits_cmp<TraitsT>::is_ts(first, last, ts)) {
--first; // roll back for loop reinit
count += ts-1;
continue;
}
// handle only 'valid' (in the context of the actual radix) digits
if (radix_traits<Radix>::isok(*first)) {
if (n > lim) {
// overflow! return non-match
n = 0;
count = 0;
return false;
}
n *= Radix; // operation is now safe
arg_type nextdigit = radix_traits<Radix>::uint(*first);
if (pred(nextdigit) > numeric_limits<arg_type>::max() - n) {
// overflow! return non-match
n = 0;
count = 0;
return false;
}
n += nextdigit; // operation is now safe too
} else
break;
}
return true;
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
namespace impl {
template <typename T> struct real_traits {};
#if !defined (BOOST_MSVC)
template <typename T> struct real_traits<T&> : public real_traits<T> {};
#endif
#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>(::pow(x, y)); }
};
//////////////////////////////////
template <> struct real_traits<double> {
static double pow(double x, double y)
{ return ::pow(x, y); }
};
//////////////////////////////////
template <> struct real_traits<long double> {
static double pow(long double x, long double y)
{ return ::pow(x, y); }
};
#if defined(BOOST_MSVC)
//////////////////////////////////
template <> struct real_traits<float&> {
static float pow(float x, float y)
{ return static_cast<float>(::pow(x, y)); }
};
//////////////////////////////////
template <> struct real_traits<double&> {
static double pow(double x, double y)
{ return ::pow(x, y); }
};
//////////////////////////////////
template <> struct real_traits<long double&> {
static double pow(long double x, long double y)
{ return ::pow(x, y); }
};
#endif // BOOST_MSVC
#endif
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -