Boost logo

Boost-Commit :

From: steven_at_[hidden]
Date: 2008-02-02 16:43:37


Author: steven_watanabe
Date: 2008-02-02 16:43:37 EST (Sat, 02 Feb 2008)
New Revision: 43060
URL: http://svn.boost.org/trac/boost/changeset/43060

Log:
Updated pow/root to use optimized static_rational_power
Text files modified:
   sandbox/units/boost/units/detail/static_rational_power.hpp | 132 +++++++++++++++++++++-------
   sandbox/units/boost/units/static_rational.hpp | 177 +++++++--------------------------------
   2 files changed, 128 insertions(+), 181 deletions(-)

Modified: sandbox/units/boost/units/detail/static_rational_power.hpp
==============================================================================
--- sandbox/units/boost/units/detail/static_rational_power.hpp (original)
+++ sandbox/units/boost/units/detail/static_rational_power.hpp 2008-02-02 16:43:37 EST (Sat, 02 Feb 2008)
@@ -13,84 +13,134 @@
 
 #include <cmath>
 
-#include <boost/units/static_rational.hpp>
 #include <boost/units/detail/one.hpp>
+#include <boost/units/operators.hpp>
 
 namespace boost {
 
 namespace units {
 
+template<long N,long D>
+class static_rational;
+
 namespace detail {
 
+namespace typeof_pow_adl_barrier {
+
+using std::pow;
+
+template<class Y>
+struct typeof_pow
+{
+#if defined(BOOST_UNITS_HAS_BOOST_TYPEOF)
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, pow(typeof_::make<Y>(), 0.0))
+ typedef typename nested::type type;
+#elif defined(BOOST_UNITS_HAS_MWERKS_TYPEOF)
+ typedef __typeof__(pow(typeof_::make<Y>(), 0.0)) type;
+#elif defined(BOOST_UNITS_HAS_GNU_TYPEOF)
+ typedef typeof(pow(typeof_::make<Y>(), 0.0)) type;
+#else
+ typedef Y type;
+#endif
+};
+
+}
+
 template<class R, class Y>
 struct static_rational_power_impl
 {
- static Y apply(const Y& y)
+ typedef typename typeof_pow_adl_barrier::typeof_pow<Y>::type type;
+ static type call(const Y& y)
     {
- return(std::pow(y, value<Y>(R())));
+ using std::pow;
+ return(pow(y, static_cast<double>(R::Numerator) / static_cast<double>(R::Denominator)));
     }
 };
 
 template<class R>
 struct static_rational_power_impl<R, one>
 {
- static one apply(const one&)
+ typedef one type;
+ static one call(const one&)
     {
         return(one());
     }
 };
 
 template<long N>
-struct static_rational_power_impl<static_rational<N>, one>
+struct static_rational_power_impl<static_rational<N, 1>, one>
 {
- static one apply(const one&)
+ typedef one type;
+ static one call(const one&)
     {
         return(one());
     }
 };
 
-template<integer_type N, bool = (N % 2 == 0)>
+template<long N, bool = (N % 2 == 0)>
 struct static_int_power_impl;
 
-template<integer_type N>
+template<long N>
 struct static_int_power_impl<N, true>
 {
     template<class Y, class R>
- static Y apply(const Y& y, const R& r) {
- const Y square = y * y;
- return(static_int_power_impl<(N >> 1)>::apply(square, r));
- }
+ struct apply
+ {
+ typedef typename multiply_typeof_helper<Y, Y>::type square_type;
+ typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, R> next;
+ typedef typename next::type type;
+ static type call(const Y& y, const R& r)
+ {
+ const Y square = y * y;
+ return(next::call(square, r));
+ }
+ };
 };
 
-template<integer_type N>
+template<long N>
 struct static_int_power_impl<N, false>
 {
     template<class Y, class R>
- static Y apply(const Y& y, const R& r)
+ struct apply
     {
- const Y square = y * y;
- return(static_int_power_impl<(N >> 1)>::apply(square, y * r));
- }
+ typedef typename multiply_typeof_helper<Y, Y>::type square_type;
+ typedef typename multiply_typeof_helper<Y, R>::type new_r;
+ typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, new_r> next;
+ typedef typename next::type type;
+ static type call(const Y& y, const R& r)
+ {
+ const Y square = y * y;
+ return(next::call(square, y * r));
+ }
+ };
 };
 
 template<>
 struct static_int_power_impl<1, false>
 {
     template<class Y, class R>
- static Y apply(const Y& y, const R& r)
+ struct apply
     {
- return(y * r);
- }
+ typedef typename multiply_typeof_helper<Y, R>::type type;
+ static type call(const Y& y, const R& r)
+ {
+ return(y * r);
+ }
+ };
 };
 
 template<>
 struct static_int_power_impl<0, true>
 {
     template<class Y, class R>
- static Y apply(const Y&, const R& r)
+ struct apply
     {
- return(r);
- }
+ typedef R type;
+ static R call(const Y&, const R& r)
+ {
+ return(r);
+ }
+ };
 };
 
 template<int N, bool = (N < 0)>
