1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and 2 // unit/quantity manipulation and conversion 3 // 4 // Copyright (C) 2003-2008 Matthias Christian Schabel 5 // Copyright (C) 2008 Steven Watanabe 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See 8 // accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #ifndef BOOST_UNITS_OPERATORS_HPP 12 #define BOOST_UNITS_OPERATORS_HPP 13 14 15 /// 16 /// \file 17 /// \brief Compile time operators and typeof helper classes. 18 /// \details 19 /// These operators declare the compile-time operators needed to support dimensional 20 /// analysis algebra. They require the use of Boost.Typeof, emulation or native. 21 /// Typeof helper classes define result type for heterogeneous operators on value types. 22 /// These must be defined through specialization for powers and roots. 23 /// 24 25 #include <boost/static_assert.hpp> 26 #include <boost/type_traits/is_same.hpp> 27 28 #include <boost/units/config.hpp> 29 30 namespace boost { 31 namespace units { 32 33 #if BOOST_UNITS_HAS_TYPEOF 34 35 #ifndef BOOST_UNITS_DOXYGEN 36 37 // to avoid need for default constructor and eliminate divide by zero errors. 38 namespace typeof_ { 39 40 /// INTERNAL ONLY 41 template<class T> T make(); 42 43 } // namespace typeof_ 44 45 #endif 46 47 #if (BOOST_UNITS_HAS_BOOST_TYPEOF) 48 49 template<typename X> struct unary_plus_typeof_helper 50 { 51 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make<X>())) 52 typedef typename nested::type type; 53 }; 54 55 template<typename X> struct unary_minus_typeof_helper 56 { 57 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make<X>())) 58 typedef typename nested::type type; 59 }; 60 61 template<typename X,typename Y> struct add_typeof_helper 62 { 63 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()+typeof_::make<Y>())) 64 typedef typename nested::type type; 65 }; 66 67 template<typename X,typename Y> struct subtract_typeof_helper 68 { 69 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()-typeof_::make<Y>())) 70 typedef typename nested::type type; 71 }; 72 73 template<typename X,typename Y> struct multiply_typeof_helper 74 { 75 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()*typeof_::make<Y>())) 76 typedef typename nested::type type; 77 }; 78 79 template<typename X,typename Y> struct divide_typeof_helper 80 { 81 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()/typeof_::make<Y>())) 82 typedef typename nested::type type; 83 }; 84 85 #elif (BOOST_UNITS_HAS_MWERKS_TYPEOF) 86 87 template<typename X> struct unary_plus_typeof_helper { typedef __typeof__((+typeof_::make<X>())) type; }; 88 template<typename X> struct unary_minus_typeof_helper { typedef __typeof__((-typeof_::make<X>())) type; }; 89 90 template<typename X,typename Y> struct add_typeof_helper { typedef __typeof__((typeof_::make<X>()+typeof_::make<Y>())) type; }; 91 template<typename X,typename Y> struct subtract_typeof_helper { typedef __typeof__((typeof_::make<X>()-typeof_::make<Y>())) type; }; 92 template<typename X,typename Y> struct multiply_typeof_helper { typedef __typeof__((typeof_::make<X>()*typeof_::make<Y>())) type; }; 93 template<typename X,typename Y> struct divide_typeof_helper { typedef __typeof__((typeof_::make<X>()/typeof_::make<Y>())) type; }; 94 95 #elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN) 96 97 template<typename X> struct unary_plus_typeof_helper { typedef typeof((+typeof_::make<X>())) type; }; 98 template<typename X> struct unary_minus_typeof_helper { typedef typeof((-typeof_::make<X>())) type; }; 99 100 template<typename X,typename Y> struct add_typeof_helper { typedef typeof((typeof_::make<X>()+typeof_::make<Y>())) type; }; 101 template<typename X,typename Y> struct subtract_typeof_helper { typedef typeof((typeof_::make<X>()-typeof_::make<Y>())) type; }; 102 template<typename X,typename Y> struct multiply_typeof_helper { typedef typeof((typeof_::make<X>()*typeof_::make<Y>())) type; }; 103 template<typename X,typename Y> struct divide_typeof_helper { typedef typeof((typeof_::make<X>()/typeof_::make<Y>())) type; }; 104 105 #endif 106 107 #else // BOOST_UNITS_HAS_TYPEOF 108 109 template<typename X> struct unary_plus_typeof_helper { typedef X type; }; 110 template<typename X> struct unary_minus_typeof_helper { typedef X type; }; 111 112 template<typename X,typename Y> struct add_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; 113 template<typename X,typename Y> struct subtract_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; 114 template<typename X,typename Y> struct multiply_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; 115 template<typename X,typename Y> struct divide_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; 116 117 #endif // BOOST_UNITS_HAS_TYPEOF 118 119 template<typename X,typename Y> struct power_typeof_helper; 120 template<typename X,typename Y> struct root_typeof_helper; 121 122 #ifdef BOOST_UNITS_DOXYGEN 123 124 /// A helper used by @c pow to raise 125 /// a runtime object to a compile time 126 /// known exponent. This template is intended to 127 /// be specialized. All specializations must 128 /// conform to the interface shown here. 129 /// @c Exponent will be either the exponent 130 /// passed to @c pow or @c static_rational<N> 131 /// for and integer argument, N. 132 template<typename BaseType, typename Exponent> 133 struct power_typeof_helper 134 { 135 /// specifies the result type 136 typedef detail::unspecified type; 137 /// Carries out the runtime calculation. 138 static BOOST_CONSTEXPR type value(const BaseType& base); 139 }; 140 141 /// A helper used by @c root to take a root 142 /// of a runtime object using a compile time 143 /// known index. This template is intended to 144 /// be specialized. All specializations must 145 /// conform to the interface shown here. 146 /// @c Index will be either the type 147 /// passed to @c pow or @c static_rational<N> 148 /// for and integer argument, N. 149 template<typename Radicand, typename Index> 150 struct root_typeof_helper 151 { 152 /// specifies the result type 153 typedef detail::unspecified type; 154 /// Carries out the runtime calculation. 155 static BOOST_CONSTEXPR type value(const Radicand& base); 156 }; 157 158 #endif 159 160 } // namespace units 161 162 } // namespace boost 163 164 #endif // BOOST_UNITS_OPERATORS_HPP 165