// 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
