static bool parse(Iterator& first, Iterator const& last, Attribute& attr, RealPolicies const& p) { if (first == last) return false; Iterator save = first; // Start by parsing the sign. neg will be true if // we got a "-" sign, false otherwise. bool neg = p.parse_sign(first, last); // Now attempt to parse an integer T n = 0; bool got_a_number = p.parse_n(first, last, n); // If we did not get a number it might be a NaN, Inf or a leading // dot. if (!got_a_number) { // Check whether the number to parse is a NaN or Inf if (p.parse_nan(first, last, n) || p.parse_inf(first, last, n)) { // If we got a negative sign, negate the number traits::move_to(traits::negate(neg, n), attr); return true; // got a NaN or Inf, return early } // If we did not get a number and our policies do not // allow a leading dot, fail and return early (no-match) if (!p.allow_leading_dot) { first = save; return false; } } bool e_hit = false; int frac_digits = 0; // Try to parse the dot ('.' decimal point) if (p.parse_dot(first, last)) { // 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. Iterator savef = first; if (p.parse_frac_n(first, last, n)) { // Optimization note: don't compute frac_digits if T is // an unused_type. This should be optimized away by the compiler. if (!is_same<T, unused_type>::value) frac_digits = static_cast<int>(std::distance(savef, first)); } else if (!got_a_number || !p.allow_trailing_dot) { // We did not get a fraction. If we still haven't got a // number and our policies do not allow a trailing dot, // return no-match. first = save; return false; } // Now, let's see if we can parse the exponent prefix e_hit = p.parse_exp(first, last); } else { // No dot and no number! Return no-match. if (!got_a_number) { first = save; return false; } // If we must expect a dot and we didn't see an exponent // prefix, return no-match. e_hit = p.parse_exp(first, last); if (p.expect_dot && !e_hit) { first = save; return false; } } 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. int exp = 0; if (p.parse_exp_n(first, last, exp)) { // Got the exponent value. Scale the number by // exp-frac_digits. traits::scale(exp, frac_digits, n); } else { // Oops, no exponent, return no-match. first = save; return false; } } else if (frac_digits) { // No exponent found. Scale the number by -frac_digits. traits::scale(-frac_digits, n); } else if (traits::is_equal_to_one(n)) { // There is a chance of having to parse one of the 1.0#... // styles some implementations use for representing NaN or Inf. // Check whether the number to parse is a NaN or Inf if (p.parse_nan(first, last, n) || p.parse_inf(first, last, n)) { // If we got a negative sign, negate the number traits::move_to(traits::negate(neg, n), attr); return true; // got a NaN or Inf, return immediately } } // If we got a negative sign, negate the number traits::move_to(traits::negate(neg, n), attr); // Success!!! return true; }
static bool parse(Iterator& first, Iterator const& last, Attribute& attr, RealPolicies const& p) { if (first == last) return false; Iterator save = first; // Start by parsing the sign. neg will be true if // we got a "-" sign, false otherwise. bool neg = p.parse_sign(first, last); // Now attempt to parse an integer T n; typename traits::real_accumulator<T>::type acc_n = 0; bool got_a_number = p.parse_n(first, last, acc_n); // If we did not get a number it might be a NaN, Inf or a leading // dot. if (!got_a_number) { // Check whether the number to parse is a NaN or Inf if (p.parse_nan(first, last, n) || p.parse_inf(first, last, n)) { // If we got a negative sign, negate the number traits::assign_to(traits::negate(neg, n), attr); return true; // got a NaN or Inf, return early } // If we did not get a number and our policies do not // allow a leading dot, fail and return early (no-match) if (!p.allow_leading_dot) { first = save; return false; } } bool e_hit = false; Iterator e_pos; int frac_digits = 0; // Try to parse the dot ('.' decimal point) if (p.parse_dot(first, last)) { // 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 (p.parse_frac_n(first, last, acc_n, frac_digits)) { } else if (!got_a_number || !p.allow_trailing_dot) { // We did not get a fraction. If we still haven't got a // number and our policies do not allow a trailing dot, // return no-match. first = save; return false; } // Now, let's see if we can parse the exponent prefix e_pos = first; e_hit = p.parse_exp(first, last); } else { // No dot and no number! Return no-match. if (!got_a_number) { first = save; return false; } // If we must expect a dot and we didn't see an exponent // prefix, return no-match. e_pos = first; e_hit = p.parse_exp(first, last); if (p.expect_dot && !e_hit) { first = save; return false; } } if (e_hit) { // We got the exponent prefix. Now we will try to parse the // actual exponent. int exp = 0; if (p.parse_exp_n(first, last, exp)) { // Got the exponent value. Scale the number by // exp-frac_digits. if (!traits::scale(exp, frac_digits, n, acc_n)) return false; } else { // If there is no number, disregard the exponent altogether. // by resetting 'first' prior to the exponent prefix (e|E) first = e_pos; n = static_cast<T>(acc_n); } } else if (frac_digits) { // No exponent found. Scale the number by -frac_digits. traits::scale(-frac_digits, n, acc_n); } else if (traits::is_equal_to_one(acc_n)) { // There is a chance of having to parse one of the 1.0#... // styles some implementations use for representing NaN or Inf. // Check whether the number to parse is a NaN or Inf if (p.parse_nan(first, last, n) || p.parse_inf(first, last, n)) { // If we got a negative sign, negate the number traits::assign_to(traits::negate(neg, n), attr); return true; // got a NaN or Inf, return immediately } n = static_cast<T>(acc_n); } else { n = static_cast<T>(acc_n); } // If we got a negative sign, negate the number traits::assign_to(traits::negate(neg, n), attr); // Success!!! return true; }