479 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			479 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								/*=============================================================================
							 | 
						||
| 
								 | 
							
								    Copyright (c) 1998-2003 Joel de Guzman
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2001-2003 Hartmut Kaiser
							 | 
						||
| 
								 | 
							
								    http://spirit.sourceforge.net/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Use, modification and distribution is subject to the Boost Software
							 | 
						||
| 
								 | 
							
								    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
							 | 
						||
| 
								 | 
							
								    http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								=============================================================================*/
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_SPIRIT_NUMERICS_IPP
							 | 
						||
| 
								 | 
							
								#define BOOST_SPIRIT_NUMERICS_IPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/config/no_tr1/cmath.hpp>
							 | 
						||
| 
								 | 
							
								#include <limits>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace spirit {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct sign_parser; // forward declaration only
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    namespace impl
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //  Extract the prefix sign (- or +)
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								        bool
							 | 
						||
| 
								 | 
							
								        extract_sign(ScannerT const& scan, std::size_t& count)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            //  Extract the sign
							 | 
						||
| 
								 | 
							
								            count = 0;
							 | 
						||
| 
								 | 
							
								            bool neg = *scan == '-';
							 | 
						||
| 
								 | 
							
								            if (neg || (*scan == '+'))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                ++scan;
							 | 
						||
| 
								 | 
							
								                ++count;
							 | 
						||
| 
								 | 
							
								                return neg;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //  Traits class for radix specific number conversion
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //      Convert a digit from character representation, ch, to binary
							 | 
						||
| 
								 | 
							
								        //      representation, returned in val.
							 | 
						||
| 
								 | 
							
								        //      Returns whether the conversion was successful.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //        template<typename CharT> static bool digit(CharT ch, T& val);
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template<const int Radix>
							 | 
						||
| 
								 | 
							
								        struct radix_traits;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ////////////////////////////////// Binary
							 | 
						||
| 
								 | 
							
								        template<>
							 | 
						||
| 
								 | 
							
								        struct radix_traits<2>
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template<typename CharT, typename T>
							 | 
						||
| 
								 | 
							
								            static bool digit(CharT ch, T& val)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                val = ch - '0';
							 | 
						||
| 
								 | 
							
								                return ('0' == ch || '1' == ch);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ////////////////////////////////// Octal
							 | 
						||
| 
								 | 
							
								        template<>
							 | 
						||
| 
								 | 
							
								        struct radix_traits<8>
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template<typename CharT, typename T>
							 | 
						||
| 
								 | 
							
								            static bool digit(CharT ch, T& val)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                val = ch - '0';
							 | 
						||
| 
								 | 
							
								                return ('0' <= ch && ch <= '7');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ////////////////////////////////// Decimal
							 | 
						||
| 
								 | 
							
								        template<>
							 | 
						||
| 
								 | 
							
								        struct radix_traits<10>
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template<typename CharT, typename T>
							 | 
						||
| 
								 | 
							
								            static bool digit(CharT ch, T& val)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                val = ch - '0';
							 | 
						||
| 
								 | 
							
								                return impl::isdigit_(ch);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ////////////////////////////////// Hexadecimal
							 | 
						||
| 
								 | 
							
								        template<>
							 | 
						||
| 
								 | 
							
								        struct radix_traits<16>
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template<typename CharT, typename T>
							 | 
						||
| 
								 | 
							
								            static bool digit(CharT ch, T& val)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (radix_traits<10>::digit(ch, val))
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                CharT lc = impl::tolower_(ch);
							 | 
						||
| 
								 | 
							
								                if ('a' <= lc && lc <= 'f')
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    val = lc - 'a' + 10;
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //      Helper templates for encapsulation of radix specific
							 | 
						||
| 
								 | 
							
								        //      conversion of an input string to an integral value.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //      main entry point:
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //          extract_int<Radix, MinDigits, MaxDigits, Accumulate>
							 | 
						||
| 
								 | 
							
								        //              ::f(first, last, n, count);
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //          The template parameter Radix represents the radix of the
							 | 
						||
| 
								 | 
							
								        //          number contained in the parsed string. The template
							 | 
						||
| 
								 | 
							
								        //          parameter MinDigits specifies the minimum digits to
							 | 
						||
| 
								 | 
							
								        //          accept. The template parameter MaxDigits specifies the
							 | 
						||
| 
								 | 
							
								        //          maximum digits to parse. A -1 value for MaxDigits will
							 | 
						||
| 
								 | 
							
								        //          make it parse an arbitrarilly large number as long as the
							 | 
						||
| 
								 | 
							
								        //          numeric type can hold it. Accumulate is either
							 | 
						||
| 
								 | 
							
								        //          positive_accumulate<Radix> (default) for parsing positive
							 | 
						||
| 
								 | 
							
								        //          numbers or negative_accumulate<Radix> otherwise.
							 | 
						||
| 
								 | 
							
								        //          Checking is only performed when std::numeric_limits<T>::
							 | 
						||
| 
								 | 
							
								        //          is_specialized is true. Otherwise, there's no way to
							 | 
						||
| 
								 | 
							
								        //          do the check.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //          scan.first and scan.last are iterators as usual (i.e.
							 | 
						||
| 
								 | 
							
								        //          first is mutable and is moved forward when a match is
							 | 
						||
| 
								 | 
							
								        //          found), n is a variable that holds the number (passed by
							 | 
						||
| 
								 | 
							
								        //          reference). The number of parsed characters is added to
							 | 
						||
| 
								 | 
							
								        //          count (also passed by reference)
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //      NOTE:
							 | 
						||
| 
								 | 
							
								        //              Returns a non-match, if the number to parse
							 | 
						||
| 
								 | 
							
								        //              overflows (or underflows) the used type.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //      BEWARE:
							 | 
						||
| 
								 | 
							
								        //              the parameters 'n' and 'count' should be properly
							 | 
						||
| 
								 | 
							
								        //              initialized before calling this function.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_MSVC)
							 | 
						||
| 
								 | 
							
								#pragma warning(push) 
							 | 
						||
| 
								 | 
							
								#pragma warning(disable:4127) //conditional expression is constant
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        template <typename T, int Radix>
							 | 
						||
| 
								 | 
							
								        struct positive_accumulate
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            //  Use this accumulator if number is positive
							 | 
						||
| 
								 | 
							
								            static bool add(T& n, T digit)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (std::numeric_limits<T>::is_specialized)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    static T const max = (std::numeric_limits<T>::max)();
							 | 
						||
| 
								 | 
							
								                    static T const max_div_radix = max/Radix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (n > max_div_radix)
							 | 
						||
| 
								 | 
							
								                        return false;
							 | 
						||
| 
								 | 
							
								                    n *= Radix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (n > max - digit)
							 | 
						||
| 
								 | 
							
								                        return false;
							 | 
						||
| 
								 | 
							
								                    n += digit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    n *= Radix;
							 | 
						||
| 
								 | 
							
								                    n += digit;
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <typename T, int Radix>
							 | 
						||
| 
								 | 
							
								        struct negative_accumulate
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            //  Use this accumulator if number is negative
							 | 
						||
| 
								 | 
							
								            static bool add(T& n, T digit)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (std::numeric_limits<T>::is_specialized)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    typedef std::numeric_limits<T> num_limits;
							 | 
						||
| 
								 | 
							
								                    static T const min =
							 | 
						||
| 
								 | 
							
								                        (!num_limits::is_integer && num_limits::is_signed && num_limits::has_denorm) ?
							 | 
						||
| 
								 | 
							
								                        -(num_limits::max)() : (num_limits::min)();
							 | 
						||
| 
								 | 
							
								                    static T const min_div_radix = min/Radix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (n < min_div_radix)
							 | 
						||
| 
								 | 
							
								                        return false;
							 | 
						||
| 
								 | 
							
								                    n *= Radix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (n < min + digit)
							 | 
						||
| 
								 | 
							
								                        return false;
							 | 
						||
| 
								 | 
							
								                    n -= digit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    n *= Radix;
							 | 
						||
| 
								 | 
							
								                    n -= digit;
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <int MaxDigits>
							 | 
						||
| 
								 | 
							
								        inline bool allow_more_digits(std::size_t i)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return i < MaxDigits;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <>
							 | 
						||
| 
								 | 
							
								        inline bool allow_more_digits<-1>(std::size_t)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <
							 | 
						||
| 
								 | 
							
								            int Radix, unsigned MinDigits, int MaxDigits,
							 | 
						||
| 
								 | 
							
								            typename Accumulate
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								        struct extract_int
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT, typename T>
							 | 
						||
| 
								 | 
							
								            static bool
							 | 
						||
| 
								 | 
							
								            f(ScannerT& scan, T& n, std::size_t& count)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                std::size_t i = 0;
							 | 
						||
| 
								 | 
							
								                T digit;
							 | 
						||
