$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78112 - in sandbox/fixed_point: boost/fixed_point libs/fixed_point/example
From: vicente.botet_at_[hidden]
Date: 2012-04-21 08:26:53
Author: viboes
Date: 2012-04-21 08:26:52 EDT (Sat, 21 Apr 2012)
New Revision: 78112
URL: http://svn.boost.org/trac/boost/changeset/78112
Log:
FixedPoint: Added more comments + refactor conversion from arithmetic types
Text files modified: 
   sandbox/fixed_point/boost/fixed_point/number.hpp       |   486 +++++++++++++++++++++++++++++++-------- 
   sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp |    22                                         
   2 files changed, 398 insertions(+), 110 deletions(-)
Modified: sandbox/fixed_point/boost/fixed_point/number.hpp
==============================================================================
--- sandbox/fixed_point/boost/fixed_point/number.hpp	(original)
+++ sandbox/fixed_point/boost/fixed_point/number.hpp	2012-04-21 08:26:52 EDT (Sat, 21 Apr 2012)
@@ -26,6 +26,7 @@
 #include <boost/type_traits/is_signed.hpp>
 #include <boost/type_traits/is_arithmetic.hpp>
 #include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/assert.hpp>
 #include <boost/static_assert.hpp>
@@ -34,13 +35,16 @@
 #include <boost/integer/static_log2.hpp>
 #include <boost/ratio/detail/mpl/abs.hpp>
 #include <limits>
+#include <stdexcept>
 #include <cmath>
 #include <boost/integer_traits.hpp>
 
 #include <boost/config.hpp>
 //#include <boost/fixed_point/config.hpp>
+//#include <boost/fixed_point/number_fwd.hpp>
 //#include <boost/fixed_point/round/nearest_odd.hpp>
 //#include <boost/fixed_point/overflow/exception.hpp>
+//#include <boost/fixed_point/detail/helpers.hpp>
 
 #include <limits>
 
