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 + -
显示快捷键?