Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:46

0001 /*=============================================================================
0002     Copyright (c) 2001-2019 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // So that we won't exceed the capacity of the underlying type T,
0022     // we limit the number of digits parsed to its max_digits10.
0023     // By default, the value is -1 which tells spirit to parse an
0024     // unbounded number of digits.
0025 
0026     template <typename T, typename Enable = void>
0027     struct max_digits10
0028     {
0029         static int const value = -1;  // unbounded
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     //  Default (unsigned) real number policies
0045     ///////////////////////////////////////////////////////////////////////////
0046     template <typename T>
0047     struct ureal_policies
0048     {
0049         // Versioning
0050         typedef mpl::int_<2> version;
0051 
0052         // trailing dot policy suggested by Gustavo Guerra
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& /*first*/, Iterator const& /*last*/)
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 // See notes on max_digits10 above
0070             , false, true>
0071             extract_uint;
0072             return extract_uint::call(first, last, attr_);
0073         }
0074 
0075         // ignore_excess_digits (required for version > 1 API)
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) // conditional expression is constant
0107 #endif
0108                 // Optimization note: don't compute frac_digits if T is
0109                 // an unused_type. This should be optimized away by the compiler.
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                 // ignore extra (non-significant digits)
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         //  The parse_nan() and parse_inf() functions get called whenever
0141         //  a number to parse does not start with a digit (after having
0142         //  successfully parsed an optional sign).
0143         //
0144         //  The functions should return true if a Nan or Inf has been found. In
0145         //  this case the attr should be set to the matched value (NaN or
0146         //  Inf). The optional sign will be automatically applied afterwards.
0147         //
0148         //  The default implementation below recognizes representations of NaN
0149         //  and Inf as mandated by the C99 Standard and as proposed for
0150         //  inclusion into the C++0x Standard: nan, nan(...), inf and infinity
0151         //  (the matching is performed case-insensitively).
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;   // end of input reached
0159 
0160             if (*first != 'n' && *first != 'N')
0161                 return false;   // not "nan"
0162 
0163             // nan[(...)] ?
0164             if (detail::string_parse("nan", "NAN", first, last, unused))
0165             {
0166                 if (first != last && *first == '(')
0167                 {
0168                     // skip trailing (...) part
0169                     Iterator i = first;
0170 
0171                     while (++i != last && *i != ')')
0172                         ;
0173                     if (i == last)
0174                         return false;     // no trailing ')' found, give up
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;   // end of input reached
0190 
0191             if (*first != 'i' && *first != 'I')
0192                 return false;   // not "inf"
0193 
0194             // inf or infinity ?
0195             if (detail::string_parse("inf", "INF", first, last, unused))
0196             {
0197                 // skip allowed 'inity' part of infinity
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     //  Default (signed) real number policies
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