123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- // 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 BOOST_CONSTEXPR 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 BOOST_CONSTEXPR type value(const Radicand& base);
- };
- #endif
- } // namespace units
- } // namespace boost
- #endif // BOOST_UNITS_OPERATORS_HPP
|