$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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