Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM) Chris@16: #define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit { namespace qi Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Default (unsigned) real number policies Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct ureal_policies Chris@16: { Chris@16: // trailing dot policy suggested by Gustavo Guerra Chris@16: static bool const allow_leading_dot = true; Chris@16: static bool const allow_trailing_dot = true; Chris@16: static bool const expect_dot = false; Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_sign(Iterator& /*first*/, Iterator const& /*last*/) Chris@16: { Chris@16: return false; Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_n(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: return extract_uint::call(first, last, attr_); Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_dot(Iterator& first, Iterator const& last) Chris@16: { Chris@16: if (first == last || *first != '.') Chris@16: return false; Chris@16: ++first; Chris@16: return true; Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: return extract_uint::call(first, last, attr_); Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_exp(Iterator& first, Iterator const& last) Chris@16: { Chris@16: if (first == last || (*first != 'e' && *first != 'E')) Chris@16: return false; Chris@16: ++first; Chris@16: return true; Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_exp_n(Iterator& first, Iterator const& last, int& attr_) Chris@16: { Chris@16: return extract_int::call(first, last, attr_); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: // The parse_nan() and parse_inf() functions get called whenever: Chris@16: // Chris@16: // - a number to parse does not start with a digit (after having Chris@16: // successfully parsed an optional sign) Chris@16: // Chris@16: // or Chris@16: // Chris@16: // - after a floating point number of the value 1 (having no Chris@16: // exponential part and a fractional part value of 0) has been Chris@16: // parsed. Chris@16: // Chris@16: // The first call allows to recognize representations of NaN or Inf Chris@16: // starting with a non-digit character (such as NaN, Inf, QNaN etc.). Chris@16: // Chris@16: // The second call allows to recognize representation formats starting Chris@16: // with a 1.0 (such as 1.0#NAN or 1.0#INF etc.). Chris@16: // Chris@16: // The functions should return true if a Nan or Inf has been found. In Chris@16: // this case the attr should be set to the matched value (NaN or Chris@16: // Inf). The optional sign will be automatically applied afterwards. Chris@16: // Chris@16: // The default implementation below recognizes representations of NaN Chris@16: // and Inf as mandated by the C99 Standard and as proposed for Chris@16: // inclusion into the C++0x Standard: nan, nan(...), inf and infinity Chris@16: // (the matching is performed case-insensitively). Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: static bool Chris@16: parse_nan(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: if (first == last) Chris@16: return false; // end of input reached Chris@16: Chris@16: if (*first != 'n' && *first != 'N') Chris@16: return false; // not "nan" Chris@16: Chris@16: // nan[(...)] ? Chris@16: if (detail::string_parse("nan", "NAN", first, last, unused)) Chris@16: { Chris@101: if (first != last && *first == '(') Chris@16: { Chris@16: // skip trailing (...) part Chris@16: Iterator i = first; Chris@16: Chris@16: while (++i != last && *i != ')') Chris@16: ; Chris@16: if (i == last) Chris@16: return false; // no trailing ')' found, give up Chris@16: Chris@16: first = ++i; Chris@16: } Chris@16: attr_ = std::numeric_limits::quiet_NaN(); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: template Chris@16: static bool Chris@16: parse_inf(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: if (first == last) Chris@16: return false; // end of input reached Chris@16: Chris@16: if (*first != 'i' && *first != 'I') Chris@16: return false; // not "inf" Chris@16: Chris@16: // inf or infinity ? Chris@16: if (detail::string_parse("inf", "INF", first, last, unused)) Chris@16: { Chris@16: // skip allowed 'inity' part of infinity Chris@16: detail::string_parse("inity", "INITY", first, last, unused); Chris@16: attr_ = std::numeric_limits::infinity(); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Default (signed) real number policies Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct real_policies : ureal_policies Chris@16: { Chris@16: template Chris@16: static bool Chris@16: parse_sign(Iterator& first, Iterator const& last) Chris@16: { Chris@16: return extract_sign(first, last); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct strict_ureal_policies : ureal_policies Chris@16: { Chris@16: static bool const expect_dot = true; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct strict_real_policies : real_policies Chris@16: { Chris@16: static bool const expect_dot = true; Chris@16: }; Chris@16: }}} Chris@16: Chris@16: #endif