Chris@16: // Boost.Units - A C++ library for zero-overhead dimensional analysis and Chris@16: // unit/quantity manipulation and conversion Chris@16: // Chris@16: // Copyright (C) 2003-2008 Matthias Christian Schabel Chris@16: // Copyright (C) 2008 Steven Watanabe Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UNITS_OPERATORS_HPP Chris@16: #define BOOST_UNITS_OPERATORS_HPP Chris@16: Chris@16: Chris@16: /// Chris@16: /// \file Chris@16: /// \brief Compile time operators and typeof helper classes. Chris@16: /// \details Chris@16: /// These operators declare the compile-time operators needed to support dimensional Chris@16: /// analysis algebra. They require the use of Boost.Typeof, emulation or native. Chris@16: /// Typeof helper classes define result type for heterogeneous operators on value types. Chris@16: /// These must be defined through specialization for powers and roots. Chris@16: /// Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace units { Chris@16: Chris@16: #if BOOST_UNITS_HAS_TYPEOF Chris@16: Chris@16: #ifndef BOOST_UNITS_DOXYGEN Chris@16: Chris@16: // to avoid need for default constructor and eliminate divide by zero errors. Chris@16: namespace typeof_ { Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: template T make(); Chris@16: Chris@16: } // namespace typeof_ Chris@16: Chris@16: #endif Chris@16: Chris@16: #if (BOOST_UNITS_HAS_BOOST_TYPEOF) Chris@16: Chris@16: template struct unary_plus_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: template struct unary_minus_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: template struct add_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()+typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: template struct subtract_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()-typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: template struct multiply_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()*typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: template struct divide_typeof_helper Chris@16: { Chris@16: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make()/typeof_::make())) Chris@16: typedef typename nested::type type; Chris@16: }; Chris@16: Chris@16: #elif (BOOST_UNITS_HAS_MWERKS_TYPEOF) Chris@16: Chris@16: template struct unary_plus_typeof_helper { typedef __typeof__((+typeof_::make())) type; }; Chris@16: template struct unary_minus_typeof_helper { typedef __typeof__((-typeof_::make())) type; }; Chris@16: Chris@16: template struct add_typeof_helper { typedef __typeof__((typeof_::make()+typeof_::make())) type; }; Chris@16: template struct subtract_typeof_helper { typedef __typeof__((typeof_::make()-typeof_::make())) type; }; Chris@16: template struct multiply_typeof_helper { typedef __typeof__((typeof_::make()*typeof_::make())) type; }; Chris@16: template struct divide_typeof_helper { typedef __typeof__((typeof_::make()/typeof_::make())) type; }; Chris@16: Chris@16: #elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN) Chris@16: Chris@16: template struct unary_plus_typeof_helper { typedef typeof((+typeof_::make())) type; }; Chris@16: template struct unary_minus_typeof_helper { typedef typeof((-typeof_::make())) type; }; Chris@16: Chris@16: template struct add_typeof_helper { typedef typeof((typeof_::make()+typeof_::make())) type; }; Chris@16: template struct subtract_typeof_helper { typedef typeof((typeof_::make()-typeof_::make())) type; }; Chris@16: template struct multiply_typeof_helper { typedef typeof((typeof_::make()*typeof_::make())) type; }; Chris@16: template struct divide_typeof_helper { typedef typeof((typeof_::make()/typeof_::make())) type; }; Chris@16: Chris@16: #endif Chris@16: Chris@16: #else // BOOST_UNITS_HAS_TYPEOF Chris@16: Chris@16: template struct unary_plus_typeof_helper { typedef X type; }; Chris@16: template struct unary_minus_typeof_helper { typedef X type; }; Chris@16: Chris@16: template struct add_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; Chris@16: template struct subtract_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; Chris@16: template struct multiply_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; Chris@16: template struct divide_typeof_helper { BOOST_STATIC_ASSERT((is_same::value == true)); typedef X type; }; Chris@16: Chris@16: #endif // BOOST_UNITS_HAS_TYPEOF Chris@16: Chris@16: template struct power_typeof_helper; Chris@16: template struct root_typeof_helper; Chris@16: Chris@16: #ifdef BOOST_UNITS_DOXYGEN Chris@16: Chris@16: /// A helper used by @c pow to raise Chris@16: /// a runtime object to a compile time Chris@16: /// known exponent. This template is intended to Chris@16: /// be specialized. All specializations must Chris@16: /// conform to the interface shown here. Chris@16: /// @c Exponent will be either the exponent Chris@16: /// passed to @c pow or @c static_rational Chris@16: /// for and integer argument, N. Chris@16: template Chris@16: struct power_typeof_helper Chris@16: { Chris@16: /// specifies the result type Chris@16: typedef detail::unspecified type; Chris@16: /// Carries out the runtime calculation. Chris@16: static type value(const BaseType& base); Chris@16: }; Chris@16: Chris@16: /// A helper used by @c root to take a root Chris@16: /// of a runtime object using a compile time Chris@16: /// known index. This template is intended to Chris@16: /// be specialized. All specializations must Chris@16: /// conform to the interface shown here. Chris@16: /// @c Index will be either the type Chris@16: /// passed to @c pow or @c static_rational Chris@16: /// for and integer argument, N. Chris@16: template Chris@16: struct root_typeof_helper Chris@16: { Chris@16: /// specifies the result type Chris@16: typedef detail::unspecified type; Chris@16: /// Carries out the runtime calculation. Chris@16: static type value(const Radicand& base); Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_OPERATORS_HPP