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