1 /*============================================================================= 2 Copyright (c) 2001-2014 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM) 9 #define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM 10 11 #include <boost/spirit/home/x3/string/detail/string_parse.hpp> 12 #include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp> 13 14 namespace boost { namespace spirit { namespace x3 15 { 16 /////////////////////////////////////////////////////////////////////////// 17 // Default (unsigned) real number policies 18 /////////////////////////////////////////////////////////////////////////// 19 template <typename T> 20 struct ureal_policies 21 { 22 // trailing dot policy suggested by Gustavo Guerra 23 static bool const allow_leading_dot = true; 24 static bool const allow_trailing_dot = true; 25 static bool const expect_dot = false; 26 27 template <typename Iterator> 28 static bool parse_signboost::spirit::x3::ureal_policies29 parse_sign(Iterator& /*first*/, Iterator const& /*last*/) 30 { 31 return false; 32 } 33 34 template <typename Iterator, typename Attribute> 35 static bool parse_nboost::spirit::x3::ureal_policies36 parse_n(Iterator& first, Iterator const& last, Attribute& attr_) 37 { 38 return extract_uint<T, 10, 1, -1>::call(first, last, attr_); 39 } 40 41 template <typename Iterator> 42 static bool parse_dotboost::spirit::x3::ureal_policies43 parse_dot(Iterator& first, Iterator const& last) 44 { 45 if (first == last || *first != '.') 46 return false; 47 ++first; 48 return true; 49 } 50 51 template <typename Iterator, typename Attribute> 52 static bool parse_frac_nboost::spirit::x3::ureal_policies53 parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_) 54 { 55 return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_); 56 } 57 58 template <typename Iterator> 59 static bool parse_expboost::spirit::x3::ureal_policies60 parse_exp(Iterator& first, Iterator const& last) 61 { 62 if (first == last || (*first != 'e' && *first != 'E')) 63 return false; 64 ++first; 65 return true; 66 } 67 68 template <typename Iterator> 69 static bool parse_exp_nboost::spirit::x3::ureal_policies70 parse_exp_n(Iterator& first, Iterator const& last, int& attr_) 71 { 72 return extract_int<int, 10, 1, -1>::call(first, last, attr_); 73 } 74 75 /////////////////////////////////////////////////////////////////////// 76 // The parse_nan() and parse_inf() functions get called whenever: 77 // 78 // - a number to parse does not start with a digit (after having 79 // successfully parsed an optional sign) 80 // 81 // or 82 // 83 // - after a floating point number of the value 1 (having no 84 // exponential part and a fractional part value of 0) has been 85 // parsed. 86 // 87 // The first call allows to recognize representations of NaN or Inf 88 // starting with a non-digit character (such as NaN, Inf, QNaN etc.). 89 // 90 // The second call allows to recognize representation formats starting 91 // with a 1.0 (such as 1.0#NAN or 1.0#INF etc.). 92 // 93 // The functions should return true if a Nan or Inf has been found. In 94 // this case the attr should be set to the matched value (NaN or 95 // Inf). The optional sign will be automatically applied afterwards. 96 // 97 // The default implementation below recognizes representations of NaN 98 // and Inf as mandated by the C99 Standard and as proposed for 99 // inclusion into the C++0x Standard: nan, nan(...), inf and infinity 100 // (the matching is performed case-insensitively). 101 /////////////////////////////////////////////////////////////////////// 102 template <typename Iterator, typename Attribute> 103 static bool parse_nanboost::spirit::x3::ureal_policies104 parse_nan(Iterator& first, Iterator const& last, Attribute& attr_) 105 { 106 if (first == last) 107 return false; // end of input reached 108 109 if (*first != 'n' && *first != 'N') 110 return false; // not "nan" 111 112 // nan[(...)] ? 113 if (detail::string_parse("nan", "NAN", first, last, unused)) 114 { 115 if (*first == '(') 116 { 117 // skip trailing (...) part 118 Iterator i = first; 119 120 while (++i != last && *i != ')') 121 ; 122 if (i == last) 123 return false; // no trailing ')' found, give up 124 125 first = ++i; 126 } 127 attr_ = std::numeric_limits<T>::quiet_NaN(); 128 return true; 129 } 130 return false; 131 } 132 133 template <typename Iterator, typename Attribute> 134 static bool parse_infboost::spirit::x3::ureal_policies135 parse_inf(Iterator& first, Iterator const& last, Attribute& attr_) 136 { 137 if (first == last) 138 return false; // end of input reached 139 140 if (*first != 'i' && *first != 'I') 141 return false; // not "inf" 142 143 // inf or infinity ? 144 if (detail::string_parse("inf", "INF", first, last, unused)) 145 { 146 // skip allowed 'inity' part of infinity 147 detail::string_parse("inity", "INITY", first, last, unused); 148 attr_ = std::numeric_limits<T>::infinity(); 149 return true; 150 } 151 return false; 152 } 153 }; 154 155 /////////////////////////////////////////////////////////////////////////// 156 // Default (signed) real number policies 157 /////////////////////////////////////////////////////////////////////////// 158 template <typename T> 159 struct real_policies : ureal_policies<T> 160 { 161 template <typename Iterator> 162 static bool parse_signboost::spirit::x3::real_policies163 parse_sign(Iterator& first, Iterator const& last) 164 { 165 return extract_sign(first, last); 166 } 167 }; 168 169 template <typename T> 170 struct strict_ureal_policies : ureal_policies<T> 171 { 172 static bool const expect_dot = true; 173 }; 174 175 template <typename T> 176 struct strict_real_policies : real_policies<T> 177 { 178 static bool const expect_dot = true; 179 }; 180 }}} 181 182 #endif 183