// 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) 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_OPERATORS_HPP 
#define BOOST_UNITS_OPERATORS_HPP


///
/// \file
/// \brief Compile time operators and typeof helper classes.
/// \details
///   These operators declare the compile-time operators needed to support dimensional
///   analysis algebra.  They require the use of Boost.Typeof, emulation or native.
///   Typeof helper classes define result type for heterogeneous operators on value types.
///   These must be defined through specialization for powers and roots.
///

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>

#include <boost/units/config.hpp>

namespace boost {
namespace units {

#if BOOST_UNITS_HAS_TYPEOF

#ifndef BOOST_UNITS_DOXYGEN

// to avoid need for default constructor and eliminate divide by zero errors.
namespace typeof_ {

/// INTERNAL ONLY
template<class T> T make();

} // namespace typeof_

#endif

#if (BOOST_UNITS_HAS_BOOST_TYPEOF)

template<typename X> struct unary_plus_typeof_helper            
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make<X>()))
    typedef typename nested::type type;
};

template<typename X> struct unary_minus_typeof_helper           
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make<X>()))
    typedef typename nested::type type;
};

template<typename X,typename Y> struct add_typeof_helper        
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()+typeof_::make<Y>()))
    typedef typename nested::type type;
};

template<typename X,typename Y> struct subtract_typeof_helper   
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()-typeof_::make<Y>()))
    typedef typename nested::type type;
};

template<typename X,typename Y> struct multiply_typeof_helper   
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()*typeof_::make<Y>()))
    typedef typename nested::type type;
};

template<typename X,typename Y> struct divide_typeof_helper     
{
    BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()/typeof_::make<Y>()))
    typedef typename nested::type type;
};

#elif (BOOST_UNITS_HAS_MWERKS_TYPEOF)

template<typename X> struct unary_plus_typeof_helper            { typedef __typeof__((+typeof_::make<X>())) type; };
template<typename X> struct unary_minus_typeof_helper           { typedef __typeof__((-typeof_::make<X>())) type; };

template<typename X,typename Y> struct add_typeof_helper        { typedef __typeof__((typeof_::make<X>()+typeof_::make<Y>())) type; };
template<typename X,typename Y> struct subtract_typeof_helper   { typedef __typeof__((typeof_::make<X>()-typeof_::make<Y>())) type; };
template<typename X,typename Y> struct multiply_typeof_helper   { typedef __typeof__((typeof_::make<X>()*typeof_::make<Y>())) type; };
template<typename X,typename Y> struct divide_typeof_helper     { typedef __typeof__((typeof_::make<X>()/typeof_::make<Y>())) type; };

#elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN)

template<typename X> struct unary_plus_typeof_helper            { typedef typeof((+typeof_::make<X>())) type; };
template<typename X> struct unary_minus_typeof_helper           { typedef typeof((-typeof_::make<X>())) type; };

template<typename X,typename Y> struct add_typeof_helper        { typedef typeof((typeof_::make<X>()+typeof_::make<Y>())) type; };
template<typename X,typename Y> struct subtract_typeof_helper   { typedef typeof((typeof_::make<X>()-typeof_::make<Y>())) type; };
template<typename X,typename Y> struct multiply_typeof_helper   { typedef typeof((typeof_::make<X>()*typeof_::make<Y>())) type; };
template<typename X,typename Y> struct divide_typeof_helper     { typedef typeof((typeof_::make<X>()/typeof_::make<Y>())) type; };

#endif

#else // BOOST_UNITS_HAS_TYPEOF

template<typename X> struct unary_plus_typeof_helper            { typedef X type; };
template<typename X> struct unary_minus_typeof_helper           { typedef X type; };

template<typename X,typename Y> struct add_typeof_helper        { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
template<typename X,typename Y> struct subtract_typeof_helper   { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
template<typename X,typename Y> struct multiply_typeof_helper   { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
template<typename X,typename Y> struct divide_typeof_helper     { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };

#endif // BOOST_UNITS_HAS_TYPEOF

template<typename X,typename Y> struct power_typeof_helper;
template<typename X,typename Y> struct root_typeof_helper;

#ifdef BOOST_UNITS_DOXYGEN

/// A helper used by @c pow to raise
/// a runtime object to a compile time
/// known exponent.  This template is intended to
/// be specialized.  All specializations must
/// conform to the interface shown here.
/// @c Exponent will be either the exponent
/// passed to @c pow or @c static_rational<N>
/// for and integer argument, N.
template<typename BaseType, typename Exponent>
struct power_typeof_helper
{
    /// specifies the result type
    typedef detail::unspecified type;
    /// Carries out the runtime calculation.
    static type value(const BaseType& base);
};

/// A helper used by @c root to take a root
/// of a runtime object using a compile time
/// known index.  This template is intended to
/// be specialized.  All specializations must
/// conform to the interface shown here.
/// @c Index will be either the type
/// passed to @c pow or @c static_rational<N>
/// for and integer argument, N.
template<typename Radicand, typename Index>
struct root_typeof_helper
{
    /// specifies the result type
    typedef detail::unspecified type;
    /// Carries out the runtime calculation.
    static type value(const Radicand& base);
};

#endif

} // namespace units

} // namespace boost

#endif // BOOST_UNITS_OPERATORS_HPP
