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) 2007-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_DETAIL_UNSCALE_HPP_INCLUDED
|
Chris@16
|
12 #define BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
|
Chris@16
|
13
|
Chris@16
|
14 #include <string>
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/mpl/bool.hpp>
|
Chris@16
|
17 #include <boost/mpl/size.hpp>
|
Chris@16
|
18 #include <boost/mpl/begin.hpp>
|
Chris@16
|
19 #include <boost/mpl/next.hpp>
|
Chris@16
|
20 #include <boost/mpl/deref.hpp>
|
Chris@16
|
21 #include <boost/mpl/plus.hpp>
|
Chris@16
|
22 #include <boost/mpl/times.hpp>
|
Chris@16
|
23 #include <boost/mpl/negate.hpp>
|
Chris@16
|
24 #include <boost/mpl/less.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/units/config.hpp>
|
Chris@16
|
27 #include <boost/units/dimension.hpp>
|
Chris@16
|
28 #include <boost/units/scale.hpp>
|
Chris@16
|
29 #include <boost/units/static_rational.hpp>
|
Chris@16
|
30 #include <boost/units/units_fwd.hpp>
|
Chris@16
|
31 #include <boost/units/detail/one.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 namespace boost {
|
Chris@16
|
34
|
Chris@16
|
35 namespace units {
|
Chris@16
|
36
|
Chris@16
|
37 template<class T>
|
Chris@16
|
38 struct heterogeneous_system;
|
Chris@16
|
39
|
Chris@16
|
40 template<class T, class D, class Scale>
|
Chris@16
|
41 struct heterogeneous_system_impl;
|
Chris@16
|
42
|
Chris@16
|
43 template<class T, class E>
|
Chris@16
|
44 struct heterogeneous_system_dim;
|
Chris@16
|
45
|
Chris@16
|
46 template<class S, class Scale>
|
Chris@16
|
47 struct scaled_base_unit;
|
Chris@16
|
48
|
Chris@16
|
49 /// removes all scaling from a unit or a base unit.
|
Chris@16
|
50 template<class T>
|
Chris@16
|
51 struct unscale
|
Chris@16
|
52 {
|
Chris@16
|
53 #ifndef BOOST_UNITS_DOXYGEN
|
Chris@16
|
54 typedef T type;
|
Chris@16
|
55 #else
|
Chris@16
|
56 typedef detail::unspecified type;
|
Chris@16
|
57 #endif
|
Chris@16
|
58 };
|
Chris@16
|
59
|
Chris@16
|
60 /// INTERNAL ONLY
|
Chris@16
|
61 template<class S, class Scale>
|
Chris@16
|
62 struct unscale<scaled_base_unit<S, Scale> >
|
Chris@16
|
63 {
|
Chris@16
|
64 typedef typename unscale<S>::type type;
|
Chris@16
|
65 };
|
Chris@16
|
66
|
Chris@16
|
67 /// INTERNAL ONLY
|
Chris@16
|
68 template<class D, class S>
|
Chris@16
|
69 struct unscale<unit<D, S> >
|
Chris@16
|
70 {
|
Chris@16
|
71 typedef unit<D, typename unscale<S>::type> type;
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 /// INTERNAL ONLY
|
Chris@16
|
75 template<class Scale>
|
Chris@16
|
76 struct scale_list_dim;
|
Chris@16
|
77
|
Chris@16
|
78 /// INTERNAL ONLY
|
Chris@16
|
79 template<class T>
|
Chris@16
|
80 struct get_scale_list
|
Chris@16
|
81 {
|
Chris@16
|
82 typedef dimensionless_type type;
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85 /// INTERNAL ONLY
|
Chris@16
|
86 template<class S, class Scale>
|
Chris@16
|
87 struct get_scale_list<scaled_base_unit<S, Scale> >
|
Chris@16
|
88 {
|
Chris@16
|
89 typedef typename mpl::times<list<scale_list_dim<Scale>, dimensionless_type>, typename get_scale_list<S>::type>::type type;
|
Chris@16
|
90 };
|
Chris@16
|
91
|
Chris@16
|
92 /// INTERNAL ONLY
|
Chris@16
|
93 template<class D, class S>
|
Chris@16
|
94 struct get_scale_list<unit<D, S> >
|
Chris@16
|
95 {
|
Chris@16
|
96 typedef typename get_scale_list<S>::type type;
|
Chris@16
|
97 };
|
Chris@16
|
98
|
Chris@16
|
99 /// INTERNAL ONLY
|
Chris@16
|
100 struct scale_dim_tag {};
|
Chris@16
|
101
|
Chris@16
|
102 /// INTERNAL ONLY
|
Chris@16
|
103 template<class Scale>
|
Chris@16
|
104 struct scale_list_dim : Scale
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef scale_dim_tag tag;
|
Chris@16
|
107 typedef scale_list_dim type;
|
Chris@16
|
108 };
|
Chris@16
|
109
|
Chris@16
|
110 } // namespace units
|
Chris@16
|
111
|
Chris@16
|
112 #ifndef BOOST_UNITS_DOXYGEN
|
Chris@16
|
113
|
Chris@16
|
114 namespace mpl {
|
Chris@16
|
115
|
Chris@16
|
116 /// INTERNAL ONLY
|
Chris@16
|
117 template<>
|
Chris@16
|
118 struct less_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
|
Chris@16
|
119 {
|
Chris@16
|
120 template<class T0, class T1>
|
Chris@16
|
121 struct apply : mpl::bool_<((T0::base) < (T1::base))> {};
|
Chris@16
|
122 };
|
Chris@16
|
123
|
Chris@16
|
124 }
|
Chris@16
|
125
|
Chris@16
|
126 #endif
|
Chris@16
|
127
|
Chris@16
|
128 namespace units {
|
Chris@16
|
129
|
Chris@16
|
130 namespace detail {
|
Chris@16
|
131
|
Chris@16
|
132 template<class Scale>
|
Chris@16
|
133 struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {};
|
Chris@16
|
134
|
Chris@16
|
135 template<long N>
|
Chris@16
|
136 struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {};
|
Chris@16
|
137
|
Chris@16
|
138 template<int N>
|
Chris@16
|
139 struct eval_scale_list_impl
|
Chris@16
|
140 {
|
Chris@16
|
141 template<class Begin>
|
Chris@16
|
142 struct apply
|
Chris@16
|
143 {
|
Chris@16
|
144 typedef typename eval_scale_list_impl<N-1>::template apply<typename Begin::next> next_iteration;
|
Chris@16
|
145 typedef typename multiply_typeof_helper<typename next_iteration::type, typename Begin::item::value_type>::type type;
|
Chris@16
|
146 static type value()
|
Chris@16
|
147 {
|
Chris@16
|
148 return(next_iteration::value() * Begin::item::value());
|
Chris@16
|
149 }
|
Chris@16
|
150 };
|
Chris@16
|
151 };
|
Chris@16
|
152
|
Chris@16
|
153 template<>
|
Chris@16
|
154 struct eval_scale_list_impl<0>
|
Chris@16
|
155 {
|
Chris@16
|
156 template<class Begin>
|
Chris@16
|
157 struct apply
|
Chris@16
|
158 {
|
Chris@16
|
159 typedef one type;
|
Chris@16
|
160 static one value()
|
Chris@16
|
161 {
|
Chris@16
|
162 one result;
|
Chris@16
|
163 return(result);
|
Chris@16
|
164 }
|
Chris@16
|
165 };
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168 }
|
Chris@16
|
169
|
Chris@16
|
170 /// INTERNAL ONLY
|
Chris@16
|
171 template<class T>
|
Chris@16
|
172 struct eval_scale_list : detail::eval_scale_list_impl<T::size::value>::template apply<T> {};
|
Chris@16
|
173
|
Chris@16
|
174 } // namespace units
|
Chris@16
|
175
|
Chris@16
|
176 #ifndef BOOST_UNITS_DOXYGEN
|
Chris@16
|
177
|
Chris@16
|
178 namespace mpl {
|
Chris@16
|
179
|
Chris@16
|
180 /// INTERNAL ONLY
|
Chris@16
|
181 template<>
|
Chris@16
|
182 struct plus_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
|
Chris@16
|
183 {
|
Chris@16
|
184 template<class T0, class T1>
|
Chris@16
|
185 struct apply
|
Chris@16
|
186 {
|
Chris@16
|
187 typedef boost::units::scale_list_dim<
|
Chris@16
|
188 boost::units::scale<
|
Chris@16
|
189 (T0::base),
|
Chris@16
|
190 typename mpl::plus<typename T0::exponent, typename T1::exponent>::type
|
Chris@16
|
191 >
|
Chris@16
|
192 > type;
|
Chris@16
|
193 };
|
Chris@16
|
194 };
|
Chris@16
|
195
|
Chris@16
|
196 /// INTERNAL ONLY
|
Chris@16
|
197 template<>
|
Chris@16
|
198 struct negate_impl<boost::units::scale_dim_tag>
|
Chris@16
|
199 {
|
Chris@16
|
200 template<class T0>
|
Chris@16
|
201 struct apply
|
Chris@16
|
202 {
|
Chris@16
|
203 typedef boost::units::scale_list_dim<
|
Chris@16
|
204 boost::units::scale<
|
Chris@16
|
205 (T0::base),
|
Chris@16
|
206 typename mpl::negate<typename T0::exponent>::type
|
Chris@16
|
207 >
|
Chris@16
|
208 > type;
|
Chris@16
|
209 };
|
Chris@16
|
210 };
|
Chris@16
|
211
|
Chris@16
|
212 /// INTERNAL ONLY
|
Chris@16
|
213 template<>
|
Chris@16
|
214 struct times_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
|
Chris@16
|
215 {
|
Chris@16
|
216 template<class T0, class T1>
|
Chris@16
|
217 struct apply
|
Chris@16
|
218 {
|
Chris@16
|
219 typedef boost::units::scale_list_dim<
|
Chris@16
|
220 boost::units::scale<
|
Chris@16
|
221 (T0::base),
|
Chris@16
|
222 typename mpl::times<typename T0::exponent, T1>::type
|
Chris@16
|
223 >
|
Chris@16
|
224 > type;
|
Chris@16
|
225 };
|
Chris@16
|
226 };
|
Chris@16
|
227
|
Chris@16
|
228 } // namespace mpl
|
Chris@16
|
229
|
Chris@16
|
230 #endif
|
Chris@16
|
231
|
Chris@16
|
232 } // namespace boost
|
Chris@16
|
233
|
Chris@16
|
234 #endif
|