@@ -100,35 +150,47 @@
 struct static_int_power_sign_impl<N, false>
 {
     template<class Y>
- static Y apply(const Y& y)
+ struct apply
     {
- return(static_int_power_impl<N>::apply(y, one()));
- }
+ typedef typename static_int_power_impl<N>::template apply<Y, one> impl;
+ typedef typename impl::type type;
+ static type call(const Y& y)
+ {
+ return(impl::call(y, one()));
+ }
+ };
 };
 
 template<int N>
 struct static_int_power_sign_impl<N, true>
 {
     template<class Y>
- static Y apply(const Y& y)
+ struct apply
     {
- return(one()/static_int_power_impl<-N>::apply(y, one()));
- }
+ typedef typename static_int_power_impl<-N>::template apply<Y, one> impl;
+ typedef typename divide_typeof_helper<one, typename impl::type>::type type;
+ static type call(const Y& y)
+ {
+ return(one()/impl::call(y, one()));
+ }
+ };
 };
 
-template<integer_type N, class Y>
-struct static_rational_power_impl<static_rational<N>, Y>
+template<long N, class Y>
+struct static_rational_power_impl<static_rational<N, 1>, Y>
 {
- static Y apply(const Y& y)
+ typedef typename static_int_power_sign_impl<N>::template apply<Y> impl;
+ typedef typename impl::type type;
+ static Y call(const Y& y)
     {
- return(static_int_power_sign_impl<N>::apply(y));
+ return(impl::call(y));
     }
 };
 
 template<class R, class Y>
-Y static_rational_power(const Y& y)
+typename detail::static_rational_power_impl<R, Y>::type static_rational_power(const Y& y)
 {
- return(detail::static_rational_power_impl<R, Y>::apply(y));
+ return(detail::static_rational_power_impl<R, Y>::call(y));
 }
 
 } // namespace detail

Modified: sandbox/units/boost/units/static_rational.hpp
==============================================================================
--- sandbox/units/boost/units/static_rational.hpp (original)
+++ sandbox/units/boost/units/static_rational.hpp 2008-02-02 16:43:37 EST (Sat, 02 Feb 2008)
@@ -14,12 +14,15 @@
 #include <cmath>
 #include <complex>
 
+#include <boost/type_traits/is_integral.hpp>
 #include <boost/math/common_factor_ct.hpp>
 #include <boost/mpl/less.hpp>
 #include <boost/mpl/arithmetic.hpp>
 #include <boost/mpl/less.hpp>
+#include <boost/mpl/if.hpp>
 
 #include <boost/units/operators.hpp>
+#include <boost/units/detail/static_rational_power.hpp>
 
 /// \file
 /// \brief Compile-time rational numbers and operators.
@@ -115,157 +118,15 @@
 
 /// get decimal value of @c static_rational
 template<class T,integer_type N,integer_type D>
-typename divide_typeof_helper<T,T>::type
-value(const static_rational<N,D>& r)
+inline typename divide_typeof_helper<T,T>::type
+value(const static_rational<N,D>&)
 {
     return T(N)/T(D);
 }
 
-/// raise @c int to a @c static_rational power
-template<long N,long D>
-struct power_dimof_helper<int,static_rational<N,D> >
-{
- typedef double type;
-
- static type value(const int& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(double(x),double(rat.numerator())/double(rat.denominator()));
- }
-};
-
-/// raise @c float to a @c static_rational power
-template<long N,long D>
-struct power_dimof_helper<float,static_rational<N,D> >
-{
- typedef double type;
-
- static type value(const float& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,float(rat.numerator())/float(rat.denominator()));
- }
-};
-
-/// raise @c double to a @c static_rational power
-template<long N,long D>
-struct power_dimof_helper<double,static_rational<N,D> >
-{
- typedef double type;
-
- static type value(const double& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,double(rat.numerator())/double(rat.denominator()));
- }
-};
-
-/// raise @c std::complex<float> to a @c static_rational power
-template<long N,long D>
-struct power_dimof_helper<std::complex<float>,static_rational<N,D> >
-{
- typedef std::complex<float> type;
-
- static type value(const std::complex<float>& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,std::complex<float>(rat.numerator())/std::complex<float>(rat.denominator()));
- }
-};
-
-/// raise @c std::complex<double> to a @c static_rational power
-template<long N,long D>
-struct power_dimof_helper<std::complex<double>,static_rational<N,D> >
-{
- typedef std::complex<double> type;
-
- static type value(const std::complex<double>& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,std::complex<double>(rat.numerator())/std::complex<double>(rat.denominator()));
- }
-};
-
-/// take @c static_rational root of an @c int
-template<long N,long D>
-struct root_typeof_helper<int,static_rational<N,D> >
-{
- typedef double type;
-
- static type value(const int& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(double(x),double(rat.denominator())/double(rat.numerator()));
- }
-};
-
-/// take @c static_rational root of a @c float
-template<long N,long D>
-struct root_typeof_helper<float,static_rational<N,D> >
-{
- typedef float type;
-
- static type value(const float& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,float(rat.denominator())/float(rat.numerator()));
- }
-};
-
-/// take @c static_rational root of a @c double
-template<long N,long D>
-struct root_typeof_helper<double,static_rational<N,D> >
-{
- typedef double type;
-
- static type value(const double& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,double(rat.denominator())/double(rat.numerator()));
- }
-};
-
-/// take @c static_rational root of a @c std::complex<float>
-template<long N,long D>
-struct root_typeof_helper<std::complex<float>,static_rational<N,D> >
-{
- typedef std::complex<float> type;
-
- static type value(const std::complex<float>& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,std::complex<float>(rat.denominator())/std::complex<float>(rat.numerator()));
- }
-};
-
-/// take @c static_rational root of a @c std::complex<double>
-template<long N,long D>
-struct root_typeof_helper<std::complex<double>,static_rational<N,D> >
-{
- typedef std::complex<double> type;
-
- static type value(const std::complex<double>& x)
- {
- const static_rational<N,D> rat;
-
- return std::pow(x,std::complex<double>(rat.denominator())/std::complex<double>(rat.numerator()));
- }
-};
-
-// need powers and roots of char, short, long long, unsigned integers...
-
 /// raise a value to a @c static_rational power
 template<class Rat,class Y>
-typename power_dimof_helper<Y,Rat>::type
+inline typename power_dimof_helper<Y,Rat>::type
 pow(const Y& x)
 {
     return power_dimof_helper<Y,Rat>::value(x);
@@ -273,12 +134,31 @@
 
 /// raise a value to an integer power
 template<long N,class Y>
-typename power_dimof_helper<Y,static_rational<N> >::type
+inline typename power_dimof_helper<Y,static_rational<N> >::type
 pow(const Y& x)
 {
     return power_dimof_helper<Y,static_rational<N> >::value(x);
 }
 
+/// raise @c T to a @c static_rational power
+template<class T, long N,long D>
+struct power_dimof_helper<T, static_rational<N,D> >
+{
+ typedef typename mpl::if_<boost::is_integral<T>, double, T>::type internal_type;
+ typedef detail::static_rational_power_impl<static_rational<N, D>, internal_type> impl;
+ typedef typename impl::type type;
+
+ static type value(const T& x)
+ {
+ return impl::call(x);
+ }
+};
+
+/// raise @c int to a @c static_rational power
+template<long N,long D>
+struct power_dimof_helper<float, static_rational<N,D> >
+ : power_dimof_helper<double, static_rational<N,D> > {};
+
 /// take the @c static_rational root of a value
 template<class Rat,class Y>
 typename root_typeof_helper<Y,Rat>::type
@@ -295,6 +175,11 @@
     return root_typeof_helper<Y,static_rational<N> >::value(x);
 }
 
+/// take @c static_rational root of an @c T
+template<class T, long N,long D>
+struct root_typeof_helper<T,static_rational<N,D> >
+ : power_dimof_helper<T, static_rational<D,N> > {};
+
 } // namespace units
 
 namespace mpl {


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