📄 numeric_utils.hpp
字号:
// Copyright (c) 2001-2008 Hartmut Kaiser// // Distributed under 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)#if !defined(BOOST_SPIRIT_KARMA_NUMERIC_UTILS_FEB_23_2007_0841PM)#define BOOST_SPIRIT_KARMA_NUMERIC_UTILS_FEB_23_2007_0841PM#if defined(_MSC_VER) && (_MSC_VER >= 1020)#pragma once // MS compatible compilers support #pragma once#endif#include <boost/config/no_tr1/cmath.hpp>#include <limits>#include <boost/type_traits/is_integral.hpp>#include <boost/spirit/home/support/char_class.hpp>#include <boost/spirit/home/support/iso8859_1.hpp>#include <boost/spirit/home/support/ascii.hpp>#include <boost/spirit/home/support/unused.hpp>#include <boost/spirit/home/karma/detail/generate_to.hpp>#include <boost/spirit/home/karma/detail/string_generate.hpp>#include <boost/spirit/home/support/detail/math/fpclassify.hpp>#include <boost/spirit/home/support/detail/math/signbit.hpp>/////////////////////////////////////////////////////////////////////////////////// The value BOOST_KARMA_NUMERICS_LOOP_UNROLL specifies, how to unroll the // integer string generation loop (see below).//// Set the value to some integer in between 0 (no unrolling) and the // largest expected generated integer string length (complete unrolling). // If not specified, this value defaults to 6./////////////////////////////////////////////////////////////////////////////////#if !defined(BOOST_KARMA_NUMERICS_LOOP_UNROLL)#define BOOST_KARMA_NUMERICS_LOOP_UNROLL 6#endif#if BOOST_KARMA_NUMERICS_LOOP_UNROLL < 0 #error "Please set the BOOST_KARMA_NUMERICS_LOOP_UNROLL to a positive value!"#endifnamespace boost { namespace spirit { namespace karma { namespace detail { /////////////////////////////////////////////////////////////////////// // // return the absolute value from a given number, avoiding over- and // underflow // /////////////////////////////////////////////////////////////////////// inline unsigned short absolute_value (short n) { return (n >= 0) ? n : (unsigned short)(-n); } inline unsigned int absolute_value (int n) { return (n >= 0) ? n : (unsigned int)(-n); } inline unsigned long absolute_value (long n) { return (n >= 0) ? n : (unsigned long)(-n); }#ifdef BOOST_HAS_LONG_LONG inline boost::ulong_long_type absolute_value (boost::long_long_type n) { return (n >= 0) ? n : (boost::ulong_long_type)(-n); }#endif inline float absolute_value (float n) { return boost::math::signbit(n) ? boost::math::changesign(n) : n; } inline double absolute_value (double n) { return boost::math::signbit(n) ? boost::math::changesign(n) : n; } inline long double absolute_value (long double n) { return boost::math::signbit(n) ? boost::math::changesign(n) : n; } template <typename T> inline T absolute_value (T n) { using namespace std; return fabs(n); } /////////////////////////////////////////////////////////////////////// inline bool is_negative(float n) { return boost::math::signbit(n); } inline bool is_negative(double n) { return boost::math::signbit(n); } inline bool is_negative(long double n) { return boost::math::signbit(n); } template <typename T> inline bool is_negative(T n) { return (n < 0) ? true : false; } /////////////////////////////////////////////////////////////////////// inline bool is_zero(float n) { return boost::math::fpclassify(n) == FP_ZERO; } inline bool is_zero(double n) { return boost::math::fpclassify(n) == FP_ZERO; } inline bool is_zero(long double n) { return boost::math::fpclassify(n) == FP_ZERO; } template <typename T> inline bool is_zero(T n) { return (n == 0) ? true : false; } /////////////////////////////////////////////////////////////////////// struct cast_to_long { static long call(float n, mpl::false_) { return static_cast<long>(std::floor(n)); } static long call(double n, mpl::false_) { return static_cast<long>(std::floor(n)); } static long call(long double n, mpl::false_) { return static_cast<long>(std::floor(n)); } template <typename T> static long call(T n, mpl::false_) { // allow for ADL to find the correct overload for floor and // lround using namespace std; return lround(floor(n)); } template <typename T> static long call(T n, mpl::true_) { return static_cast<long>(n); } template <typename T> static long call(T n) { return call(n, mpl::bool_<is_integral<T>::value>()); } }; /////////////////////////////////////////////////////////////////////// struct round_to_long { static long call(float n, mpl::false_) { return static_cast<long>(std::floor(n + 0.5f)); } static long call(double n, mpl::false_) { return static_cast<long>(std::floor(n + 0.5)); } static long call(long double n, mpl::false_) { return static_cast<long>(std::floor(n + 0.5l)); } template <typename T> static long call(T n, mpl::false_) { using namespace std; return lround(n); } template <typename T> static long call(T n, mpl::true_) { return static_cast<long>(n); } template <typename T> static long call(T n) { return call(n, mpl::bool_<is_integral<T>::value>()); } }; /////////////////////////////////////////////////////////////////////// // // Traits class for radix specific number conversion // // Convert a digit from binary representation to character // representation: // // static int digit(unsigned n); // /////////////////////////////////////////////////////////////////////// template<unsigned Radix, typename Tag> struct radix_traits; // Binary template<typename Tag> struct radix_traits<2, Tag> { static int digit(unsigned n) { return n + '0'; } }; // Octal template<typename Tag> struct radix_traits<8, Tag> { static int digit(unsigned n) { return n + '0'; } }; // Decimal template<typename Tag> struct radix_traits<10, Tag> { static int digit(unsigned n) { return n + '0'; } }; // Hexadecimal, lower case template<> struct radix_traits<16, unused_type> { static int digit(unsigned n) { if (n <= 9) return n + '0'; return n - 10 + 'a'; } }; // Hexadecimal, upper case template<typename Tag> struct radix_traits<16, Tag> { typedef typename Tag::char_set char_set; typedef typename Tag::char_class char_class_; static int digit(unsigned n) { if (n <= 9) return n + '0'; using spirit::char_class::convert; return convert<char_set>::to(char_class_(), n - 10 + 'a'); } }; /////////////////////////////////////////////////////////////////////// template <unsigned Radix> struct divide { template <typename T> static T call(T& n, mpl::true_) { return n / Radix; } template <typename T> static T call(T& n, mpl::false_) { // Allow ADL to find the correct overload for floor using namespace std; return floor(n / Radix); } template <typename T> static T call(T& n) { return call(n, mpl::bool_<is_integral<T>::value>()); } }; /////////////////////////////////////////////////////////////////////// template <unsigned Radix> struct remainder
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -