⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numerics.ipp

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 IPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================
    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 <cmath>

#if defined(BOOST_NO_STDC_NAMESPACE)
#  define BOOST_SPIRIT_IMPL_STD_NS
#else
#  define BOOST_SPIRIT_IMPL_STD_NS std
#endif

namespace boost { namespace spirit {

    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
        //
        //      Test the validity of a single character:
        //
        //          template<typename CharT> static bool is_valid(CharT ch);
        //
        //      Convert a digit from character representation to binary
        //      representation:
        //
        //          template<typename CharT> static int digit(CharT ch);
        //
        ///////////////////////////////////////////////////////////////////////
        template<const int Radix>
        struct radix_traits;

        ////////////////////////////////// Binary
        template<>
        struct radix_traits<2>
        {
            template<typename CharT>
            static bool is_valid(CharT ch) 
            { 
                return ('0' == ch || '1' == ch); 
            }

            template<typename CharT>
            static int digit(CharT ch) 
            { 
                return ch - '0'; 
            }
        };

        ////////////////////////////////// Octal
        template<>
        struct radix_traits<8>
        {
            template<typename CharT>
            static bool is_valid(CharT ch) 
            { 
                return ('0' <= ch && ch <= '7'); 
            }

            template<typename CharT>
            static int digit(CharT ch) 
            { 
                return ch - '0'; 
            }
        };

        ////////////////////////////////// Decimal
        template<>
        struct radix_traits<10>
        {
            template<typename CharT>
            static bool is_valid(CharT ch) 
            { 
                return impl::isdigit_(ch); 
            }

            template<typename CharT>
            static int digit(CharT ch) 
            { 
                return ch - '0'; 
            }
        };

        ////////////////////////////////// Hexadecimal
        template<>
        struct radix_traits<16>
        {
            template<typename CharT>
            static bool is_valid(CharT ch) 
            { 
                return impl::isxdigit_(ch); 
            }

            template<typename CharT>
            static int digit(CharT ch)
            {
                if (impl::isdigit_(ch))
                    return ch - '0';
                return impl::tolower_(ch) - 'a' + 10;
            }
        };

        ///////////////////////////////////////////////////////////////////////
        //
        //      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.
        //
        //          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 integral type.
        //              Overflow (or underflow) is detected when an
        //              operation wraps a value from its maximum to its
        //              minimum (or vice-versa). For example, overflow
        //              occurs when the result of the expression n * x is
        //              less than n (assuming n is positive and x is 
        //              greater than 1).
        //
        //      BEWARE:
        //              the parameters 'n' and 'count' should be properly
        //              initialized before calling this function.
        //
        ///////////////////////////////////////////////////////////////////////
        template <int Radix>
        struct positive_accumulate
        {
            //  Use this accumulator if number is positive

            template <typename T>
            static bool check(T const& n, T const& prev)
            { 
                return n < prev; 
            }

            template <typename T, typename CharT>
            static void add(T& n, CharT ch)
            { 
                n += radix_traits<Radix>::digit(ch); 
            }
        };

        template <int Radix>
        struct negative_accumulate
        {
            //  Use this accumulator if number is negative

            template <typename T>
            static bool check(T const& n, T const& prev)
            { 
                return n > prev; 
            }

            template <typename T, typename CharT>
            static void add(T& n, CharT ch)
            { 
                n -= radix_traits<Radix>::digit(ch); 
            }
        };

        template <int Radix, typename Accumulate>
        struct extract_int_base
        {
            //  Common code for extract_int specializations
            template <typename ScannerT, typename T>
            static bool
            f(ScannerT& scan, T& n)
            {
                T prev = n;
                n *= Radix;
                if (Accumulate::check(n, prev))
                    return false;   //  over/underflow!
                prev = n;
                Accumulate::add(n, *scan);
                if (Accumulate::check(n, prev))
                    return false;   //  over/underflow!
                return true;
            }
        };

        template <bool Bounded>
        struct extract_int_
        {
            template <
                int Radix,
                unsigned MinDigits,
                int MaxDigits,
                typename Accumulate
            >
            struct apply
            {
                typedef extract_int_base<Radix, Accumulate> base;
                typedef radix_traits<Radix> check;

                template <typename ScannerT, typename T>
                static bool
                f(ScannerT& scan, T& n, std::size_t& count)
                {
                    std::size_t i = 0;
                    for (; (i < MaxDigits) && !scan.at_end()
                        && check::is_valid(*scan);
                        ++i, ++scan, ++count)
                    {
                        if (!base::f(scan, n))
                            return false;   //  over/underflow!
                    }
                    return i >= MinDigits;
                }
            };
        };

        template <>
        struct extract_int_<false>
        {
            template <

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -