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