@@ -48,6 +52,7 @@
 {
   namespace fixed_point
   {
+    //#include <boost/fixed_point/detail/helpers.hpp>
     namespace detail
     {
 
@@ -129,26 +134,71 @@
 
     }
 
+    //#include <boost/fixed_point/overflow/exceptions.hpp>
     /**
      * Exception throw when there is a positive overflow.
      */
-    struct positive_overflow
+    class positive_overflow: public std::overflow_error
     {
+    public:
+      positive_overflow() :
+        std::overflow_error("FixedPoint: positive overflow")
+      {
+      }
+      explicit positive_overflow(const std::string& what_arg) :
+        std::overflow_error(what_arg)
+      {
+      }
+      explicit positive_overflow(const char* what_arg) :
+        std::overflow_error(what_arg)
+      {
+      }
     };
+
     /**
      * Exception throw when there is a negative overflow.
      */
-    struct negative_overflow
+    class negative_overflow: public std::underflow_error
     {
+    public:
+      negative_overflow() :
+        std::underflow_error("FixedPoint: negative overflow")
+      {
+      }
+      explicit negative_overflow(const std::string& what_arg) :
+        std::underflow_error(what_arg)
+      {
+      }
+      explicit negative_overflow(const char* what_arg) :
+        std::underflow_error(what_arg)
+      {
+      }
     };
 
-    /**
-     * Namespace for rounding policies.
-     */
     namespace round
     {
+#if defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
+      /**
+       * When the computation is not exact, rounding will be to one of the two nearest representable values.
+       * The algorithm for choosing between these values is the rounding mode.
+       * Different applications desire different modes, so programmers may specify its own rounding mode.
+       * However the library provides the usual rounding policies.
+       * All of them follwos the following this stereotype
+       *
+       */
+
+      struct stereotype
+      {
+        BOOST_STATIC_CONSTEXPR
+        std::float_round_style round_style;
+        template <typename From, typename To>
+        static typename To::underlying_type round(From const& rhs);
+        template <typename To, typename From>
+        static typename To::underlying_type round_divide(From const& lhs, From const& rhs);
+      };
+#endif
       /**
-       * Use the fastest rounding.
+       *  Speed is more important than the choice in value.
        */
       struct fastest
       {
@@ -158,11 +208,31 @@
 
       /**
        * Rounds toward negative infinity.
+       *
+       * This mode is useful in interval arithmetic.
        */
       struct negative
       {
         BOOST_STATIC_CONSTEXPR
         std::float_round_style round_style = std::round_toward_neg_infinity;
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_integral(From const& rhs)
+        {
+          BOOST_STATIC_CONSTEXPR boost::uintmax_t d = To::resolution_exp;
+          typedef typename detail::max_type<is_signed<typename To::underlying_type>::value>::type tmp_type;
+          BOOST_STATIC_ASSERT(d < (8 * sizeof(tmp_type)));
+
+          tmp_type res = tmp_type(rhs) >> d;
+          return res;
+        }
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_float_point(From const& rhs)
+        {
+          return To::integer_part(rhs / To::template factor<From>());
+        }
+
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -207,11 +277,34 @@
       };
       /**
        * Rounds toward zero.
+       *
+       * This mode is useful in implementing integral arithmetic.
        */
       struct truncated
       {
         BOOST_STATIC_CONSTEXPR
         std::float_round_style round_style = std::round_toward_zero;
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_integral(From const& rhs)
+        {
+          BOOST_STATIC_CONSTEXPR boost::uintmax_t d = To::resolution_exp;
+          typedef typename detail::max_type<is_signed<typename To::underlying_type>::value>::type tmp_type;
+          BOOST_STATIC_ASSERT(d < (8 * sizeof(tmp_type)));
+
+          tmp_type m( ( (rhs > 0) ? rhs : -rhs));
+          tmp_type s( ( (rhs > 0) ? +1 : -1));
+
+          tmp_type res = s * (m >> d);
+          return res;
+        }
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_float_point(From const& rhs)
+        {
+          return To::integer_part(rhs / To::template factor<From>());
+        }
+
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -239,11 +332,36 @@
       };
       /**
        * Rounds toward positive infinity.
+       *
+       * This mode is useful in interval arithmetic.
        */
       struct positive
       {
         BOOST_STATIC_CONSTEXPR
         std::float_round_style round_style = std::round_toward_infinity;
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_integral(From const& rhs)
+        {
+          BOOST_STATIC_CONSTEXPR boost::uintmax_t d = To::resolution_exp;
+          typedef typename detail::max_type<is_signed<typename To::underlying_type>::value>::type tmp_type;
+          BOOST_STATIC_ASSERT(d < (8 * sizeof(tmp_type)));
+
+          BOOST_STATIC_CONSTEXPR tmp_type w = (1<<d)-1;
+          tmp_type i = rhs;
+
+          BOOST_ASSERT(i <= (integer_traits<tmp_type>::const_max - w));
+
+          tmp_type res = (i + w) >> d;
+          return res;
+        }
+
+        template <typename From, typename To>
+        static typename To::underlying_type round_float_point(From const& rhs)
+        {
+          return To::integer_part(rhs / To::template factor<From>());
+        }
+
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -291,7 +409,9 @@
         }
       };
       /**
-       * Rounds to nearest half up.
+       * Round towards the nearest value, but exactly-half values are rounded towards maximum magnitude.
+       *
+       * This mode is the standard school algorithm.
        */
       struct nearest_half_up
       {
@@ -307,7 +427,8 @@
         std::float_round_style round_style = std::round_to_nearest;
       };
       /**
-       * Rounds to nearest even.
+       * Round towards the nearest value, but exactly-half values are rounded towards even values.
+       * This mode has more balance than the classic mode.
        */
       struct nearest_even
       {
@@ -315,7 +436,8 @@
         std::float_round_style round_style = std::round_to_nearest;
       };
       /**
-       * Rounds to nearest odd.
+       * Round towards the nearest value, but exactly-half values are rounded towards odd values.
+       * This mode has as much balance as the near_even mode, but preserves more information.
        */
       struct nearest_odd
       {
@@ -324,13 +446,39 @@
       };
     }
 
-    /**
-     * Namespace for overflow policies.
-     */
     namespace overflow
     {
+
+#if defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
       /**
-       * Overflow is impossible and ensured by the user.
+       * Since the range of intermediate values grow to hold all possible values, and variables have a static range and
+       * resolution, construction and assignment may need to reduce the range and resolution.
+       * Reducing the resolution is done with a rounding mode associated with the variable.
+       * When the dynamic value exceeds the range of variable, the assignment overflows.
+       *
+       * When an overflow does occur, the desirable behavior depends on the application, so programmers may specify the
+       * overflow mode with his own specific overflow policy. The library provides however the usual ones.
+       * All of them follows the following stereotype
+       */
+      struct stereotype
+      {
+        BOOST_STATIC_CONSTEXPR
+        bool is_modulo;
+
+        template <typename T, typename U>
+        static BOOST_CONSTEXPR
+        typename T::underlying_type
+        on_negative_overflow(U value);
+
+        template <typename T, typename U>
+        static BOOST_CONSTEXPR
+        typename T::underlying_type
+        on_positive_overflow(U value);
+      };
+#endif
+      /**
+       * Programmer analysis of the program has determined that overflow cannot occur.
+       * Uses of this mode should be accompanied by an argument supporting the conclusion.
        *
        * An assertion is raised on debug mode.
        */
@@ -358,9 +506,7 @@
         }
       };
       /**
-       * Overflow is undefined.
-       *
-       * Usually uses the fastest overflow approach.
+       * Programmers are willing to accept undefined behavior in the event of an overflow.
        */
       struct undefined
       {
@@ -379,6 +525,7 @@
           return value;
         }
       };
