|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r71242 - in trunk/boost/spirit/home: karma/numeric karma/numeric/detail qi/numeric/detail support support/detail
From: hartmut.kaiser_at_[hidden]
Date: 2011-04-14 09:05:20
Author: hkaiser
Date: 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
New Revision: 71242
URL: http://svn.boost.org/trac/boost/changeset/71242
Log:
Spirit: refactoring some of the numeric helpers into customization points
Text files modified:
trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp | 644 +++++++++++++++++++++------------------
trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp | 25
trunk/boost/spirit/home/karma/numeric/int.hpp | 12
trunk/boost/spirit/home/karma/numeric/real_policies.hpp | 19
trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp | 2
trunk/boost/spirit/home/support/adapt_adt_attributes.hpp | 1
trunk/boost/spirit/home/support/detail/pow10.hpp | 117 ++++---
trunk/boost/spirit/home/support/numeric_traits.hpp | 15
8 files changed, 454 insertions(+), 381 deletions(-)
Modified: trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -17,6 +17,7 @@
#include <boost/type_traits/is_integral.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/numeric_traits.hpp>
#include <boost/spirit/home/support/detail/pow10.hpp>
#include <boost/spirit/home/support/detail/sign.hpp>
#include <boost/spirit/home/karma/detail/generate_to.hpp>
@@ -40,34 +41,32 @@
#error "Please set the BOOST_KARMA_NUMERICS_LOOP_UNROLL to a non-negative value!"
#endif
-namespace boost { namespace spirit { namespace karma
+namespace boost { namespace spirit { namespace traits
{
- namespace detail
+ ///////////////////////////////////////////////////////////////////////
+ //
+ // return the absolute value from a given number, avoiding over- and
+ // underflow
+ //
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable/* = void*/>
+ struct absolute_value
{
- ///////////////////////////////////////////////////////////////////////
- //
- // return the absolute value from a given number, avoiding over- and
- // underflow
- //
- ///////////////////////////////////////////////////////////////////////
- template <typename T>
- struct absolute_value_helper
+ typedef T type;
+ static T call (T n)
{
- typedef T result_type;
- static T call (T n)
- {
- // allow for ADL to find the correct overloads for fabs
- using namespace std;
- return fabs(n);
- }
- };
+ // allow for ADL to find the correct overloads for fabs
+ using namespace std;
+ return fabs(n);
+ }
+ };
-#define BOOST_SPIRIT_ABSOLUTE_VALUE(type, unsignedtype) \
+#define BOOST_SPIRIT_ABSOLUTE_VALUE(signedtype, unsignedtype) \
template <> \
- struct absolute_value_helper<type> \
+ struct absolute_value<signedtype> \
{ \
- typedef unsignedtype result_type; \
- static result_type call(type n) \
+ typedef unsignedtype type; \
+ static type call(signedtype n) \
{ \
return (n >= 0) ? n : (unsignedtype)(-n); \
} \
@@ -75,367 +74,410 @@
/**/
#define BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsignedtype) \
template <> \
- struct absolute_value_helper<unsignedtype> \
+ struct absolute_value<unsignedtype> \
{ \
- typedef unsignedtype result_type; \
- static result_type call(unsignedtype n) \
+ typedef unsignedtype type; \
+ static type call(unsignedtype n) \
{ \
return n; \
} \
} \
/**/
- BOOST_SPIRIT_ABSOLUTE_VALUE(signed char, unsigned char);
- BOOST_SPIRIT_ABSOLUTE_VALUE(char, unsigned char);
- BOOST_SPIRIT_ABSOLUTE_VALUE(short, unsigned short);
- BOOST_SPIRIT_ABSOLUTE_VALUE(int, unsigned int);
- BOOST_SPIRIT_ABSOLUTE_VALUE(long, unsigned long);
- BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned char);
- BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned short);
- BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned int);
- BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned long);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(signed char, unsigned char);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(char, unsigned char);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(short, unsigned short);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(int, unsigned int);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(long, unsigned long);
+ BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned char);
+ BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned short);
+ BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned int);
+ BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(unsigned long);
#ifdef BOOST_HAS_LONG_LONG
- BOOST_SPIRIT_ABSOLUTE_VALUE(boost::long_long_type, boost::ulong_long_type);
- BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(boost::ulong_long_type);
+ BOOST_SPIRIT_ABSOLUTE_VALUE(boost::long_long_type, boost::ulong_long_type);
+ BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED(boost::ulong_long_type);
#endif
#undef BOOST_SPIRIT_ABSOLUTE_VALUE
#undef BOOST_SPIRIT_ABSOLUTE_VALUE_UNSIGNED
- template <>
- struct absolute_value_helper<float>
+ template <>
+ struct absolute_value<float>
+ {
+ typedef float type;
+ static type call(float n)
{
- typedef float result_type;
- static result_type call(float n)
- {
- return (spirit::detail::signbit)(n) ? -n : n;
- }
- };
+ return (spirit::detail::signbit)(n) ? -n : n;
+ }
+ };
- template <>
- struct absolute_value_helper<double>
+ template <>
+ struct absolute_value<double>
+ {
+ typedef double type;
+ static type call(double n)
{
- typedef double result_type;
- static result_type call(double n)
- {
- return (spirit::detail::signbit)(n) ? -n : n;
- }
- };
+ return (spirit::detail::signbit)(n) ? -n : n;
+ }
+ };
- template <>
- struct absolute_value_helper<long double>
+ template <>
+ struct absolute_value<long double>
+ {
+ typedef long double type;
+ static type call(long double n)
{
- typedef long double result_type;
- static result_type call(long double n)
- {
- return (spirit::detail::signbit)(n) ? -n : n;
- }
- };
+ return (spirit::detail::signbit)(n) ? -n : n;
+ }
+ };
- // specialization for pointers
- template <typename T>
- struct absolute_value_helper<T*>
+ // specialization for pointers
+ template <typename T>
+ struct absolute_value<T*>
+ {
+ typedef std::size_t type;
+ static type call (T* p)
{
- typedef std::size_t result_type;
- static std::size_t call (T* p)
- {
- return std::size_t(p);
- }
- };
+ return std::size_t(p);
+ }
+ };
- template <typename T>
- typename absolute_value_helper<T>::result_type
- absolute_value(T n)
- {
- return absolute_value_helper<T>::call(n);
+ template <typename T>
+ inline typename absolute_value<T>::type
+ get_absolute_value(T n)
+ {
+ return absolute_value<T>::call(n);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable/* = void*/>
+ struct is_negative
+ {
+ static bool call(T n)
+ {
+ return (n < 0) ? true : false;
}
+ };
- ///////////////////////////////////////////////////////////////////////
- inline bool is_negative(float n)
+ template <>
+ struct is_negative<float>
+ {
+ static bool call(float n)
{
return (spirit::detail::signbit)(n) ? true : false;
}
+ };
- inline bool is_negative(double n)
+ template <>
+ struct is_negative<double>
+ {
+ static bool call(double n)
{
return (spirit::detail::signbit)(n) ? true : false;
}
+ };
- inline bool is_negative(long double n)
+ template <>
+ struct is_negative<long double>
+ {
+ static bool call(long double n)
{
return (spirit::detail::signbit)(n) ? true : false;
}
+ };
- template <typename T>
- inline bool is_negative(T n)
- {
- return (n < 0) ? true : false;
+ template <typename T>
+ inline bool test_negative(T n)
+ {
+ return is_negative<T>::call(n);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable/* = void*/>
+ struct is_zero
+ {
+ static bool call(T n)
+ {
+ return (n == 0) ? true : false;
}
+ };
- ///////////////////////////////////////////////////////////////////////
- inline bool is_zero(float n)
+ template <>
+ struct is_zero<float>
+ {
+ static bool call(float n)
{
return (math::fpclassify)(n) == FP_ZERO;
}
+ };
- inline bool is_zero(double n)
+ template <>
+ struct is_zero<double>
+ {
+ static bool call(double n)
{
return (math::fpclassify)(n) == FP_ZERO;
}
+ };
- inline bool is_zero(long double n)
+ template <>
+ struct is_zero<long double>
+ {
+ static bool call(long double n)
{
return (math::fpclassify)(n) == FP_ZERO;
}
+ };
- template <typename T>
- inline bool is_zero(T n)
+ template <typename T>
+ inline bool test_zero(T n)
+ {
+ return is_zero<T>::call(n);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ struct cast_to_long
+ {
+ static long call(float n, mpl::false_)
{
- return (n == 0) ? true : false;
+ return static_cast<long>(std::floor(n));
}
- ///////////////////////////////////////////////////////////////////////
- struct cast_to_long
+ static long call(double n, mpl::false_)
{
- 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));
- }
+ return static_cast<long>(std::floor(n));
+ }
- static long call(long 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::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, mpl::true_)
+ {
+ return static_cast<long>(n);
+ }
- template <typename T>
- static long call(T n)
- {
- return call(n, mpl::bool_<is_integral<T>::value>());
- }
- };
+ template <typename T>
+ static long call(T n)
+ {
+ return call(n, mpl::bool_<is_integral<T>::value>());
+ }
+ };
- ///////////////////////////////////////////////////////////////////////
- struct truncate_to_long
+ ///////////////////////////////////////////////////////////////////////
+ struct truncate_to_long
+ {
+ static long call(float n, mpl::false_)
{
- static long call(float n, mpl::false_)
- {
- return is_negative(n) ? static_cast<long>(std::ceil(n)) :
- static_cast<long>(std::floor(n));
- }
+ return test_negative(n) ? static_cast<long>(std::ceil(n)) :
+ static_cast<long>(std::floor(n));
+ }
- static long call(double n, mpl::false_)
- {
- return is_negative(n) ? static_cast<long>(std::ceil(n)) :
- static_cast<long>(std::floor(n));
- }
+ static long call(double n, mpl::false_)
+ {
+ return test_negative(n) ? static_cast<long>(std::ceil(n)) :
+ static_cast<long>(std::floor(n));
+ }
- static long call(long double n, mpl::false_)
- {
- return is_negative(n) ? static_cast<long>(std::ceil(n)) :
- static_cast<long>(std::floor(n));
- }
+ static long call(long double n, mpl::false_)
+ {
+ return test_negative(n) ? static_cast<long>(std::ceil(n)) :
+ static_cast<long>(std::floor(n));
+ }
- template <typename T>
- static long call(T n, mpl::false_)
- {
- // allow for ADL to find the correct overloads for ltrunc
- using namespace std;
- return ltrunc(n);
- }
+ template <typename T>
+ static long call(T n, mpl::false_)
+ {
+ // allow for ADL to find the correct overloads for ltrunc
+ using namespace std;
+ return ltrunc(n);
+ }
- template <typename T>
- static long call(T n, mpl::true_)
- {
- return static_cast<long>(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>());
- }
- };
+ 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 CharEncoding, typename Tag>
- struct radix_traits;
-
- // Binary
- template<typename CharEncoding, typename Tag>
- struct radix_traits<2, CharEncoding, Tag>
+ ///////////////////////////////////////////////////////////////////////
+ //
+ // Traits class for radix specific number conversion
+ //
+ // Convert a digit from binary representation to character
+ // representation:
+ //
+ // static int call(unsigned n);
+ //
+ ///////////////////////////////////////////////////////////////////////
+ template <unsigned Radix, typename CharEncoding, typename Tag>
+ struct convert_digit;
+
+ // Binary
+ template <typename CharEncoding, typename Tag>
+ struct convert_digit<2, CharEncoding, Tag>
+ {
+ static int call(unsigned n)
{
- static int digit(unsigned n)
- {
- return n + '0';
- }
- };
+ return n + '0';
+ }
+ };
- // Octal
- template<typename CharEncoding, typename Tag>
- struct radix_traits<8, CharEncoding, Tag>
+ // Octal
+ template <typename CharEncoding, typename Tag>
+ struct convert_digit<8, CharEncoding, Tag>
+ {
+ static int call(unsigned n)
{
- static int digit(unsigned n)
- {
- return n + '0';
- }
- };
+ return n + '0';
+ }
+ };
- // Decimal
- template<typename CharEncoding, typename Tag>
- struct radix_traits<10, CharEncoding, Tag>
+ // Decimal
+ template <typename CharEncoding, typename Tag>
+ struct convert_digit<10, CharEncoding, Tag>
+ {
+ static int call(unsigned n)
{
- static int digit(unsigned n)
- {
- return n + '0';
- }
- };
+ return n + '0';
+ }
+ };
- // Hexadecimal, lower case
- template<>
- struct radix_traits<16, unused_type, unused_type>
+ // Hexadecimal, lower case
+ template <>
+ struct convert_digit<16, unused_type, unused_type>
+ {
+ static int call(unsigned n)
{
- static int digit(unsigned n)
- {
- if (n <= 9)
- return n + '0';
- return n - 10 + 'a';
- }
- };
+ if (n <= 9)
+ return n + '0';
+ return n - 10 + 'a';
+ }
+ };
- // Hexadecimal, upper case
- template<typename CharEncoding, typename Tag>
- struct radix_traits<16, CharEncoding, Tag>
+ // Hexadecimal, upper case
+ template <typename CharEncoding, typename Tag>
+ struct convert_digit<16, CharEncoding, Tag>
+ {
+ static int call(unsigned n)
{
- static int digit(unsigned n)
- {
- if (n <= 9)
- return n + '0';
+ if (n <= 9)
+ return n + '0';
- using spirit::char_class::convert;
- return convert<CharEncoding>::to(Tag(), n - 10 + 'a');
- }
- };
+ using spirit::char_class::convert;
+ return convert<CharEncoding>::to(Tag(), n - 10 + 'a');
+ }
+ };
- ///////////////////////////////////////////////////////////////////////
- template <unsigned Radix>
- struct divide
+ ///////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct divide
+ {
+ template <typename T>
+ static T call(T& n, mpl::true_)
{
- 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);
- }
+ return n / Radix;
+ }
- template <typename T>
- static T call(T& n, T const&, int)
- {
- return call(n, mpl::bool_<is_integral<T>::value>());
- }
+ 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 <typename T>
+ static T call(T& n, T const&, int)
+ {
+ return call(n, mpl::bool_<is_integral<T>::value>());
+ }
- // specialization for division by 10
- template <>
- struct divide<10>
+ template <typename T>
+ static T call(T& n)
{
- template <typename T>
- static T call(T& n, T, int, mpl::true_)
- {
- return n / 10;
- }
+ return call(n, mpl::bool_<is_integral<T>::value>());
+ }
+ };
- template <typename T>
- static T call(T, T& num, int exp, mpl::false_)
- {
- // Allow ADL to find the correct overload for floor
- using namespace std;
- return floor(num / spirit::detail::pow10<T>(exp));
- }
+ // specialization for division by 10
+ template <>
+ struct divide<10>
+ {
+ template <typename T>
+ static T call(T& n, T, int, mpl::true_)
+ {
+ return n / 10;
+ }
- template <typename T>
- static T call(T& n, T& num, int exp)
- {
- return call(n, num, exp, mpl::bool_<is_integral<T>::value>());
- }
+ template <typename T>
+ static T call(T, T& num, int exp, mpl::false_)
+ {
+ // Allow ADL to find the correct overload for floor
+ using namespace std;
+ return floor(num / spirit::traits::pow10<T>(exp));
+ }
- template <typename T>
- static T call(T& n)
- {
- return call(n, n, 1, mpl::bool_<is_integral<T>::value>());
- }
- };
+ template <typename T>
+ static T call(T& n, T& num, int exp)
+ {
+ return call(n, num, exp, mpl::bool_<is_integral<T>::value>());
+ }
- ///////////////////////////////////////////////////////////////////////
- template <unsigned Radix>
- struct remainder
+ template <typename T>
+ static T call(T& n)
{
- template <typename T>
- static long call(T n, mpl::true_)
- {
- // this cast is safe since we know the result is not larger
- // than Radix
- return static_cast<long>(n % Radix);
- }
+ return call(n, n, 1, mpl::bool_<is_integral<T>::value>());
+ }
+ };
- template <typename T>
- static long call(T n, mpl::false_)
- {
- // Allow ADL to find the correct overload for fmod
- using namespace std;
- return cast_to_long::call(fmod(n, T(Radix)));
- }
+ ///////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct remainder
+ {
+ template <typename T>
+ static long call(T n, mpl::true_)
+ {
+ // this cast is safe since we know the result is not larger
+ // than Radix
+ return static_cast<long>(n % Radix);
+ }
- template <typename T>
- static long call(T n)
- {
- return call(n, mpl::bool_<is_integral<T>::value>());
- }
- };
+ template <typename T>
+ static long call(T n, mpl::false_)
+ {
+ // Allow ADL to find the correct overload for fmod
+ using namespace std;
+ return cast_to_long::call(fmod(n, T(Radix)));
+ }
- } // namespace detail
+ template <typename T>
+ static long call(T n)
+ {
+ return call(n, mpl::bool_<is_integral<T>::value>());
+ }
+ };
+}}}
+namespace boost { namespace spirit { namespace karma
+{
///////////////////////////////////////////////////////////////////////////
//
// The int_inserter template takes care of the integer to string
@@ -448,8 +490,8 @@
//
///////////////////////////////////////////////////////////////////////////
#define BOOST_KARMA_NUMERICS_INNER_LOOP_PREFIX(z, x, data) \
- if (!detail::is_zero(n)) { \
- int ch = radix_type::digit(remainder_type::call(n)); \
+ if (!traits::test_zero(n)) { \
+ int ch = radix_type::call(remainder_type::call(n)); \
n = divide_type::call(n, num, ++exp); \
/**/
@@ -464,23 +506,23 @@
, typename Tag = unused_type>
struct int_inserter
{
- typedef detail::radix_traits<Radix, CharEncoding, Tag> radix_type;
- typedef detail::divide<Radix> divide_type;
- typedef detail::remainder<Radix> remainder_type;
+ typedef traits::convert_digit<Radix, CharEncoding, Tag> radix_type;
+ typedef traits::divide<Radix> divide_type;
+ typedef traits::remainder<Radix> remainder_type;
template <typename OutputIterator, typename T>
static bool
call(OutputIterator& sink, T n, T& num, int exp)
{
// remainder_type::call returns n % Radix
- int ch = radix_type::digit(remainder_type::call(n));
+ int ch = radix_type::call(remainder_type::call(n));
n = divide_type::call(n, num, ++exp);
BOOST_PP_REPEAT(
BOOST_KARMA_NUMERICS_LOOP_UNROLL,
BOOST_KARMA_NUMERICS_INNER_LOOP_PREFIX, _);
- if (!detail::is_zero(n))
+ if (!traits::test_zero(n))
call(sink, n, num, exp);
BOOST_PP_REPEAT(
@@ -576,7 +618,7 @@
static bool
call(OutputIterator& sink, T const& n)
{
- typedef typename detail::absolute_value_helper<T>::result_type type;
+ typedef typename traits::absolute_value<T>::type type;
type un = type(n);
return base_type::call(sink, un, un, 0);
}
Modified: trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -115,7 +115,7 @@
bool force_sign = p.force_sign(n);
bool sign_val = false;
int flags = p.floatfield(n);
- if (detail::is_negative(n))
+ if (traits::test_negative(n))
{
n = -n;
sign_val = true;
@@ -137,23 +137,23 @@
using namespace std;
U dim = 0;
- if (0 == (Policies::fmtflags::fixed & flags) && !detail::is_zero(n))
+ if (0 == (Policies::fmtflags::fixed & flags) && !traits::test_zero(n))
{
dim = log10(n);
if (dim > 0)
- n /= spirit::detail::pow10<U>(detail::truncate_to_long::call(dim));
+ n /= spirit::traits::pow10<U>(traits::truncate_to_long::call(dim));
else if (n < 1.) {
- long exp = detail::truncate_to_long::call(-dim);
+ long exp = traits::truncate_to_long::call(-dim);
if (exp != -dim)
++exp;
dim = -exp;
- n *= spirit::detail::pow10<U>(exp);
+ n *= spirit::traits::pow10<U>(exp);
}
}
// prepare numbers (sign, integer and fraction part)
U integer_part;
- U precexp = spirit::detail::pow10<U>(precision);
+ U precexp = spirit::traits::pow10<U>(precision);
U fractional_part = modf(n, &integer_part);
fractional_part = floor(fractional_part * precexp + U(0.5));
@@ -174,9 +174,9 @@
if (0 != long_frac_part) {
// remove the trailing zeros
while (0 != prec &&
- 0 == detail::remainder<10>::call(long_frac_part))
+ 0 == traits::remainder<10>::call(long_frac_part))
{
- long_frac_part = detail::divide<10>::call(long_frac_part);
+ long_frac_part = traits::divide<10>::call(long_frac_part);
--prec;
}
}
@@ -189,13 +189,13 @@
if (precision != prec)
{
long_frac_part = frac_part_floor /
- spirit::detail::pow10<U>(precision-prec);
+ spirit::traits::pow10<U>(precision-prec);
}
}
// call the actual generating functions to output the different parts
- if (sign_val && detail::is_zero(long_int_part) &&
- detail::is_zero(long_frac_part))
+ if (sign_val && traits::test_zero(long_int_part) &&
+ traits::test_zero(long_frac_part))
{
sign_val = false; // result is zero, no sign please
}
@@ -211,7 +211,7 @@
if (r && 0 == (Policies::fmtflags::fixed & flags)) {
return p.template exponent<CharEncoding, Tag>(sink,
- detail::truncate_to_long::call(dim));
+ traits::truncate_to_long::call(dim));
}
return r;
}
@@ -221,7 +221,6 @@
#endif
};
-
}}}
#endif
Modified: trunk/boost/spirit/home/karma/numeric/int.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/int.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/int.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -207,10 +207,10 @@
template <typename OutputIterator, typename Attribute>
static bool insert_int(OutputIterator& sink, Attribute const& attr)
{
- return sign_inserter::call(sink, detail::is_zero(attr)
- , detail::is_negative(attr), force_sign) &&
+ return sign_inserter::call(sink, traits::test_zero(attr)
+ , traits::test_negative(attr), force_sign) &&
int_inserter<Radix, CharEncoding, Tag>::call(sink
- , detail::absolute_value(attr));
+ , traits::get_absolute_value(attr));
}
public:
@@ -278,10 +278,10 @@
template <typename OutputIterator, typename Attribute>
static bool insert_int(OutputIterator& sink, Attribute const& attr)
{
- return sign_inserter::call(sink, detail::is_zero(attr)
- , detail::is_negative(attr), force_sign) &&
+ return sign_inserter::call(sink, traits::test_zero(attr)
+ , traits::test_negative(attr), force_sign) &&
int_inserter<Radix, CharEncoding, Tag>::call(sink
- , detail::absolute_value(attr));
+ , traits::get_absolute_value(attr));
}
public:
Modified: trunk/boost/spirit/home/karma/numeric/real_policies.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/real_policies.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/real_policies.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -142,10 +142,10 @@
///////////////////////////////////////////////////////////////////////
static int floatfield(T n)
{
- if (detail::is_zero(n))
+ if (traits::test_zero(n))
return fmtflags::fixed;
- T abs_n = detail::absolute_value(n);
+ T abs_n = traits::get_absolute_value(n);
return (abs_n >= 1e5 || abs_n < 1e-3)
? fmtflags::scientific : fmtflags::fixed;
}
@@ -187,7 +187,7 @@
, bool force_sign)
{
return sign_inserter::call(
- sink, detail::is_zero(n), sign, force_sign) &&
+ sink, traits::test_zero(n), sign, force_sign) &&
int_inserter<10>::call(sink, n);
}
@@ -259,7 +259,7 @@
// but it's spelled out to avoid inter-modular dependencies.
typename remove_const<T>::type digits =
- (detail::is_zero(n) ? 0 : floor(log10(n))) + 1;
+ (traits::test_zero(n) ? 0 : floor(log10(n))) + 1;
bool r = true;
for (/**/; r && digits < precision_; digits = digits + 1)
r = char_inserter<>::call(sink, '0');
@@ -284,10 +284,10 @@
template <typename CharEncoding, typename Tag, typename OutputIterator>
static bool exponent (OutputIterator& sink, long n)
{
- long abs_n = detail::absolute_value(n);
+ long abs_n = traits::get_absolute_value(n);
bool r = char_inserter<CharEncoding, Tag>::call(sink, 'e') &&
- sign_inserter::call(sink, detail::is_zero(n)
- , detail::is_negative(n), false);
+ sign_inserter::call(sink, traits::test_zero(n)
+ , traits::test_negative(n), false);
// the C99 Standard requires at least two digits in the exponent
if (r && abs_n < 10)
@@ -316,7 +316,7 @@
static bool nan (OutputIterator& sink, T n, bool force_sign)
{
return sign_inserter::call(
- sink, false, detail::is_negative(n), force_sign) &&
+ sink, false, traits::test_negative(n), force_sign) &&
string_inserter<CharEncoding, Tag>::call(sink, "nan");
}
@@ -324,11 +324,10 @@
static bool inf (OutputIterator& sink, T n, bool force_sign)
{
return sign_inserter::call(
- sink, false, detail::is_negative(n), force_sign) &&
+ sink, false, traits::test_negative(n), force_sign) &&
string_inserter<CharEncoding, Tag>::call(sink, "inf");
}
};
-
}}}
#endif // defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
Modified: trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -30,7 +30,7 @@
namespace boost { namespace spirit { namespace traits
{
- using spirit::detail::pow10;
+ using spirit::traits::pow10;
template <typename T>
inline void
Modified: trunk/boost/spirit/home/support/adapt_adt_attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/adapt_adt_attributes.hpp (original)
+++ trunk/boost/spirit/home/support/adapt_adt_attributes.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -12,6 +12,7 @@
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/numeric_traits.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/utility/enable_if.hpp>
Modified: trunk/boost/spirit/home/support/detail/pow10.hpp
==============================================================================
--- trunk/boost/spirit/home/support/detail/pow10.hpp (original)
+++ trunk/boost/spirit/home/support/detail/pow10.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -16,77 +16,94 @@
#include <boost/config/no_tr1/cmath.hpp>
#include <limits>
#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/numeric_traits.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
#endif
-namespace boost { namespace spirit { namespace detail
+namespace boost { namespace spirit { namespace traits
{
- template <typename T>
- inline T pow10(unsigned dim)
+ template <typename T, typename Enable/* = void*/>
+ struct pow10_helper
{
- using namespace std; // allow for ADL to find the correct overload
- return pow(T(10), T(dim));
- }
+ static T call(unsigned dim)
+ {
+ using namespace std; // allow for ADL to find the correct overload
+ return pow(T(10), T(dim));
+ }
+ };
template <>
- inline unused_type pow10<unused_type>(unsigned)
+ struct pow10_helper<unused_type>
{
- return unused;
- }
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
#if (DBL_MAX_EXP == 308) // for IEEE-754
template <>
- inline double pow10<double>(unsigned dim)
+ struct pow10_helper<double>
{
- static double const exponents[] =
+ static double call(unsigned dim)
{
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
- 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
- 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
- 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
- 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
- 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
- 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
- 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
- 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
- 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
- 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
- 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
- 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
- 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
- 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
- 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
- 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
- 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
- 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
- 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
- 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
- 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
- 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
- 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
- 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
- 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
- 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
- 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
- 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
- };
- BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
- return exponents[dim];
- }
+ static double const exponents[] =
+ {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
+ 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
+ 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
+ 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
+ 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
+ 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
+ 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
+ 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
+ };
+ BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
+ return exponents[dim];
+ }
+ };
template <>
- inline float pow10<float>(unsigned dim)
+ struct pow10_helper<double>
{
- return pow10<double>(dim);
- }
-
+ inline float pow10<float>(unsigned dim)
+ {
+ return pow10_helper<double>::call(dim);
+ }
+ };
#endif // for IEEE-754
+ template <typename T>
+ inline T pow10(unsigned dim)
+ {
+ return pow10_helper<T>::call(dim);
+ }
}}}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
Modified: trunk/boost/spirit/home/support/numeric_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/numeric_traits.hpp (original)
+++ trunk/boost/spirit/home/support/numeric_traits.hpp 2011-04-14 09:05:18 EDT (Thu, 14 Apr 2011)
@@ -92,6 +92,21 @@
template <>
struct is_real<long double> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // customization points for numeric operations
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct absolute_value;
+
+ template <typename T, typename Enable = void>
+ struct is_negative;
+
+ template <typename T, typename Enable = void>
+ struct is_zero;
+
+ template <typename T, typename Enable = void>
+ struct pow10_helper;
}}}
#endif
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk