⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numerics.ipp

📁 著名的Parser库Spirit在VC6上的Port
💻 IPP
📖 第 1 页 / 共 2 页
字号:
    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 + -