You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
206 lines
4.8 KiB
206 lines
4.8 KiB
// 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 Y 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 Y 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
|
|
|