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(BOOST_SPIRIT_X3_REAL_POLICIES_APRIL_17_2006_1158PM) 9 #define BOOST_SPIRIT_X3_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 // a number to parse does not start with a digit (after having 78 // successfully parsed an optional sign). 79 // 80 // The functions should return true if a Nan or Inf has been found. In 81 // this case the attr should be set to the matched value (NaN or 82 // Inf). The optional sign will be automatically applied afterwards. 83 // 84 // The default implementation below recognizes representations of NaN 85 // and Inf as mandated by the C99 Standard and as proposed for 86 // inclusion into the C++0x Standard: nan, nan(...), inf and infinity 87 // (the matching is performed case-insensitively). 88 /////////////////////////////////////////////////////////////////////// 89 template <typename Iterator, typename Attribute> 90 static bool parse_nanboost::spirit::x3::ureal_policies91 parse_nan(Iterator& first, Iterator const& last, Attribute& attr_) 92 { 93 if (first == last) 94 return false; // end of input reached 95 96 if (*first != 'n' && *first != 'N') 97 return false; // not "nan" 98 99 // nan[(...)] ? 100 if (detail::string_parse("nan", "NAN", first, last, unused)) 101 { 102 if (first != last && *first == '(') 103 { 104 // skip trailing (...) part 105 Iterator i = first; 106 107 while (++i != last && *i != ')') 108 ; 109 if (i == last) 110 return false; // no trailing ')' found, give up 111 112 first = ++i; 113 } 114 attr_ = std::numeric_limits<T>::quiet_NaN(); 115 return true; 116 } 117 return false; 118 } 119 120 template <typename Iterator, typename Attribute> 121 static bool parse_infboost::spirit::x3::ureal_policies122 parse_inf(Iterator& first, Iterator const& last, Attribute& attr_) 123 { 124 if (first == last) 125 return false; // end of input reached 126 127 if (*first != 'i' && *first != 'I') 128 return false; // not "inf" 129 130 // inf or infinity ? 131 if (detail::string_parse("inf", "INF", first, last, unused)) 132 { 133 // skip allowed 'inity' part of infinity 134 detail::string_parse("inity", "INITY", first, last, unused); 135 attr_ = std::numeric_limits<T>::infinity(); 136 return true; 137 } 138 return false; 139 } 140 }; 141 142 /////////////////////////////////////////////////////////////////////////// 143 // Default (signed) real number policies 144 /////////////////////////////////////////////////////////////////////////// 145 template <typename T> 146 struct real_policies : ureal_policies<T> 147 { 148 template <typename Iterator> 149 static bool parse_signboost::spirit::x3::real_policies150 parse_sign(Iterator& first, Iterator const& last) 151 { 152 return extract_sign(first, last); 153 } 154 }; 155 156 template <typename T> 157 struct strict_ureal_policies : ureal_policies<T> 158 { 159 static bool const expect_dot = true; 160 }; 161 162 template <typename T> 163 struct strict_real_policies : real_policies<T> 164 { 165 static bool const expect_dot = true; 166 }; 167 }}} 168 169 #endif 170