+#if ! defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
       namespace detail
       {
         template <typename T, typename U, bool TisSigned = T::is_signed>
@@ -422,8 +569,11 @@
           }
         };
       }
+#endif
+
       /**
-       * Overflow results are wrapped.
+       * The assigned value is the dynamic value @c mod the range of the variable.
+       * This mode makes sense only with unsigned numbers. It is useful for angular measures.
        */
       struct modulus
       {
@@ -443,7 +593,7 @@
         }
       };
       /**
-       * On overflow the results is the nearest.
+       * If the dynamic value exceeds the range of the variable, assign the nearest representable value.
        */
       struct saturate
       {
@@ -464,7 +614,7 @@
 
       };
       /**
-       * On overflow an exception is thrown.
+       * If the dynamic value exceeds the range of the variable, throw an exception of derived from std::overflow_error.
        */
       struct exception
       {
@@ -491,6 +641,27 @@
     {
 
       /**
+       * Every storage policy must define two meta-functions <c>signed_integer_type<Range, Resolution>::type</c> and
+       * <c>unsigned_integer_type<Range, Resolution>::type</c>.
+       */
+      struct stereotype
+      {
+        /**
+         * Gets the signed integer type with enough bits to manage with
+         * the Range and Resolution.
+         */
+        template <int Range, int Resolution>
+        struct signed_integer_type;
+
+        /**
+         * Gets the unsigned integer type with enough bits to manage with
+         * the Range and Resolution
+         */
+        template <int Range, int Resolution>
+        struct unsigned_integer_type;
+      };
+
+      /**
        * The storage is undefined.
        */
       struct undefined
@@ -551,13 +722,33 @@
     }
 
     /**
-     * Namespace for conversion policies.
+     * Since fixed points have different range and resolution the user needs to convert from one type to another.
+     *
+     * When the target type has a larger range and a more precise resolution than the source type, the conversion is implicit.
+     * Otherwise, as the conversion could loss information, the conversion should be explicit to be safe.
+     * Anyway some domains could consider that working with fixed-points should mimic the builtin and expect this conversion to be implicit.
+     * If for this reason that the library manage with both cases via the conversion policy.
+     *
+     * The conversion from builtins arithmetic types suffer from the same loss of information issue but
+     * some users could find an implicit conversion more natural.
+     *
+     * Conversions to builtins arithmetic types is a different concern.
+     * There is no know way to enable conversions operator subject to conditions on the type.
+     * The library has taken a conservative approach and only explicit conversions are provided.
+     * The user could always wrap the type and provide implicit conversion.
+     *
      */
     namespace conversion
     {
+      /**
+       * Used to state that a conversion needs to be explicit.
+       */
       struct explicitly
       {
       };
+      /**
+       * Used to state that a conversion needs to be implicit.
+       */
       struct implicitly
       {
       };
@@ -568,9 +759,37 @@
      */
     namespace arithmetic
     {
+      /*
+       * The range and resolution of the result of basic operations are deduced to try to hold the mathematical results.
+       * This deduction depends on the bound policy.
+       *
+       * - unbounded: The range and resolution of the result of basic operations are large enough to hold the mathematical results.
+       *
+       * Overflow in template argument computation is undefined behavior.
+       * In practice, overflow is unlikely to be a significant problem because even small machines can represent
+       * numbers with thousands of bits and because compiler can diagnose overflow in template arguments.
+       *
+       * The special case in the operations is division, where the mathematical result may require an infinite
+       * number of bits. The actual value must be rounded to a representable value.
+       * The above resolution is sufficient to ensure that if the mathematical result is not zero, the fixed-point
+       * result is not zero.
+       * Furthermore, assuming values have an error of one-half ULP, the defined resolution is close to the error
+       * bound in the computation.
+       *
+       * - bounded: As far as the result type is large enough to hold mathematical results it behaves as the unbounded one.
+       * When the bounding type is not enough large the operation is undefined.
+       * The user need to use functions that have the expected result type as parameter.
+       *
+       * Overflow while computing the arithmetic operations can be detected in this bounded cases.
+       *
+       */
       struct open
       {
       };
+      /*
+       * The range and resolution of the result is the one of the argument operations.
+       * In order to mix different fixed points, the user could be forced to convert explicitly the arguments to the expected type.
+       */
       struct closed
       {
       };
@@ -581,9 +800,19 @@
      */
     namespace bound
     {
+      /**
+       * Bounded fixed points types are closed, that is that the result of an arithmetic operations will be
+       * closed only if both arguments are closed.
+       * The range and resolution are bounded by the larger integral type provided by the compiler.
+       *
+       */
       struct bounded
       {
       };
+
+      /**
+       * The range and resolution of the result of basic operations are large enough to hold the mathematical results.
+       */
       struct unbounded
       {
       };
@@ -748,6 +977,7 @@
     template <class From, class To>
     To number_cast(From const& from);
 
+    //#include <boost/fixed_point/detail/helpers.hpp>
     namespace detail
     {
       template <typename T, int Range, int Resolution >
@@ -1678,47 +1908,48 @@
       typename default_type<F1,F2>::type
       > type;
     };
-#endif
-
-    template <typename T, typename U>
-    struct is_more_precisse;
+#endif // BOOST_FIXED_POINT_DOXYGEN_INVOKED
+    namespace detail
+    {
+      template <typename T, typename U>
+      struct is_more_precisse;
 
-#if ! defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
-    template <
-    int R1, int P1, typename RP1, typename OP1, typename F1,
-    int R2, int P2, typename RP2, typename OP2, typename F2
-    >
-    struct is_more_precisse<real_t<R1,P1,RP1,OP1,F1>, real_t<R2,P2,RP2,OP2,F2> > :
-    mpl::and_ <
-    mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
-    mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
-    >
-    {};
+      template <
+      int R1, int P1, typename RP1, typename OP1, typename F1,
+      int R2, int P2, typename RP2, typename OP2, typename F2
+      >
+      struct is_more_precisse<real_t<R1,P1,RP1,OP1,F1>, real_t<R2,P2,RP2,OP2,F2> > :
+      mpl::and_ <
+      mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
+      mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
+      >
+      {};
 
-    template <
-    int R1, int P1, typename RP1, typename OP1, typename F1,
-    int R2, int P2, typename RP2, typename OP2, typename F2
-    >
-    struct is_more_precisse<real_t<R1,P1,RP1,OP1,F1>, ureal_t<R2,P2,RP2,OP2,F2> > :
-    mpl::and_ <
-    mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
-    mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
-    >
-    {};
+      template <
+      int R1, int P1, typename RP1, typename OP1, typename F1,
+      int R2, int P2, typename RP2, typename OP2, typename F2
+      >
+      struct is_more_precisse<real_t<R1,P1,RP1,OP1,F1>, ureal_t<R2,P2,RP2,OP2,F2> > :
+      mpl::and_ <
+      mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
+      mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
+      >
+      {};
 
-    template <
-    int R1, int P1, typename RP1, typename OP1, typename F1,
-    int R2, int P2, typename RP2, typename OP2, typename F2
-    >
-    struct is_more_precisse<ureal_t<R1,P1,RP1,OP1,F1>, ureal_t<R2,P2,RP2,OP2,F2> > :
-    mpl::and_ <
-    mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
-    mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
-    >
-    {};
+      template <
+      int R1, int P1, typename RP1, typename OP1, typename F1,
+      int R2, int P2, typename RP2, typename OP2, typename F2
+      >
+      struct is_more_precisse<ureal_t<R1,P1,RP1,OP1,F1>, ureal_t<R2,P2,RP2,OP2,F2> > :
+      mpl::and_ <
+      mpl::less_equal < mpl::int_<R2>, mpl::int_<R1> >,
+      mpl::greater_equal < mpl::int_<P2>, mpl::int_<P1> >
+      >
+      {};
+    }
 
     template <typename S, typename T>
-    struct is_convertible : is_more_precisse<T,S>
+    struct is_convertible : detail::is_more_precisse<T,S>
     {};
 
     template <typename S, typename T, bool IsArithmetic=is_arithmetic<S>::value >
@@ -1727,7 +1958,7 @@
     struct is_explicitly_convertible<S,T,false> :
     mpl::and_<
     mpl::not_<allows_implicit_conversion_from_fp<T> >,
-    mpl::not_<is_more_precisse<T,S> >
+    mpl::not_<detail::is_more_precisse<T,S> >
     >
     {};
 
@@ -1742,7 +1973,7 @@
     struct is_implicitly_convertible<S,T,false> :
     mpl::and_<
     allows_implicit_conversion_from_fp<T>,
-    mpl::not_<is_more_precisse<T,S> >
+    mpl::not_<detail::is_more_precisse<T,S> >
     >
     {};
 
@@ -1750,7 +1981,6 @@
     struct is_implicitly_convertible<S,T,true> :
     allows_implicit_conversion_from_builtin<T>
     {};
-#endif
 
     /**
      * @brief Signed fixed point number.
@@ -1771,8 +2001,10 @@
       BOOST_MPL_ASSERT_MSG(Range>=Resolution,
           RANGE_MUST_BE_GREATER_EQUAL_THAN_RESOLUTION, (mpl::int_<Range>,mpl::int_<Resolution>));
 #endif
-    public:
 
+    public:
+      //! this type
+      typedef real_t self_type;
       // name the template parameters
       //! the Range parameter.
       BOOST_STATIC_CONSTEXPR int range_exp = Range;
@@ -1839,7 +2071,7 @@
        *
        * @Effects Adapt the resolution of @c rhs to this resolution.
        * @Throws Nothing.
-       * @Notes This overload participates in overload resolution only if the source @c is_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       real_t(real_t<R,P,RP,OP,F> const& rhs
@@ -1847,7 +2079,7 @@
           , typename boost::enable_if<is_convertible<real_t<R,P,RP,OP,F>, real_t > >::type* = 0
 #endif
       )
-      : value_(fixed_point::detail::fxp_number_cast<real_t<R,P,RP,OP,F>, real_t, true, true>()(rhs).count())
+      : value_(fixed_point::detail::fxp_number_cast<real_t<R,P,RP,OP,F>, real_t>()(rhs).count())
       {
       }
       /**
@@ -1858,7 +2090,7 @@
        *
        * @Effects Adapt the resolution of @c rhs to this resolution.
        * @Throws Nothing.
-       * @Notes This overload participates in overload resolution only if the source @c is_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       real_t(ureal_t<R,P,RP,OP,F> const& rhs
@@ -1866,7 +2098,7 @@
           , typename boost::enable_if<is_convertible<ureal_t<R,P,RP,OP,F>, real_t > >::type* = 0
 #endif
       )
-      : value_(fixed_point::detail::fxp_number_cast<ureal_t<R,P,RP,OP,F>, real_t, true, true>()(rhs).count())
+      : value_(fixed_point::detail::fxp_number_cast<ureal_t<R,P,RP,OP,F>, real_t>()(rhs).count())
       {
       }
 
@@ -1878,7 +2110,7 @@
        *
        * @Effects Rounds and check overflow if needed.
        * @Throws Whatever the target overflow policy can throw.
-       * @Notes This overload participates in overload resolution only if the source @c is_explicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_explicitly_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       explicit real_t(real_t<R,P,RP,OP,F> const& rhs
@@ -1901,7 +2133,7 @@
        *
        * @Effects Rounds and check overflow if needed.
        * @Throws Whatever the target overflow policy can throw.
-       * @Notes This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       real_t(real_t<R,P,RP,OP,F> const& rhs
@@ -1924,7 +2156,7 @@
        *
        * @Throws Whatever the target overflow policy can throw.
        * @Effects Rounds and check overflow if needed.
-       * @Notes This overload participates in overload resolution only if the source @c is_explicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_explicitly_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       explicit real_t(ureal_t<R,P,RP,OP,F> const& rhs
@@ -1947,7 +2179,7 @@
        *
        * @Effects Rounds and check overflow if needed.
        * @Throws Whatever the target overflow policy can throw.
-       * @Notes This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       real_t(ureal_t<R,P,RP,OP,F> const& rhs
@@ -1970,7 +2202,7 @@
        *
        * @Effects Rounds and check overflow if needed.
        * @Throws Whatever the target overflow policy can throw.
-       * @Notes This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
        */
 
       template <int R, int P, typename RP, typename OP, typename F>
@@ -1989,7 +2221,7 @@
        *
        * @Effects Rounds and check overflow if needed.
        * @Throws Whatever the target overflow policy can throw.
-       * @Notes This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
+       * @Remark This overload participates in overload resolution only if the source @c is_implicitly_convertible to the target.
        */
       template <int R, int P, typename RP, typename OP, typename F>
       real_t(convert_tag<ureal_t<R,P,RP,OP,F> > rhs)
@@ -2140,33 +2372,53 @@
       {
         return underlying_type(std::floor(x));
       }
+      template <typename I>
+      static underlying_type classify(I i
+#if !defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
+          , typename boost::enable_if<is_integral<I> >::type* = 0
+#endif
+      )
+      {
+        // Round
+        underlying_type indx = rounding_type::template round_integral<I, self_type>(i);
+        // Overflow
+        if (indx > max_index)
+        {
+          return overflow_type::template on_positive_overflow<self_type,underlying_type>(indx);
+        }
+        if (indx < min_index)
+        {
+          return overflow_type::template on_negative_overflow<self_type,underlying_type>(indx);
+        }
+
+        return indx;
+      }
+
       template <typename FP>
-      static underlying_type classify(FP x)
+      static underlying_type classify(FP x
+#if !defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
+          , typename boost::enable_if<is_floating_point<FP> >::type* = 0
+#endif
+      )
       {
 
-        //        underlying_type indx = rounding_type::template round<To>(x)
-        //        // Overflow
-        //        if (x>max().as<FP>())
-        //        {
-        //          return overflow_type::template on_positive_overflow<To,underlying_type>(indx)));
-        //        }
-        //        if (rhs.count() < (typename From::underlying_type(To::min_index)<<(P2-P1)))
-        //        {
-        //          return To(index(OP2::template on_negative_overflow<To,underlying_type>(indx)));
-        //        }
-        //
-        //        // Round
-        //        return To(index(RP2::template round<From,To>(rhs)));
-
-        if (x<min().as<FP>())
-        return min_index;
-        if (x>max().as<FP>())
-        return max_index;
-        return integer_part(x/factor<FP>());
+        // Round
+        underlying_type indx = rounding_type::template round_float_point<FP,self_type>(x);
+        // Overflow
+        if (indx > max_index)
+        {
+          return overflow_type::template on_positive_overflow<self_type,underlying_type>(indx);
+        }
+        if (indx < min_index)
+        {
+          return overflow_type::template on_negative_overflow<self_type,underlying_type>(indx);
+        }
+
+        return indx;
       }
 
       /**
-       * Implicit conversion from arithmetic @T.
+       * Implicit conversion from arithmetic @c T.
        */
       template <typename T>
       real_t(T x
@@ -2175,7 +2427,7 @@
 #endif
       ) : value_(fixed_point::detail::arthm_number_cast<T, real_t>()(x).count())
       {}
-      //! explicit conversion from arithmetic @T.
+      //! explicit conversion from arithmetic @c T.
       template <typename T>
       explicit real_t(T x
 #if !defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
@@ -2380,6 +2632,8 @@
 #endif
 
     public:
+      //! this type
+      typedef ureal_t self_type;
 
       // name the template parameters
       //! the Range parameter.
@@ -2443,7 +2697,7 @@
       ureal_t(ureal_t<R,P,RP,OP,F> const& rhs
           , typename boost::enable_if<is_convertible<ureal_t<R,P,RP,OP,F>, ureal_t > >::type* = 0
       )
-      : value_(fixed_point::detail::fxp_number_cast<ureal_t<R,P,RP,OP,F>, ureal_t, true, true>()(rhs).count())
+      : value_(fixed_point::detail::fxp_number_cast<ureal_t<R,P,RP,OP,F>, ureal_t>()(rhs).count())
       {
       }
 
@@ -2561,12 +2815,46 @@
 
         return k*factor<FP>();
       }
+
+      template <typename I>
+      static underlying_type classify(I i
+#if !defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
+          , typename boost::enable_if<is_integral<I> >::type* = 0
+#endif
+      )
+      {
+        if (i<0)
+          return overflow_type::template on_negative_overflow<self_type,underlying_type>(0);
+        // Round
+        underlying_type indx = rounding_type::template round_integral<I, self_type>(i);
+        // Overflow
+        if (indx > max_index)
+        {
+          return overflow_type::template on_positive_overflow<self_type,underlying_type>(indx);
+        }
+
+        return indx;
+      }
+
       template <typename FP>
-      static underlying_type classify(FP x)
+      static underlying_type classify(FP x
+#if !defined(BOOST_FIXED_POINT_DOXYGEN_INVOKED)
+          , typename boost::enable_if<is_floating_point<FP> >::type* = 0
+#endif
+      )
       {
-        if (x<min().as<FP>()) return min_index;
-        if (x>max().as<FP>()) return max_index;
-        return integer_part(x/factor<FP>());
+        if (x<0)
+          return overflow_type::template on_negative_overflow<self_type,underlying_type>(0);
+
+        // Round
+        underlying_type indx = rounding_type::template round_float_point<FP,self_type>(x);
+        // Overflow
+        if (indx > max_index)
+        {
+          return overflow_type::template on_positive_overflow<self_type,underlying_type>(indx);
+        }
+
+        return indx;
       }
 
       //! implicit conversion from int
@@ -2827,7 +3115,7 @@
 #else
     ureal_t< static_log2<mpl::abs<mpl::int_<Times+1> >::type::value>::value+Resolution, Resolution>
 #endif
-    to_unsigned_number()
+    to_ureal_t()
     {
       return ureal_t<
       static_log2<mpl::abs<mpl::int_<Times+1> >::type::value>::value+Resolution, Resolution
@@ -2850,7 +3138,7 @@
 #else
     real_t< static_log2<mpl::abs<mpl::int_<Times+1> >::type::value>::value+Resolution, Resolution>
 #endif
-    to_signed_number()
+    to_real_t()
     {
       return real_t<
       static_log2<mpl::abs<mpl::int_<Times+1> >::type::value>::value+Resolution, Resolution
Modified: sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp
==============================================================================
--- sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp	(original)
+++ sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp	2012-04-21 08:26:52 EDT (Sat, 21 Apr 2012)
@@ -16,17 +16,17 @@
 
 pixel blend(pixel a, pixel b)
 {
-  BOOST_AUTO(scale, (to_unsigned_number<255, 0> ()));
+  BOOST_AUTO(scale, (to_ureal_t<255, 0> ()));
   BOOST_AUTO(a_r, a.r / scale);
   BOOST_AUTO(b_r, b.r / scale);
   (void) a_r;
   (void) b_r;
-  BOOST_AUTO(aia, b.a * (to_unsigned_number<1, 0> () - a.a));
+  BOOST_AUTO(aia, b.a * (to_ureal_t<1, 0> () - a.a));
   BOOST_AUTO(c_a, a.a + aia);
   BOOST_AUTO(c_r, (a.r * a.a + b.r * aia) / c_a);
   pixel c;
-  c.a = number_cast<ureal_t<8, 0> > (c_a * to_unsigned_number<255, 0> ());
-  c.r = number_cast<ureal_t<8, 0> > (c_r * to_unsigned_number<255, 0> ());
+  c.a = number_cast<ureal_t<8, 0> > (c_a * to_ureal_t<255, 0> ());
+  c.r = number_cast<ureal_t<8, 0> > (c_r * to_ureal_t<255, 0> ());
   return c;
 }
 
@@ -55,7 +55,7 @@
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    ureal_t<2, -2, round::negative> n = to_unsigned_number<1, 0> (); //
+    ureal_t<2, -2, round::negative> n = to_ureal_t<1, 0> (); //
     std::cout << int(n.count()) << std::endl;
     BOOST_TEST(n.count() == 4);
   }
@@ -405,7 +405,7 @@
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    ureal_t<4, -1> n1(-0.5f);
+    ureal_t<4, -1, round::negative, ::overflow::saturate> n1(-0.5f);
     BOOST_TEST(n1.count() == 0);
     BOOST_TEST(n1.as_float() == 0.0f);
   }
@@ -1045,27 +1045,27 @@
   //  }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    BOOST_AUTO(scale, (to_unsigned_number<255, 0> ()));
+    BOOST_AUTO(scale, (to_ureal_t<255, 0> ()));
     BOOST_TEST(scale.count() == 255);
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    BOOST_AUTO(scale, (to_signed_number<255, 0> ()));
+    BOOST_AUTO(scale, (to_real_t<255, 0> ()));
     BOOST_TEST(scale.count() == 255);
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    BOOST_AUTO(scale, (to_unsigned_number<1, -12> ()));
+    BOOST_AUTO(scale, (to_ureal_t<1, -12> ()));
     BOOST_TEST(scale.count() == 1);
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    BOOST_AUTO(scale, (to_signed_number<1, -12> ()));
+    BOOST_AUTO(scale, (to_real_t<1, -12> ()));
     BOOST_TEST(scale.count() == 1);
   }
   {
     std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
-    BOOST_AUTO(scale, (to_unsigned_number<3, 10> ()));
+    BOOST_AUTO(scale, (to_ureal_t<3, 10> ()));
     BOOST_TEST(scale.count() == 3);
   }
   {