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