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