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