| 
								 | 
							
								                while( allow_more_digits<MaxDigits>(i) && !scan.at_end() &&
							 | 
						||
| 
								 | 
							
								                    radix_traits<Radix>::digit(*scan, digit) )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    if (!Accumulate::add(n, digit))
							 | 
						||
| 
								 | 
							
								                        return false; // Overflow
							 | 
						||
| 
								 | 
							
								                    ++i, ++scan, ++count;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return i >= MinDigits;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //  uint_parser_impl class
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <
							 | 
						||
| 
								 | 
							
								            typename T = unsigned,
							 | 
						||
| 
								 | 
							
								            int Radix = 10,
							 | 
						||
| 
								 | 
							
								            unsigned MinDigits = 1,
							 | 
						||
| 
								 | 
							
								            int MaxDigits = -1
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								        struct uint_parser_impl
							 | 
						||
| 
								 | 
							
								            : parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> >
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            struct result
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                typedef typename match_result<ScannerT, T>::type type;
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            typename parser_result<self_t, ScannerT>::type
							 | 
						||
| 
								 | 
							
								            parse(ScannerT const& scan) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (!scan.at_end())
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    T n = 0;
							 | 
						||
| 
								 | 
							
								                    std::size_t count = 0;
							 | 
						||
| 
								 | 
							
								                    typename ScannerT::iterator_t save = scan.first;
							 | 
						||
| 
								 | 
							
								                    if (extract_int<Radix, MinDigits, MaxDigits,
							 | 
						||
| 
								 | 
							
								                        positive_accumulate<T, Radix> >::f(scan, n, count))
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        return scan.create_match(count, n, save, scan.first);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    // return no-match if number overflows
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return scan.no_match();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //  int_parser_impl class
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <
							 | 
						||
| 
								 | 
							
								            typename T = unsigned,
							 | 
						||
| 
								 | 
							
								            int Radix = 10,
							 | 
						||
| 
								 | 
							
								            unsigned MinDigits = 1,
							 | 
						||
| 
								 | 
							
								            int MaxDigits = -1
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								        struct int_parser_impl
							 | 
						||
| 
								 | 
							
								            : parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> >
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            struct result
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                typedef typename match_result<ScannerT, T>::type type;
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            typename parser_result<self_t, ScannerT>::type
							 | 
						||
| 
								 | 
							
								            parse(ScannerT const& scan) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                typedef extract_int<Radix, MinDigits, MaxDigits,
							 | 
						||
| 
								 | 
							
								                    negative_accumulate<T, Radix> > extract_int_neg_t;
							 | 
						||
| 
								 | 
							
								                typedef extract_int<Radix, MinDigits, MaxDigits,
							 | 
						||
| 
								 | 
							
								                    positive_accumulate<T, Radix> > extract_int_pos_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (!scan.at_end())
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    T n = 0;
							 | 
						||
| 
								 | 
							
								                    std::size_t count = 0;
							 | 
						||
| 
								 | 
							
								                    typename ScannerT::iterator_t save = scan.first;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    bool hit = impl::extract_sign(scan, count);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (hit)
							 | 
						||
| 
								 | 
							
								                        hit = extract_int_neg_t::f(scan, n, count);
							 | 
						||
| 
								 | 
							
								                    else
							 | 
						||
| 
								 | 
							
								                        hit = extract_int_pos_t::f(scan, n, count);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (hit)
							 | 
						||
| 
								 | 
							
								                        return scan.create_match(count, n, save, scan.first);
							 | 
						||
| 
								 | 
							
								                    else
							 | 
						||
| 
								 | 
							
								                        scan.first = save;
							 | 
						||
| 
								 | 
							
								                    // return no-match if number overflows or underflows
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return scan.no_match();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //  real_parser_impl class
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ///////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename RT, typename T, typename RealPoliciesT>
							 | 
						||
| 
								 | 
							
								        struct real_parser_impl
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef real_parser_impl<RT, T, RealPoliciesT> self_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            RT parse_main(ScannerT const& scan) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (scan.at_end())
							 | 
						||
| 
								 | 
							
								                    return scan.no_match();
							 | 
						||
| 
								 | 
							
								                typename ScannerT::iterator_t save = scan.first;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                typedef typename parser_result<sign_parser, ScannerT>::type
							 | 
						||
| 
								 | 
							
								                    sign_match_t;
							 | 
						||
| 
								 | 
							
								                typedef typename parser_result<chlit<>, ScannerT>::type
							 | 
						||
