// 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 #include #include 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 T make(); } // namespace typeof_ #endif #if (BOOST_UNITS_HAS_BOOST_TYPEOF) template struct unary_plus_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make())) typedef typename nested::type type; }; template struct unary_minus_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make())) typedef typename nested::type type; }; template struct add_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()+typeof_::make())) typedef typename nested::type type; }; template struct subtract_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()-typeof_::make())) typedef typename nested::type type; }; template struct multiply_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()*typeof_::make())) typedef typename nested::type type; }; template struct divide_typeof_helper { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()/typeof_::make())) typedef typename nested::type type; }; #elif (BOOST_UNITS_HAS_MWERKS_TYPEOF) template struct unary_plus_typeof_helper { typedef __typeof__((+typeof_::make())) type; }; template struct unary_minus_typeof_helper { typedef __typeof__((-typeof_::make())) type; }; template struct add_typeof_helper { typedef __typeof__((typeof_::make()+typeof_::make())) type; }; template struct subtract_typeof_helper { typedef __typeof__((typeof_::make()-typeof_::make())) type; }; template struct multiply_typeof_helper { typedef __typeof__((typeof_::make()*typeof_::make())) type; }; template struct divide_typeof_helper { typedef __typeof__((typeof_::make()/typeof_::make())) type; }; #elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN) template struct unary_plus_typeof_helper { typedef typeof((+typeof_::make())) type; }; template struct unary_minus_typeof_helper { typedef typeof((-typeof_::make())) type; }; template struct add_typeof_helper { typedef typeof((typeof_::make()+typeof_::make())) type; }; template struct subtract_typeof_helper { typedef typeof((typeof_::make()-typeof_::make())) type; }; template struct multiply_typeof_helper { typedef typeof((typeof_::make()*typeof_::make())) type; }; template struct divide_typeof_helper { typedef typeof((typeof_::make()/typeof_::make())) type; }; #endif #else // BOOST_UNITS_HAS_TYPEOF template struct unary_plus_typeof_helper { typedef X type; }; template struct unary_minus_typeof_helper { typedef X type; }; template struct add_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; template struct subtract_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; template struct multiply_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; template struct divide_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; #endif // BOOST_UNITS_HAS_TYPEOF template struct power_typeof_helper; template 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 /// for and integer argument, N. template 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 /// for and integer argument, N. template 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