Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:14

0001 // Boost.Units - A C++ library for zero-overhead dimensional analysis and 
0002 // unit/quantity manipulation and conversion
0003 //
0004 // Copyright (C) 2003-2008 Matthias Christian Schabel
0005 // Copyright (C) 2007-2008 Steven Watanabe
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See
0008 // accompanying file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
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 } // namespace detail
0196 
0197 } // namespace units
0198 
0199 } // namespace boost
0200 
0201 #endif