| 
								 | 
							
								                    exp_match_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                sign_match_t    sign_match = RealPoliciesT::parse_sign(scan);
							 | 
						||
| 
								 | 
							
								                std::size_t     count = sign_match ? sign_match.length() : 0;
							 | 
						||
| 
								 | 
							
								                bool            neg = sign_match.has_valid_attribute() ?
							 | 
						||
| 
								 | 
							
								                                    sign_match.value() : false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                RT              n_match = RealPoliciesT::parse_n(scan);
							 | 
						||
| 
								 | 
							
								                T               n = n_match.has_valid_attribute() ?
							 | 
						||
| 
								 | 
							
								                                    n_match.value() : T(0);
							 | 
						||
| 
								 | 
							
								                bool            got_a_number = n_match;
							 | 
						||
| 
								 | 
							
								                exp_match_t     e_hit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (!got_a_number && !RealPoliciesT::allow_leading_dot)
							 | 
						||
| 
								 | 
							
								                     return scan.no_match();
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    count += n_match.length();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (neg)
							 | 
						||
| 
								 | 
							
								                    n = -n;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (RealPoliciesT::parse_dot(scan))
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    //  We got the decimal point. Now we will try to parse
							 | 
						||
| 
								 | 
							
								                    //  the fraction if it is there. If not, it defaults
							 | 
						||
| 
								 | 
							
								                    //  to zero (0) only if we already got a number.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (RT hit = RealPoliciesT::parse_frac_n(scan))
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								#if !defined(BOOST_NO_STDC_NAMESPACE)
							 | 
						||
| 
								 | 
							
								                        using namespace std;  // allow for ADL to find pow()
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                        hit.value(hit.value()
							 | 
						||
| 
								 | 
							
								                            * pow(T(10), T(-hit.length())));
							 | 
						||
| 
								 | 
							
								                        if (neg)
							 | 
						||
| 
								 | 
							
								                            n -= hit.value();
							 | 
						||
| 
								 | 
							
								                        else
							 | 
						||
| 
								 | 
							
								                            n += hit.value();
							 | 
						||
| 
								 | 
							
								                        count += hit.length() + 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    else if (!got_a_number ||
							 | 
						||
| 
								 | 
							
								                        !RealPoliciesT::allow_trailing_dot)
							 | 
						||
| 
								 | 
							
								                        return scan.no_match();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    e_hit = RealPoliciesT::parse_exp(scan);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    //  We have reached a point where we
							 | 
						||
| 
								 | 
							
								                    //  still haven't seen a number at all.
							 | 
						||
| 
								 | 
							
								                    //  We return early with a no-match.
							 | 
						||
| 
								 | 
							
								                    if (!got_a_number)
							 | 
						||
| 
								 | 
							
								                        return scan.no_match();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    //  If we must expect a dot and we didn't see
							 | 
						||
| 
								 | 
							
								                    //  an exponent, return early with a no-match.
							 | 
						||
| 
								 | 
							
								                    e_hit = RealPoliciesT::parse_exp(scan);
							 | 
						||
| 
								 | 
							
								                    if (RealPoliciesT::expect_dot && !e_hit)
							 | 
						||
| 
								 | 
							
								                        return scan.no_match();
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (e_hit)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    //  We got the exponent prefix. Now we will try to parse the
							 | 
						||
| 
								 | 
							
								                    //  actual exponent. It is an error if it is not there.
							 | 
						||
| 
								 | 
							
								                    if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan))
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								#if !defined(BOOST_NO_STDC_NAMESPACE)
							 | 
						||
| 
								 | 
							
								                        using namespace std;    // allow for ADL to find pow()
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                        n *= pow(T(10), T(e_n_hit.value()));
							 | 
						||
| 
								 | 
							
								                        count += e_n_hit.length() + e_hit.length();
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    else
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        //  Oops, no exponent, return a no-match
							 | 
						||
| 
								 | 
							
								                        return scan.no_match();
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                return scan.create_match(count, n, save, scan.first);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <typename ScannerT>
							 | 
						||
| 
								 | 
							
								            static RT parse(ScannerT const& scan)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                static self_t this_;
							 | 
						||
| 
								 | 
							
								                return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_MSVC)
							 | 
						||
| 
								 | 
							
								#pragma warning(pop)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }   //  namespace impl
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								BOOST_SPIRIT_CLASSIC_NAMESPACE_END
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}} // namespace boost::spirit
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |