diff options
Diffstat (limited to 'boost/spirit/home/qi/numeric/real_policies.hpp')
-rw-r--r-- | boost/spirit/home/qi/numeric/real_policies.hpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/boost/spirit/home/qi/numeric/real_policies.hpp b/boost/spirit/home/qi/numeric/real_policies.hpp index 48cf2b97a5..185a108b8b 100644 --- a/boost/spirit/home/qi/numeric/real_policies.hpp +++ b/boost/spirit/home/qi/numeric/real_policies.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2019 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -14,6 +14,29 @@ #include <boost/spirit/home/qi/numeric/numeric_utils.hpp> #include <boost/spirit/home/qi/detail/string_parse.hpp> +#include <boost/type_traits/is_floating_point.hpp> + +namespace boost { namespace spirit { namespace traits +{ + // So that we won't exceed the capacity of the underlying type T, + // we limit the number of digits parsed to its max_digits10. + // By default, the value is -1 which tells spirit to parse an + // unbounded number of digits. + + template <typename T, typename Enable = void> + struct max_digits10 + { + static int const value = -1; // unbounded + }; + + template <typename T> + struct max_digits10<T + , typename enable_if_c<(is_floating_point<T>::value)>::type> + { + static int const digits = std::numeric_limits<T>::digits; + static int const value = 2 + (digits * 30103l) / 100000l; + }; +}}} namespace boost { namespace spirit { namespace qi { @@ -23,6 +46,9 @@ namespace boost { namespace spirit { namespace qi template <typename T> struct ureal_policies { + // Versioning + typedef mpl::int_<2> version; + // trailing dot policy suggested by Gustavo Guerra static bool const allow_leading_dot = true; static bool const allow_trailing_dot = true; @@ -39,7 +65,22 @@ namespace boost { namespace spirit { namespace qi static bool parse_n(Iterator& first, Iterator const& last, Attribute& attr_) { - return extract_uint<Attribute, 10, 1, -1>::call(first, last, attr_); + typedef extract_uint<Attribute, 10, 1 + , traits::max_digits10<T>::value // See notes on max_digits10 above + , false, true> + extract_uint; + return extract_uint::call(first, last, attr_); + } + + // ignore_excess_digits (required for version > 1 API) + template <typename Iterator> + static std::size_t + ignore_excess_digits(Iterator& first, Iterator const& last) + { + Iterator save = first; + if (extract_uint<unused_type, 10, 1, -1>::call(first, last, unused)) + return std::distance(save, first); + return 0; } template <typename Iterator> |