numerics.ipp

来自「Boost provides free peer-reviewed portab」· IPP 代码 · 共 479 行 · 第 1/2 页

IPP
479
字号
                T digit;                while( allow_more_digits<MaxDigits>(i) && !scan.at_end() &&                    radix_traits<Radix>::digit(*scan, digit) )                {                    if (!Accumulate::add(n, digit))                        return false; // Overflow                    ++i, ++scan, ++count;                }                return i >= MinDigits;            }        };        ///////////////////////////////////////////////////////////////////////        //        //  uint_parser_impl class        //        ///////////////////////////////////////////////////////////////////////        template <            typename T = unsigned,            int Radix = 10,            unsigned MinDigits = 1,            int MaxDigits = -1        >        struct uint_parser_impl            : parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> >        {            typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;            template <typename ScannerT>            struct result            {                typedef typename match_result<ScannerT, T>::type type;            };            template <typename ScannerT>            typename parser_result<self_t, ScannerT>::type            parse(ScannerT const& scan) const            {                if (!scan.at_end())                {                    T n = 0;                    std::size_t count = 0;                    typename ScannerT::iterator_t save = scan.first;                    if (extract_int<Radix, MinDigits, MaxDigits,                        positive_accumulate<T, Radix> >::f(scan, n, count))                    {                        return scan.create_match(count, n, save, scan.first);                    }                    // return no-match if number overflows                }                return scan.no_match();            }        };        ///////////////////////////////////////////////////////////////////////        //        //  int_parser_impl class        //        ///////////////////////////////////////////////////////////////////////        template <            typename T = unsigned,            int Radix = 10,            unsigned MinDigits = 1,            int MaxDigits = -1        >        struct int_parser_impl            : parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> >        {            typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;            template <typename ScannerT>            struct result            {                typedef typename match_result<ScannerT, T>::type type;            };            template <typename ScannerT>            typename parser_result<self_t, ScannerT>::type            parse(ScannerT const& scan) const            {                typedef extract_int<Radix, MinDigits, MaxDigits,                    negative_accumulate<T, Radix> > extract_int_neg_t;                typedef extract_int<Radix, MinDigits, MaxDigits,                    positive_accumulate<T, Radix> > extract_int_pos_t;                if (!scan.at_end())                {                    T n = 0;                    std::size_t count = 0;                    typename ScannerT::iterator_t save = scan.first;                    bool hit = impl::extract_sign(scan, count);                    if (hit)                        hit = extract_int_neg_t::f(scan, n, count);                    else                        hit = extract_int_pos_t::f(scan, n, count);                    if (hit)                        return scan.create_match(count, n, save, scan.first);                    else                        scan.first = save;                    // return no-match if number overflows or underflows                }                return scan.no_match();            }        };        ///////////////////////////////////////////////////////////////////////        //        //  real_parser_impl class        //        ///////////////////////////////////////////////////////////////////////#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))#pragma warning(push)#pragma warning(disable:4127)#endif        template <typename RT, typename T, typename RealPoliciesT>        struct real_parser_impl        {            typedef real_parser_impl<RT, T, RealPoliciesT> self_t;            template <typename ScannerT>            RT parse_main(ScannerT const& scan) const            {                if (scan.at_end())                    return scan.no_match();                typename ScannerT::iterator_t save = scan.first;                typedef typename parser_result<sign_parser, ScannerT>::type                    sign_match_t;                typedef typename parser_result<chlit<>, ScannerT>::type                    exp_match_t;                sign_match_t    sign_match = RealPoliciesT::parse_sign(scan);                std::size_t     count = sign_match ? sign_match.length() : 0;                bool            neg = sign_match.has_valid_attribute() ?                                    sign_match.value() : false;                RT              n_match = RealPoliciesT::parse_n(scan);                T               n = n_match.has_valid_attribute() ?                                    n_match.value() : T(0);                bool            got_a_number = n_match;                exp_match_t     e_hit;                if (!got_a_number && !RealPoliciesT::allow_leading_dot)                     return scan.no_match();                else                    count += n_match.length();                if (neg)                    n = -n;                if (RealPoliciesT::parse_dot(scan))                {                    //  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.                    if (RT hit = RealPoliciesT::parse_frac_n(scan))                    {#if !defined(BOOST_NO_STDC_NAMESPACE)                        using namespace std;  // allow for ADL to find pow()#endif                        hit.value(hit.value()                            * pow(T(10), T(-hit.length())));                        if (neg)                            n -= hit.value();                        else                            n += hit.value();                        count += hit.length() + 1;                    }                    else if (!got_a_number ||                        !RealPoliciesT::allow_trailing_dot)                        return scan.no_match();                    e_hit = RealPoliciesT::parse_exp(scan);                }                else                {                    //  We have reached a point where we                    //  still haven't seen a number at all.                    //  We return early with a no-match.                    if (!got_a_number)                        return scan.no_match();                    //  If we must expect a dot and we didn't see                    //  an exponent, return early with a no-match.                    e_hit = RealPoliciesT::parse_exp(scan);                    if (RealPoliciesT::expect_dot && !e_hit)                        return scan.no_match();                }                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.                    if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan))                    {#if !defined(BOOST_NO_STDC_NAMESPACE)                        using namespace std;    // allow for ADL to find pow()#endif                        n *= pow(T(10), T(e_n_hit.value()));                        count += e_n_hit.length() + e_hit.length();                    }                    else                    {                        //  Oops, no exponent, return a no-match                        return scan.no_match();                    }                }                return scan.create_match(count, n, save, scan.first);            }            template <typename ScannerT>            static RT parse(ScannerT const& scan)            {                static self_t this_;                return impl::implicit_lexeme_parse<RT>(this_, scan, scan);            }        };#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))#pragma warning(pop)#endif    }   //  namespace impl///////////////////////////////////////////////////////////////////////////////BOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace boost::spirit#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?