# Boost-Commit :

From: john_at_[hidden]
Date: 2008-01-25 12:09:52

Date: 2008-01-25 12:09:52 EST (Fri, 25 Jan 2008)
New Revision: 42967
URL: http://svn.boost.org/trac/boost/changeset/42967

Log:
Improved integer conversion code and suppressed some more warnings, also added mixed mode arithmetic operators.
Text files modified:
sandbox/interval_math_toolkit/boost/numeric/interval/interval.hpp | 21 +++++++++++++++++++++
sandbox/interval_math_toolkit/boost/numeric/interval/rounded_arith.hpp | 38 +++++++++++++++++++++++++++++++-------
2 files changed, 52 insertions(+), 7 deletions(-)

Modified: sandbox/interval_math_toolkit/boost/numeric/interval/interval.hpp
==============================================================================
--- sandbox/interval_math_toolkit/boost/numeric/interval/interval.hpp (original)
+++ sandbox/interval_math_toolkit/boost/numeric/interval/interval.hpp 2008-01-25 12:09:52 EST (Fri, 25 Jan 2008)
@@ -77,6 +77,27 @@
interval& operator/= (const T& r);
interval& operator/= (const interval& r);

+ template <class U>
+ interval& operator+= (const U& r)
+ {
+ return *this += interval(r);
+ }
+ template <class U>
+ interval& operator-= (const U& r)
+ {
+ return *this -= interval(r);
+ }
+ template <class U>
+ interval& operator*= (const U& r)
+ {
+ return *this *= interval(r);
+ }
+ template <class U>
+ interval& operator/= (const U& r)
+ {
+ return *this /= interval(r);
+ }
+
bool operator< (const interval_holder& r) const;
bool operator> (const interval_holder& r) const;
bool operator<= (const interval_holder& r) const;

Modified: sandbox/interval_math_toolkit/boost/numeric/interval/rounded_arith.hpp
==============================================================================
--- sandbox/interval_math_toolkit/boost/numeric/interval/rounded_arith.hpp (original)
+++ sandbox/interval_math_toolkit/boost/numeric/interval/rounded_arith.hpp 2008-01-25 12:09:52 EST (Fri, 25 Jan 2008)
@@ -12,9 +12,11 @@

#include <boost/numeric/interval/rounding.hpp>
#include <boost/numeric/interval/detail/bugs.hpp>
-#include <boost/type_traits/make_signed.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/and.hpp>
#include <boost/mpl/identity.hpp>
#include <cmath>

@@ -57,8 +59,8 @@
# define BOOST_NR(EXPR) this->to_nearest(); return this->force_rounding(EXPR)
# define BOOST_UP(EXPR) this->upward(); return this->force_rounding(EXPR)
void init() { }
- template<class U> T conv_down(U const &v) { BOOST_DN(v); }
- template<class U> T conv_up (U const &v) { BOOST_UP(v); }
+ template<class U> T conv_down(U const &v) { BOOST_DN(static_cast<T>(v)); }
+ template<class U> T conv_up (U const &v) { BOOST_UP(static_cast<T>(v)); }
T add_down(const T& x, const T& y) { BOOST_DN(x + y); }
T sub_down(const T& x, const T& y) { BOOST_DN(x - y); }
T mul_down(const T& x, const T& y) { BOOST_DN(x * y); }
@@ -94,12 +96,34 @@
return r
# define BOOST_UP(EXPR) return this->force_rounding(EXPR)
# define BOOST_UP_NEG(EXPR) return -this->force_rounding(EXPR)
+private:
+ // Downward conversion has three cases:
+ template<class U> T conv_down(U const &v, const mpl::true_&, const mpl::true_&)
+ {
+ // U is an integer as wide as boost::intmax_t:
+ if((v > static_cast<U>(std::numeric_limits<boost::intmax_t>::max()))
+ || (v < static_cast<U>(std::numeric_limits<boost::intmax_t>::min())))
+ {
+ BOOST_DN(static_cast<T>(v));
+ }
+ BOOST_UP_NEG(static_cast<T>(-static_cast<boost::intmax_t>(v)));
+ }
+ template<class U> T conv_down(U const &v, const mpl::true_&, const mpl::false_&)
+ {
+ // U is an integer smaller than boost::intmax_t:
+ BOOST_UP_NEG(static_cast<T>(-static_cast<boost::intmax_t>(v)));
+ }
+ template<class U> T conv_down(U const &v, const mpl::false_&, const mpl::false_&)
+ {
+ // U is not an integer, so it had better be a signed type(!):
+ BOOST_UP_NEG(-v);
+ }
+public:
template<class U> T conv_down(U const &v)
{
- typedef typename mpl::eval_if<
- is_integral<U>, make_signed<U>, mpl::identity<U> >::type signed_type;
-
- BOOST_UP_NEG(static_cast<T>(-static_cast<signed_type>(v)));
+ typedef typename boost::is_integral<U>::type t1;
+ typedef typename mpl::and_<t1, boost::is_unsigned<U>, mpl::bool_<sizeof(U) == sizeof(boost::intmax_t)> >::type t2;
+ return conv_down(v, t1(), t2());
}
template<class U> T conv_up (U const &v) { BOOST_UP(static_cast<T>(v)); }
T add_down(const T& x, const T& y) { BOOST_UP_NEG((-x) - y); }