File indexing completed on 2025-01-18 09:53:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP
0012 #define BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP
0013
0014 #include <boost/config/no_tr1/cmath.hpp>
0015
0016 #include <boost/units/detail/one.hpp>
0017 #include <boost/units/operators.hpp>
0018
0019 namespace boost {
0020
0021 namespace units {
0022
0023 template<long N,long D>
0024 class static_rational;
0025
0026 namespace detail {
0027
0028 namespace typeof_pow_adl_barrier {
0029
0030 using std::pow;
0031
0032 template<class Y>
0033 struct typeof_pow
0034 {
0035 #if defined(BOOST_UNITS_HAS_BOOST_TYPEOF)
0036 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, pow(typeof_::make<Y>(), 0.0))
0037 typedef typename nested::type type;
0038 #elif defined(BOOST_UNITS_HAS_MWERKS_TYPEOF)
0039 typedef __typeof__(pow(typeof_::make<Y>(), 0.0)) type;
0040 #elif defined(BOOST_UNITS_HAS_GNU_TYPEOF)
0041 typedef typeof(pow(typeof_::make<Y>(), 0.0)) type;
0042 #else
0043 typedef Y type;
0044 #endif
0045 };
0046
0047 }
0048
0049 template<class R, class Y>
0050 struct static_rational_power_impl
0051 {
0052 typedef typename typeof_pow_adl_barrier::typeof_pow<Y>::type type;
0053 static BOOST_CONSTEXPR type call(const Y& y)
0054 {
0055 using std::pow;
0056 return(pow(y, static_cast<double>(R::Numerator) / static_cast<double>(R::Denominator)));
0057 }
0058 };
0059
0060 template<class R>
0061 struct static_rational_power_impl<R, one>
0062 {
0063 typedef one type;
0064 static BOOST_CONSTEXPR one call(const one&)
0065 {
0066 return(one());
0067 }
0068 };
0069
0070 template<long N>
0071 struct static_rational_power_impl<static_rational<N, 1>, one>
0072 {
0073 typedef one type;
0074 static BOOST_CONSTEXPR one call(const one&)
0075 {
0076 return(one());
0077 }
0078 };
0079
0080 template<long N, bool = (N % 2 == 0)>
0081 struct static_int_power_impl;
0082
0083 template<long N>
0084 struct static_int_power_impl<N, true>
0085 {
0086 template<class Y, class R>
0087 struct apply
0088 {
0089 typedef typename multiply_typeof_helper<Y, Y>::type square_type;
0090 typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, R> next;
0091 typedef typename next::type type;
0092 static BOOST_CONSTEXPR type call(const Y& y, const R& r)
0093 {
0094 return(next::call(static_cast<square_type>(y * y), r));
0095 }
0096 };
0097 };
0098
0099 template<long N>
0100 struct static_int_power_impl<N, false>
0101 {
0102 template<class Y, class R>
0103 struct apply
0104 {
0105 typedef typename multiply_typeof_helper<Y, Y>::type square_type;
0106 typedef typename multiply_typeof_helper<Y, R>::type new_r;
0107 typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, new_r> next;
0108 typedef typename next::type type;
0109 static BOOST_CONSTEXPR type call(const Y& y, const R& r)
0110 {
0111 return(next::call(static_cast<Y>(y * y), y * r));
0112 }
0113 };
0114 };
0115
0116 template<>
0117 struct static_int_power_impl<1, false>
0118 {
0119 template<class Y, class R>
0120 struct apply
0121 {
0122 typedef typename multiply_typeof_helper<Y, R>::type type;
0123 static BOOST_CONSTEXPR type call(const Y& y, const R& r)
0124 {
0125 return(y * r);
0126 }
0127 };
0128 };
0129
0130 template<>
0131 struct static_int_power_impl<0, true>
0132 {
0133 template<class Y, class R>
0134 struct apply
0135 {
0136 typedef R type;
0137 static BOOST_CONSTEXPR R call(const Y&, const R& r)
0138 {
0139 return(r);
0140 }
0141 };
0142 };
0143
0144 template<int N, bool = (N < 0)>
0145 struct static_int_power_sign_impl;
0146
0147 template<int N>
0148 struct static_int_power_sign_impl<N, false>
0149 {
0150 template<class Y>
0151 struct apply
0152 {
0153 typedef typename static_int_power_impl<N>::template apply<Y, one> impl;
0154 typedef typename impl::type type;
0155 static BOOST_CONSTEXPR type call(const Y& y)
0156 {
0157 return(impl::call(y, one()));
0158 }
0159 };
0160 };
0161
0162 template<int N>
0163 struct static_int_power_sign_impl<N, true>
0164 {
0165 template<class Y>
0166 struct apply
0167 {
0168 typedef typename static_int_power_impl<-N>::template apply<Y, one> impl;
0169 typedef typename divide_typeof_helper<one, typename impl::type>::type type;
0170 static BOOST_CONSTEXPR type call(const Y& y)
0171 {
0172 return(one()/impl::call(y, one()));
0173 }
0174 };
0175 };
0176
0177 template<long N, class Y>
0178 struct static_rational_power_impl<static_rational<N, 1>, Y>
0179 {
0180 typedef typename static_int_power_sign_impl<N>::template apply<Y> impl;
0181 typedef typename impl::type type;
0182 static BOOST_CONSTEXPR type call(const Y& y)
0183 {
0184 return(impl::call(y));
0185 }
0186 };
0187
0188 template<class R, class Y>
0189 BOOST_CONSTEXPR
0190 typename detail::static_rational_power_impl<R, Y>::type static_rational_power(const Y& y)
0191 {
0192 return(detail::static_rational_power_impl<R, Y>::call(y));
0193 }
0194
0195 }
0196
0197 }
0198
0199 }
0200
0201 #endif