// Boost.Units - A C++ library for zero-overhead dimensional analysis and // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel // Copyright (C) 2007-2008 Steven Watanabe // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP #define BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP #include #include #include namespace boost { namespace units { template class static_rational; namespace detail { namespace typeof_pow_adl_barrier { using std::pow; template struct typeof_pow { #if defined(BOOST_UNITS_HAS_BOOST_TYPEOF) BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, pow(typeof_::make(), 0.0)) typedef typename nested::type type; #elif defined(BOOST_UNITS_HAS_MWERKS_TYPEOF) typedef __typeof__(pow(typeof_::make(), 0.0)) type; #elif defined(BOOST_UNITS_HAS_GNU_TYPEOF) typedef typeof(pow(typeof_::make(), 0.0)) type; #else typedef Y type; #endif }; } template struct static_rational_power_impl { typedef typename typeof_pow_adl_barrier::typeof_pow::type type; static type call(const Y& y) { using std::pow; return(pow(y, static_cast(R::Numerator) / static_cast(R::Denominator))); } }; template struct static_rational_power_impl { typedef one type; static one call(const one&) { one result; return(result); } }; template struct static_rational_power_impl, one> { typedef one type; static one call(const one&) { one result; return(result); } }; template struct static_int_power_impl; template struct static_int_power_impl { template struct apply { typedef typename multiply_typeof_helper::type square_type; typedef typename static_int_power_impl<(N >> 1)>::template apply 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 struct static_int_power_impl { template struct apply { typedef typename multiply_typeof_helper::type square_type; typedef typename multiply_typeof_helper::type new_r; typedef typename static_int_power_impl<(N >> 1)>::template apply 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 struct apply { typedef typename multiply_typeof_helper::type type; static type call(const Y& y, const R& r) { return(y * r); } }; }; template<> struct static_int_power_impl<0, true> { template struct apply { typedef R type; static R call(const Y&, const R& r) { return(r); } }; }; template struct static_int_power_sign_impl; template struct static_int_power_sign_impl { template struct apply { typedef typename static_int_power_impl::template apply impl; typedef typename impl::type type; static type call(const Y& y) { one result; return(impl::call(y, result)); } }; }; template struct static_int_power_sign_impl { template struct apply { typedef typename static_int_power_impl<-N>::template apply impl; typedef typename divide_typeof_helper::type type; static type call(const Y& y) { one result; return(result/impl::call(y, result)); } }; }; template struct static_rational_power_impl, Y> { typedef typename static_int_power_sign_impl::template apply impl; typedef typename impl::type type; static Y call(const Y& y) { return(impl::call(y)); } }; template typename detail::static_rational_power_impl::type static_rational_power(const Y& y) { return(detail::static_rational_power_impl::call(y)); } } // namespace detail } // namespace units } // namespace boost #endif