207 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			207 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// 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 <boost/config/no_tr1/cmath.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
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef typename typeof_pow_adl_barrier::typeof_pow<Y>::type type;
							 | 
						||
| 
								 | 
							
								    static type call(const Y& y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        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>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef one type;
							 | 
						||
| 
								 | 
							
								    static one call(const one&)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        one result;
							 | 
						||
| 
								 | 
							
								        return(result);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<long N>
							 | 
						||
| 
								 | 
							
								struct static_rational_power_impl<static_rational<N, 1>, one>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef one type;
							 | 
						||
| 
								 | 
							
								    static one call(const one&)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        one result;
							 | 
						||
| 
								 | 
							
								        return(result);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<long N, bool = (N % 2 == 0)>
							 | 
						||
| 
								 | 
							
								struct static_int_power_impl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<long N>
							 | 
						||
| 
								 | 
							
								struct static_int_power_impl<N, true>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template<class Y, class 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 square_type square = y * y;
							 | 
						||
| 
								 | 
							
								            return(next::call(square, r));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<long N>
							 | 
						||
| 
								 | 
							
								struct static_int_power_impl<N, false>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template<class Y, class R>
							 | 
						||
| 
								 | 
							
								    struct apply
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        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>
							 | 
						||
| 
								 | 
							
								    struct apply
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        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>
							 | 
						||
| 
								 | 
							
								    struct apply
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef R type;
							 | 
						||
| 
								 | 
							
								        static R call(const Y&, const R& r)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return(r);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<int N, bool = (N < 0)>
							 | 
						||
| 
								 | 
							
								struct static_int_power_sign_impl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<int N>
							 | 
						||
| 
								 | 
							
								struct static_int_power_sign_impl<N, false>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template<class Y>
							 | 
						||
| 
								 | 
							
								    struct apply
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename static_int_power_impl<N>::template apply<Y, one> impl;
							 | 
						||
| 
								 | 
							
								        typedef typename impl::type type;
							 | 
						||
| 
								 | 
							
								        static type call(const Y& y)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            one result;
							 | 
						||
| 
								 | 
							
								            return(impl::call(y, result));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<int N>
							 | 
						||
| 
								 | 
							
								struct static_int_power_sign_impl<N, true>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template<class Y>
							 | 
						||
| 
								 | 
							
								    struct apply
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        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)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            one result;
							 | 
						||
| 
								 | 
							
								            return(result/impl::call(y, result));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<long N, class Y>
							 | 
						||
| 
								 | 
							
								struct static_rational_power_impl<static_rational<N, 1>, Y>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef typename static_int_power_sign_impl<N>::template apply<Y> impl;
							 | 
						||
| 
								 | 
							
								    typedef typename impl::type type;
							 | 
						||
| 
								 | 
							
								    static type call(const Y& y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return(impl::call(y));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class R, class Y>
							 | 
						||
| 
								 | 
							
								typename detail::static_rational_power_impl<R, Y>::type static_rational_power(const Y& y)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return(detail::static_rational_power_impl<R, Y>::call(y));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace detail
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace units
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace boost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |