File indexing completed on 2025-01-19 09:47:46
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_SPIRIT_QI_NUMERIC_REAL_POLICIES_HPP
0009 #define BOOST_SPIRIT_QI_NUMERIC_REAL_POLICIES_HPP
0010
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014
0015 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
0016 #include <boost/spirit/home/qi/detail/string_parse.hpp>
0017 #include <boost/type_traits/is_floating_point.hpp>
0018
0019 namespace boost { namespace spirit { namespace traits
0020 {
0021
0022
0023
0024
0025
0026 template <typename T, typename Enable = void>
0027 struct max_digits10
0028 {
0029 static int const value = -1;
0030 };
0031
0032 template <typename T>
0033 struct max_digits10<T
0034 , typename enable_if_c<(is_floating_point<T>::value)>::type>
0035 {
0036 static int const digits = std::numeric_limits<T>::digits;
0037 static int const value = 2 + (digits * 30103l) / 100000l;
0038 };
0039 }}}
0040
0041 namespace boost { namespace spirit { namespace qi
0042 {
0043
0044
0045
0046 template <typename T>
0047 struct ureal_policies
0048 {
0049
0050 typedef mpl::int_<2> version;
0051
0052
0053 static bool const allow_leading_dot = true;
0054 static bool const allow_trailing_dot = true;
0055 static bool const expect_dot = false;
0056
0057 template <typename Iterator>
0058 static bool
0059 parse_sign(Iterator& , Iterator const& )
0060 {
0061 return false;
0062 }
0063
0064 template <typename Iterator, typename Attribute>
0065 static bool
0066 parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
0067 {
0068 typedef extract_uint<Attribute, 10, 1
0069 , traits::max_digits10<T>::value
0070 , false, true>
0071 extract_uint;
0072 return extract_uint::call(first, last, attr_);
0073 }
0074
0075
0076 template <typename Iterator>
0077 static std::size_t
0078 ignore_excess_digits(Iterator& first, Iterator const& last)
0079 {
0080 Iterator save = first;
0081 if (extract_uint<unused_type, 10, 1, -1>::call(first, last, unused))
0082 return static_cast<std::size_t>(std::distance(save, first));
0083 return 0;
0084 }
0085
0086 template <typename Iterator>
0087 static bool
0088 parse_dot(Iterator& first, Iterator const& last)
0089 {
0090 if (first == last || *first != '.')
0091 return false;
0092 ++first;
0093 return true;
0094 }
0095
0096 template <typename Iterator, typename Attribute>
0097 static bool
0098 parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_, int& frac_digits)
0099 {
0100 Iterator savef = first;
0101 bool r = extract_uint<Attribute, 10, 1, -1, true, true>::call(first, last, attr_);
0102 if (r)
0103 {
0104 #if defined(_MSC_VER) && _MSC_VER < 1900
0105 # pragma warning(push)
0106 # pragma warning(disable: 4127)
0107 #endif
0108
0109
0110 if (!is_same<T, unused_type>::value)
0111 frac_digits =
0112 static_cast<int>(std::distance(savef, first));
0113 #if defined(_MSC_VER) && _MSC_VER < 1900
0114 # pragma warning(pop)
0115 #endif
0116
0117 extract_uint<unused_type, 10, 1, -1>::call(first, last, unused);
0118 }
0119 return r;
0120 }
0121
0122 template <typename Iterator>
0123 static bool
0124 parse_exp(Iterator& first, Iterator const& last)
0125 {
0126 if (first == last || (*first != 'e' && *first != 'E'))
0127 return false;
0128 ++first;
0129 return true;
0130 }
0131
0132 template <typename Iterator>
0133 static bool
0134 parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
0135 {
0136 return extract_int<int, 10, 1, -1>::call(first, last, attr_);
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 template <typename Iterator, typename Attribute>
0154 static bool
0155 parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
0156 {
0157 if (first == last)
0158 return false;
0159
0160 if (*first != 'n' && *first != 'N')
0161 return false;
0162
0163
0164 if (detail::string_parse("nan", "NAN", first, last, unused))
0165 {
0166 if (first != last && *first == '(')
0167 {
0168
0169 Iterator i = first;
0170
0171 while (++i != last && *i != ')')
0172 ;
0173 if (i == last)
0174 return false;
0175
0176 first = ++i;
0177 }
0178 attr_ = std::numeric_limits<T>::quiet_NaN();
0179 return true;
0180 }
0181 return false;
0182 }
0183
0184 template <typename Iterator, typename Attribute>
0185 static bool
0186 parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
0187 {
0188 if (first == last)
0189 return false;
0190
0191 if (*first != 'i' && *first != 'I')
0192 return false;
0193
0194
0195 if (detail::string_parse("inf", "INF", first, last, unused))
0196 {
0197
0198 detail::string_parse("inity", "INITY", first, last, unused);
0199 attr_ = std::numeric_limits<T>::infinity();
0200 return true;
0201 }
0202 return false;
0203 }
0204 };
0205
0206
0207
0208
0209 template <typename T>
0210 struct real_policies : ureal_policies<T>
0211 {
0212 template <typename Iterator>
0213 static bool
0214 parse_sign(Iterator& first, Iterator const& last)
0215 {
0216 return extract_sign(first, last);
0217 }
0218 };
0219
0220 template <typename T>
0221 struct strict_ureal_policies : ureal_policies<T>
0222 {
0223 static bool const expect_dot = true;
0224 };
0225
0226 template <typename T>
0227 struct strict_real_policies : real_policies<T>
0228 {
0229 static bool const expect_dot = true;
0230 };
0231 }}}
0232
0233 #endif