]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/spirit/home/qi/numeric/real_policies.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / spirit / home / qi / numeric / real_policies.hpp
index d73a9dce8a076680fc269adc69fe676a515d4be4..0a1f87c3374e1f7a72549694cfb6b2baf52829b7 100644 (file)
@@ -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
 
 #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>
@@ -60,11 +101,18 @@ namespace boost { namespace spirit { namespace qi
             bool r = extract_uint<Attribute, 10, 1, -1, true, true>::call(first, last, attr_);
             if (r)
             {
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
                 // Optimization note: don't compute frac_digits if T is
                 // an unused_type. This should be optimized away by the compiler.
                 if (!is_same<T, unused_type>::value)
                     frac_digits =
                         static_cast<int>(std::distance(savef, first));
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# pragma warning(pop)
+#endif
                 // ignore extra (non-significant digits)
                 extract_uint<unused_type, 10, 1, -1>::call(first, last, unused);
             }
@@ -89,22 +137,9 @@ namespace boost { namespace spirit { namespace qi
         }
 
         ///////////////////////////////////////////////////////////////////////
-        //  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 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).
         //
         //  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