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