]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 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 type value(const Radicand& base); | |
156 | }; | |
157 | ||
158 | #endif | |
159 | ||
160 | } // namespace units | |
161 | ||
162 | } // namespace boost | |
163 | ||
164 | #endif // BOOST_UNITS_OPERATORS_HPP |