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_QUANTITY_HPP
|
Chris@16
|
12 #define BOOST_UNITS_QUANTITY_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <algorithm>
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/config.hpp>
|
Chris@16
|
17 #include <boost/static_assert.hpp>
|
Chris@16
|
18 #include <boost/mpl/bool.hpp>
|
Chris@16
|
19 #include <boost/mpl/and.hpp>
|
Chris@16
|
20 #include <boost/mpl/not.hpp>
|
Chris@16
|
21 #include <boost/mpl/or.hpp>
|
Chris@16
|
22 #include <boost/mpl/assert.hpp>
|
Chris@16
|
23 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
24 #include <boost/type_traits/is_arithmetic.hpp>
|
Chris@16
|
25 #include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
26 #include <boost/type_traits/is_integral.hpp>
|
Chris@16
|
27 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/units/conversion.hpp>
|
Chris@16
|
30 #include <boost/units/dimensionless_type.hpp>
|
Chris@16
|
31 #include <boost/units/homogeneous_system.hpp>
|
Chris@16
|
32 #include <boost/units/operators.hpp>
|
Chris@16
|
33 #include <boost/units/static_rational.hpp>
|
Chris@16
|
34 #include <boost/units/units_fwd.hpp>
|
Chris@16
|
35 #include <boost/units/detail/dimensionless_unit.hpp>
|
Chris@16
|
36
|
Chris@16
|
37 namespace boost {
|
Chris@16
|
38
|
Chris@16
|
39 namespace units {
|
Chris@16
|
40
|
Chris@16
|
41 namespace detail {
|
Chris@16
|
42
|
Chris@16
|
43 template<class T, class Enable = void>
|
Chris@16
|
44 struct is_base_unit : mpl::false_ {};
|
Chris@16
|
45
|
Chris@16
|
46 template<class T>
|
Chris@16
|
47 struct is_base_unit<T, typename T::boost_units_is_base_unit_type> : mpl::true_ {};
|
Chris@16
|
48
|
Chris@16
|
49 template<class Source, class Destination>
|
Chris@16
|
50 struct is_narrowing_conversion_impl : mpl::bool_<(sizeof(Source) > sizeof(Destination))> {};
|
Chris@16
|
51
|
Chris@16
|
52 template<class Source, class Destination>
|
Chris@16
|
53 struct is_non_narrowing_conversion :
|
Chris@16
|
54 mpl::and_<
|
Chris@16
|
55 boost::is_convertible<Source, Destination>,
|
Chris@16
|
56 mpl::not_<
|
Chris@16
|
57 mpl::and_<
|
Chris@16
|
58 boost::is_arithmetic<Source>,
|
Chris@16
|
59 boost::is_arithmetic<Destination>,
|
Chris@16
|
60 mpl::or_<
|
Chris@16
|
61 mpl::and_<
|
Chris@16
|
62 is_integral<Destination>,
|
Chris@16
|
63 mpl::not_<is_integral<Source> >
|
Chris@16
|
64 >,
|
Chris@16
|
65 is_narrowing_conversion_impl<Source, Destination>
|
Chris@16
|
66 >
|
Chris@16
|
67 >
|
Chris@16
|
68 >
|
Chris@16
|
69 >
|
Chris@16
|
70 {};
|
Chris@16
|
71
|
Chris@16
|
72 template<>
|
Chris@16
|
73 struct is_non_narrowing_conversion<long double, double> : mpl::false_ {};
|
Chris@16
|
74
|
Chris@16
|
75 // msvc 7.1 needs extra disambiguation
|
Chris@16
|
76 template<class T, class U>
|
Chris@16
|
77 struct disable_if_is_same
|
Chris@16
|
78 {
|
Chris@16
|
79 typedef void type;
|
Chris@16
|
80 };
|
Chris@16
|
81
|
Chris@16
|
82 template<class T>
|
Chris@16
|
83 struct disable_if_is_same<T, T> {};
|
Chris@16
|
84
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 /// class declaration
|
Chris@101
|
88 template<class Unit,class Y>
|
Chris@16
|
89 class quantity
|
Chris@16
|
90 {
|
Chris@16
|
91 // base units are not the same as units.
|
Chris@16
|
92 BOOST_MPL_ASSERT_NOT((detail::is_base_unit<Unit>));
|
Chris@16
|
93 enum { force_instantiation_of_unit = sizeof(Unit) };
|
Chris@16
|
94 typedef void (quantity::*unspecified_null_pointer_constant_type)(int*******);
|
Chris@16
|
95 public:
|
Chris@16
|
96 typedef quantity<Unit,Y> this_type;
|
Chris@16
|
97
|
Chris@16
|
98 typedef Y value_type;
|
Chris@16
|
99 typedef Unit unit_type;
|
Chris@16
|
100
|
Chris@16
|
101 quantity() : val_()
|
Chris@16
|
102 {
|
Chris@16
|
103 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 quantity(unspecified_null_pointer_constant_type) : val_()
|
Chris@16
|
107 {
|
Chris@16
|
108 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 quantity(const this_type& source) : val_(source.val_)
|
Chris@16
|
112 {
|
Chris@16
|
113 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 // Need to make sure that the destructor of
|
Chris@16
|
117 // Unit which contains the checking is instantiated,
|
Chris@16
|
118 // on sun.
|
Chris@16
|
119 #ifdef __SUNPRO_CC
|
Chris@16
|
120 ~quantity() {
|
Chris@16
|
121 unit_type force_unit_instantiation;
|
Chris@16
|
122 }
|
Chris@16
|
123 #endif
|
Chris@16
|
124
|
Chris@16
|
125 //~quantity() { }
|
Chris@16
|
126
|
Chris@16
|
127 this_type& operator=(const this_type& source)
|
Chris@16
|
128 {
|
Chris@16
|
129 val_ = source.val_;
|
Chris@16
|
130
|
Chris@16
|
131 return *this;
|
Chris@16
|
132 }
|
Chris@16
|
133
|
Chris@16
|
134 #ifndef BOOST_NO_SFINAE
|
Chris@16
|
135
|
Chris@16
|
136 /// implicit conversion between value types is allowed if allowed for value types themselves
|
Chris@16
|
137 template<class YY>
|
Chris@16
|
138 quantity(const quantity<Unit,YY>& source,
|
Chris@16
|
139 typename boost::enable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
|
Chris@16
|
140 val_(source.value())
|
Chris@16
|
141 {
|
Chris@16
|
142 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
143 }
|
Chris@16
|
144
|
Chris@16
|
145 /// implicit conversion between value types is not allowed if not allowed for value types themselves
|
Chris@16
|
146 template<class YY>
|
Chris@16
|
147 explicit quantity(const quantity<Unit,YY>& source,
|
Chris@16
|
148 typename boost::disable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
|
Chris@16
|
149 val_(static_cast<Y>(source.value()))
|
Chris@16
|
150 {
|
Chris@16
|
151 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
152 }
|
Chris@16
|
153
|
Chris@16
|
154 #else
|
Chris@16
|
155
|
Chris@16
|
156 /// implicit conversion between value types is allowed if allowed for value types themselves
|
Chris@16
|
157 template<class YY>
|
Chris@16
|
158 quantity(const quantity<Unit,YY>& source) :
|
Chris@16
|
159 val_(source.value())
|
Chris@16
|
160 {
|
Chris@16
|
161 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
162 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
|
Chris@16
|
163 }
|
Chris@16
|
164
|
Chris@16
|
165 #endif
|
Chris@16
|
166
|
Chris@16
|
167 /// implicit assignment between value types is allowed if allowed for value types themselves
|
Chris@16
|
168 template<class YY>
|
Chris@16
|
169 this_type& operator=(const quantity<Unit,YY>& source)
|
Chris@16
|
170 {
|
Chris@16
|
171 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
|
Chris@16
|
172
|
Chris@16
|
173 *this = this_type(source);
|
Chris@16
|
174
|
Chris@16
|
175 return *this;
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 #ifndef BOOST_NO_SFINAE
|
Chris@16
|
179
|
Chris@16
|
180 /// explicit conversion between different unit systems is allowed if implicit conversion is disallowed
|
Chris@16
|
181 template<class Unit2,class YY>
|
Chris@16
|
182 explicit
|
Chris@16
|
183 quantity(const quantity<Unit2,YY>& source,
|
Chris@16
|
184 typename boost::disable_if<
|
Chris@16
|
185 mpl::and_<
|
Chris@16
|
186 //is_implicitly_convertible should be undefined when the
|
Chris@16
|
187 //units are not convertible at all
|
Chris@16
|
188 typename is_implicitly_convertible<Unit2,Unit>::type,
|
Chris@16
|
189 detail::is_non_narrowing_conversion<YY, Y>
|
Chris@16
|
190 >,
|
Chris@16
|
191 typename detail::disable_if_is_same<Unit, Unit2>::type
|
Chris@16
|
192 >::type* = 0)
|
Chris@16
|
193 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
|
Chris@16
|
194 {
|
Chris@16
|
195 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
196 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
|
Chris@16
|
197 }
|
Chris@16
|
198
|
Chris@16
|
199 /// implicit conversion between different unit systems is allowed if each fundamental dimension is implicitly convertible
|
Chris@16
|
200 template<class Unit2,class YY>
|
Chris@16
|
201 quantity(const quantity<Unit2,YY>& source,
|
Chris@16
|
202 typename boost::enable_if<
|
Chris@16
|
203 mpl::and_<
|
Chris@16
|
204 typename is_implicitly_convertible<Unit2,Unit>::type,
|
Chris@16
|
205 detail::is_non_narrowing_conversion<YY, Y>
|
Chris@16
|
206 >,
|
Chris@16
|
207 typename detail::disable_if_is_same<Unit, Unit2>::type
|
Chris@16
|
208 >::type* = 0)
|
Chris@16
|
209 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
|
Chris@16
|
210 {
|
Chris@16
|
211 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
212 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 #else
|
Chris@16
|
216
|
Chris@16
|
217 /// without SFINAE we can't distinguish between explicit and implicit conversions so
|
Chris@16
|
218 /// the conversion is always explicit
|
Chris@16
|
219 template<class Unit2,class YY>
|
Chris@16
|
220 explicit quantity(const quantity<Unit2,YY>& source)
|
Chris@16
|
221 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
|
Chris@16
|
222 {
|
Chris@16
|
223 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
224 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 #endif
|
Chris@16
|
228
|
Chris@16
|
229 /// implicit assignment between different unit systems is allowed if each fundamental dimension is implicitly convertible
|
Chris@16
|
230 template<class Unit2,class YY>
|
Chris@16
|
231 this_type& operator=(const quantity<Unit2,YY>& source)
|
Chris@16
|
232 {
|
Chris@16
|
233
|
Chris@16
|
234 BOOST_STATIC_ASSERT((is_implicitly_convertible<Unit2,unit_type>::value == true));
|
Chris@16
|
235 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
|
Chris@16
|
236
|
Chris@16
|
237 *this = this_type(source);
|
Chris@16
|
238
|
Chris@16
|
239 return *this;
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242 const value_type& value() const { return val_; } ///< constant accessor to value
|
Chris@16
|
243
|
Chris@16
|
244 ///< can add a quantity of the same type if add_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
245 template<class Unit2, class YY>
|
Chris@16
|
246 this_type& operator+=(const quantity<Unit2, YY>& source)
|
Chris@16
|
247 {
|
Chris@16
|
248 BOOST_STATIC_ASSERT((boost::is_same<typename add_typeof_helper<Unit, Unit2>::type, Unit>::value));
|
Chris@16
|
249 val_ += source.value();
|
Chris@16
|
250 return *this;
|
Chris@16
|
251 }
|
Chris@16
|
252
|
Chris@16
|
253 ///< can subtract a quantity of the same type if subtract_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
254 template<class Unit2, class YY>
|
Chris@16
|
255 this_type& operator-=(const quantity<Unit2, YY>& source)
|
Chris@16
|
256 {
|
Chris@16
|
257 BOOST_STATIC_ASSERT((boost::is_same<typename subtract_typeof_helper<Unit, Unit2>::type, Unit>::value));
|
Chris@16
|
258 val_ -= source.value();
|
Chris@16
|
259 return *this;
|
Chris@16
|
260 }
|
Chris@16
|
261
|
Chris@16
|
262 template<class Unit2, class YY>
|
Chris@16
|
263 this_type& operator*=(const quantity<Unit2, YY>& source)
|
Chris@16
|
264 {
|
Chris@16
|
265 BOOST_STATIC_ASSERT((boost::is_same<typename multiply_typeof_helper<Unit, Unit2>::type, Unit>::value));
|
Chris@16
|
266 val_ *= source.value();
|
Chris@16
|
267 return *this;
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 template<class Unit2, class YY>
|
Chris@16
|
271 this_type& operator/=(const quantity<Unit2, YY>& source)
|
Chris@16
|
272 {
|
Chris@16
|
273 BOOST_STATIC_ASSERT((boost::is_same<typename divide_typeof_helper<Unit, Unit2>::type, Unit>::value));
|
Chris@16
|
274 val_ /= source.value();
|
Chris@16
|
275 return *this;
|
Chris@16
|
276 }
|
Chris@16
|
277
|
Chris@16
|
278 ///< can multiply a quantity by a scalar value_type if multiply_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
279 this_type& operator*=(const value_type& source) { val_ *= source; return *this; }
|
Chris@16
|
280 ///< can divide a quantity by a scalar value_type if divide_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
281 this_type& operator/=(const value_type& source) { val_ /= source; return *this; }
|
Chris@16
|
282
|
Chris@16
|
283 /// Construct quantity directly from @c value_type (potentially dangerous).
|
Chris@16
|
284 static this_type from_value(const value_type& val) { return this_type(val, 0); }
|
Chris@16
|
285
|
Chris@16
|
286 protected:
|
Chris@16
|
287 explicit quantity(const value_type& val, int) : val_(val) { }
|
Chris@16
|
288
|
Chris@16
|
289 private:
|
Chris@16
|
290 value_type val_;
|
Chris@16
|
291 };
|
Chris@16
|
292
|
Chris@16
|
293 /// Specialization for dimensionless quantities. Implicit conversions between
|
Chris@16
|
294 /// unit systems are allowed because all dimensionless quantities are equivalent.
|
Chris@16
|
295 /// Implicit construction and assignment from and conversion to @c value_type is
|
Chris@16
|
296 /// also allowed.
|
Chris@16
|
297 template<class System,class Y>
|
Chris@16
|
298 class quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System),Y>
|
Chris@16
|
299 {
|
Chris@16
|
300 public:
|
Chris@16
|
301 typedef quantity<unit<dimensionless_type,System>,Y> this_type;
|
Chris@16
|
302
|
Chris@16
|
303 typedef Y value_type;
|
Chris@16
|
304 typedef System system_type;
|
Chris@16
|
305 typedef dimensionless_type dimension_type;
|
Chris@16
|
306 typedef unit<dimension_type,system_type> unit_type;
|
Chris@16
|
307
|
Chris@16
|
308 quantity() : val_()
|
Chris@16
|
309 {
|
Chris@16
|
310 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
311 }
|
Chris@16
|
312
|
Chris@16
|
313 /// construction from raw @c value_type is allowed
|
Chris@16
|
314 quantity(value_type val) : val_(val)
|
Chris@16
|
315 {
|
Chris@16
|
316 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
317 }
|
Chris@16
|
318
|
Chris@16
|
319 quantity(const this_type& source) : val_(source.val_)
|
Chris@16
|
320 {
|
Chris@16
|
321 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
322 }
|
Chris@16
|
323
|
Chris@16
|
324 //~quantity() { }
|
Chris@16
|
325
|
Chris@16
|
326 this_type& operator=(const this_type& source)
|
Chris@16
|
327 {
|
Chris@16
|
328 val_ = source.val_;
|
Chris@16
|
329
|
Chris@16
|
330 return *this;
|
Chris@16
|
331 }
|
Chris@16
|
332
|
Chris@16
|
333 #ifndef BOOST_NO_SFINAE
|
Chris@16
|
334
|
Chris@16
|
335 /// implicit conversion between value types is allowed if allowed for value types themselves
|
Chris@16
|
336 template<class YY>
|
Chris@16
|
337 quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
|
Chris@16
|
338 typename boost::enable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
|
Chris@16
|
339 val_(source.value())
|
Chris@16
|
340 {
|
Chris@16
|
341 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
342 }
|
Chris@16
|
343
|
Chris@16
|
344 /// implicit conversion between value types is not allowed if not allowed for value types themselves
|
Chris@16
|
345 template<class YY>
|
Chris@16
|
346 explicit quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
|
Chris@16
|
347 typename boost::disable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
|
Chris@16
|
348 val_(static_cast<Y>(source.value()))
|
Chris@16
|
349 {
|
Chris@16
|
350 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
351 }
|
Chris@16
|
352
|
Chris@16
|
353 #else
|
Chris@16
|
354
|
Chris@16
|
355 /// implicit conversion between value types is allowed if allowed for value types themselves
|
Chris@16
|
356 template<class YY>
|
Chris@16
|
357 quantity(const quantity<unit<dimension_type,system_type>,YY>& source) :
|
Chris@16
|
358 val_(source.value())
|
Chris@16
|
359 {
|
Chris@16
|
360 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
361 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
|
Chris@16
|
362 }
|
Chris@16
|
363
|
Chris@16
|
364 #endif
|
Chris@16
|
365
|
Chris@16
|
366 /// implicit assignment between value types is allowed if allowed for value types themselves
|
Chris@16
|
367 template<class YY>
|
Chris@16
|
368 this_type& operator=(const quantity<unit<dimension_type,system_type>,YY>& source)
|
Chris@16
|
369 {
|
Chris@16
|
370 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
|
Chris@16
|
371
|
Chris@16
|
372 *this = this_type(source);
|
Chris@16
|
373
|
Chris@16
|
374 return *this;
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 #if 1
|
Chris@16
|
378
|
Chris@16
|
379 /// implicit conversion between different unit systems is allowed
|
Chris@16
|
380 template<class System2, class Y2>
|
Chris@16
|
381 quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
|
Chris@16
|
382 #ifdef __SUNPRO_CC
|
Chris@16
|
383 typename boost::enable_if<
|
Chris@16
|
384 boost::mpl::and_<
|
Chris@16
|
385 detail::is_non_narrowing_conversion<Y2, Y>,
|
Chris@16
|
386 detail::is_dimensionless_system<System2>
|
Chris@16
|
387 >
|
Chris@16
|
388 >::type* = 0
|
Chris@16
|
389 #else
|
Chris@16
|
390 typename boost::enable_if<detail::is_non_narrowing_conversion<Y2, Y> >::type* = 0,
|
Chris@16
|
391 typename detail::disable_if_is_same<System, System2>::type* = 0,
|
Chris@16
|
392 typename boost::enable_if<detail::is_dimensionless_system<System2> >::type* = 0
|
Chris@16
|
393 #endif
|
Chris@16
|
394 ) :
|
Chris@16
|
395 val_(source.value())
|
Chris@16
|
396 {
|
Chris@16
|
397 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
398 }
|
Chris@16
|
399
|
Chris@16
|
400 /// implicit conversion between different unit systems is allowed
|
Chris@16
|
401 template<class System2, class Y2>
|
Chris@16
|
402 explicit quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
|
Chris@16
|
403 #ifdef __SUNPRO_CC
|
Chris@16
|
404 typename boost::enable_if<
|
Chris@16
|
405 boost::mpl::and_<
|
Chris@16
|
406 boost::mpl::not_<detail::is_non_narrowing_conversion<Y2, Y> >,
|
Chris@16
|
407 detail::is_dimensionless_system<System2>
|
Chris@16
|
408 >
|
Chris@16
|
409 >::type* = 0
|
Chris@16
|
410 #else
|
Chris@16
|
411 typename boost::disable_if<detail::is_non_narrowing_conversion<Y2, Y> >::type* = 0,
|
Chris@16
|
412 typename detail::disable_if_is_same<System, System2>::type* = 0,
|
Chris@16
|
413 typename boost::enable_if<detail::is_dimensionless_system<System2> >::type* = 0
|
Chris@16
|
414 #endif
|
Chris@16
|
415 ) :
|
Chris@16
|
416 val_(static_cast<Y>(source.value()))
|
Chris@16
|
417 {
|
Chris@16
|
418 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
419 }
|
Chris@16
|
420
|
Chris@16
|
421 #else
|
Chris@16
|
422
|
Chris@16
|
423 /// implicit conversion between different unit systems is allowed
|
Chris@16
|
424 template<class System2, class Y2>
|
Chris@16
|
425 quantity(const quantity<unit<dimensionless_type,homogeneous_system<System2> >,Y2>& source) :
|
Chris@16
|
426 val_(source.value())
|
Chris@16
|
427 {
|
Chris@16
|
428 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
429 BOOST_STATIC_ASSERT((boost::is_convertible<Y2, Y>::value == true));
|
Chris@16
|
430 }
|
Chris@16
|
431
|
Chris@16
|
432 #endif
|
Chris@16
|
433
|
Chris@16
|
434 /// conversion between different unit systems is explicit when
|
Chris@16
|
435 /// the units are not equivalent.
|
Chris@16
|
436 template<class System2, class Y2>
|
Chris@16
|
437 explicit quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
|
Chris@16
|
438 typename boost::disable_if<detail::is_dimensionless_system<System2> >::type* = 0) :
|
Chris@16
|
439 val_(conversion_helper<quantity<unit<dimensionless_type, System2>,Y2>, this_type>::convert(source).value())
|
Chris@16
|
440 {
|
Chris@16
|
441 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
|
Chris@16
|
442 }
|
Chris@16
|
443
|
Chris@16
|
444 #ifndef __SUNPRO_CC
|
Chris@16
|
445
|
Chris@16
|
446 /// implicit assignment between different unit systems is allowed
|
Chris@16
|
447 template<class System2>
|
Chris@16
|
448 this_type& operator=(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System2),Y>& source)
|
Chris@16
|
449 {
|
Chris@16
|
450 *this = this_type(source);
|
Chris@16
|
451
|
Chris@16
|
452 return *this;
|
Chris@16
|
453 }
|
Chris@16
|
454
|
Chris@16
|
455 #endif
|
Chris@16
|
456
|
Chris@16
|
457 /// implicit conversion to @c value_type is allowed
|
Chris@16
|
458 operator value_type() const { return val_; }
|
Chris@16
|
459
|
Chris@16
|
460 const value_type& value() const { return val_; } ///< constant accessor to value
|
Chris@16
|
461
|
Chris@16
|
462 ///< can add a quantity of the same type if add_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
463 this_type& operator+=(const this_type& source) { val_ += source.val_; return *this; }
|
Chris@16
|
464
|
Chris@16
|
465 ///< can subtract a quantity of the same type if subtract_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
466 this_type& operator-=(const this_type& source) { val_ -= source.val_; return *this; }
|
Chris@16
|
467
|
Chris@16
|
468 ///< can multiply a quantity by a scalar value_type if multiply_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
469 this_type& operator*=(const value_type& val) { val_ *= val; return *this; }
|
Chris@16
|
470
|
Chris@16
|
471 ///< can divide a quantity by a scalar value_type if divide_typeof_helper<value_type,value_type>::type is convertible to value_type
|
Chris@16
|
472 this_type& operator/=(const value_type& val) { val_ /= val; return *this; }
|
Chris@16
|
473
|
Chris@16
|
474 /// Construct quantity directly from @c value_type.
|
Chris@16
|
475 static this_type from_value(const value_type& val) { return this_type(val); }
|
Chris@16
|
476
|
Chris@16
|
477 private:
|
Chris@16
|
478 value_type val_;
|
Chris@16
|
479 };
|
Chris@16
|
480
|
Chris@16
|
481 #ifdef BOOST_MSVC
|
Chris@16
|
482 // HACK: For some obscure reason msvc 8.0 needs these specializations
|
Chris@16
|
483 template<class System, class T>
|
Chris@16
|
484 class quantity<unit<int, System>, T> {};
|
Chris@16
|
485 template<class T>
|
Chris@16
|
486 class quantity<int, T> {};
|
Chris@16
|
487 #endif
|
Chris@16
|
488
|
Chris@16
|
489 } // namespace units
|
Chris@16
|
490
|
Chris@16
|
491 } // namespace boost
|
Chris@16
|
492
|
Chris@16
|
493 #if BOOST_UNITS_HAS_BOOST_TYPEOF
|
Chris@16
|
494
|
Chris@16
|
495 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
Chris@16
|
496
|
Chris@16
|
497 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::quantity, 2)
|
Chris@16
|
498
|
Chris@16
|
499 #endif
|
Chris@16
|
500
|
Chris@16
|
501 namespace boost {
|
Chris@16
|
502
|
Chris@16
|
503 namespace units {
|
Chris@16
|
504
|
Chris@16
|
505 namespace detail {
|
Chris@16
|
506
|
Chris@16
|
507 /// helper class for quantity_cast
|
Chris@16
|
508 template<class X,class Y> struct quantity_cast_helper;
|
Chris@16
|
509
|
Chris@16
|
510 /// specialization for casting to the value type
|
Chris@16
|
511 template<class Y,class X,class Unit>
|
Chris@16
|
512 struct quantity_cast_helper<Y,quantity<Unit,X> >
|
Chris@16
|
513 {
|
Chris@16
|
514 typedef Y type;
|
Chris@16
|
515
|
Chris@16
|
516 type operator()(quantity<Unit,X>& source) { return const_cast<X&>(source.value()); }
|
Chris@16
|
517 };
|
Chris@16
|
518
|
Chris@16
|
519 /// specialization for casting to the value type
|
Chris@16
|
520 template<class Y,class X,class Unit>
|
Chris@16
|
521 struct quantity_cast_helper<Y,const quantity<Unit,X> >
|
Chris@16
|
522 {
|
Chris@16
|
523 typedef Y type;
|
Chris@16
|
524
|
Chris@16
|
525 type operator()(const quantity<Unit,X>& source) { return source.value(); }
|
Chris@16
|
526 };
|
Chris@16
|
527
|
Chris@16
|
528 } // namespace detail
|
Chris@16
|
529
|
Chris@16
|
530 /// quantity_cast provides mutating access to underlying quantity value_type
|
Chris@16
|
531 template<class X,class Y>
|
Chris@16
|
532 inline
|
Chris@16
|
533 X
|
Chris@16
|
534 quantity_cast(Y& source)
|
Chris@16
|
535 {
|
Chris@16
|
536 detail::quantity_cast_helper<X,Y> qch;
|
Chris@16
|
537
|
Chris@16
|
538 return qch(source);
|
Chris@16
|
539 }
|
Chris@16
|
540
|
Chris@16
|
541 template<class X,class Y>
|
Chris@16
|
542 inline
|
Chris@16
|
543 X
|
Chris@16
|
544 quantity_cast(const Y& source)
|
Chris@16
|
545 {
|
Chris@16
|
546 detail::quantity_cast_helper<X,const Y> qch;
|
Chris@16
|
547
|
Chris@16
|
548 return qch(source);
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 /// swap quantities
|
Chris@16
|
552 template<class Unit,class Y>
|
Chris@16
|
553 inline void swap(quantity<Unit,Y>& lhs, quantity<Unit,Y>& rhs)
|
Chris@16
|
554 {
|
Chris@16
|
555 using std::swap;
|
Chris@16
|
556 swap(quantity_cast<Y&>(lhs),quantity_cast<Y&>(rhs));
|
Chris@16
|
557 }
|
Chris@16
|
558
|
Chris@16
|
559 /// specialize unary plus typeof helper
|
Chris@16
|
560 /// INTERNAL ONLY
|
Chris@16
|
561 template<class Unit,class Y>
|
Chris@16
|
562 struct unary_plus_typeof_helper< quantity<Unit,Y> >
|
Chris@16
|
563 {
|
Chris@16
|
564 typedef typename unary_plus_typeof_helper<Y>::type value_type;
|
Chris@16
|
565 typedef typename unary_plus_typeof_helper<Unit>::type unit_type;
|
Chris@16
|
566 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
567 };
|
Chris@16
|
568
|
Chris@16
|
569 /// specialize unary minus typeof helper
|
Chris@16
|
570 /// INTERNAL ONLY
|
Chris@16
|
571 template<class Unit,class Y>
|
Chris@16
|
572 struct unary_minus_typeof_helper< quantity<Unit,Y> >
|
Chris@16
|
573 {
|
Chris@16
|
574 typedef typename unary_minus_typeof_helper<Y>::type value_type;
|
Chris@16
|
575 typedef typename unary_minus_typeof_helper<Unit>::type unit_type;
|
Chris@16
|
576 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
577 };
|
Chris@16
|
578
|
Chris@16
|
579 /// specialize add typeof helper
|
Chris@16
|
580 /// INTERNAL ONLY
|
Chris@16
|
581 template<class Unit1,
|
Chris@16
|
582 class Unit2,
|
Chris@16
|
583 class X,
|
Chris@16
|
584 class Y>
|
Chris@16
|
585 struct add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
|
Chris@16
|
586 {
|
Chris@16
|
587 typedef typename add_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
588 typedef typename add_typeof_helper<Unit1,Unit2>::type unit_type;
|
Chris@16
|
589 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
590 };
|
Chris@16
|
591
|
Chris@16
|
592 /// for sun CC we need to invoke SFINAE at
|
Chris@16
|
593 /// the top level, otherwise it will silently
|
Chris@16
|
594 /// return int.
|
Chris@16
|
595 template<class Dim1, class System1,
|
Chris@16
|
596 class Dim2, class System2,
|
Chris@16
|
597 class X,
|
Chris@16
|
598 class Y>
|
Chris@16
|
599 struct add_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> >
|
Chris@16
|
600 {
|
Chris@16
|
601 };
|
Chris@16
|
602
|
Chris@16
|
603 template<class Dim,
|
Chris@16
|
604 class System,
|
Chris@16
|
605 class X,
|
Chris@16
|
606 class Y>
|
Chris@16
|
607 struct add_typeof_helper< quantity<unit<Dim, System>,X>,quantity<unit<Dim, System>,Y> >
|
Chris@16
|
608 {
|
Chris@16
|
609 typedef typename add_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
610 typedef unit<Dim, System> unit_type;
|
Chris@16
|
611 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
612 };
|
Chris@16
|
613
|
Chris@16
|
614 /// specialize subtract typeof helper
|
Chris@16
|
615 /// INTERNAL ONLY
|
Chris@16
|
616 template<class Unit1,
|
Chris@16
|
617 class Unit2,
|
Chris@16
|
618 class X,
|
Chris@16
|
619 class Y>
|
Chris@16
|
620 struct subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
|
Chris@16
|
621 {
|
Chris@16
|
622 typedef typename subtract_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
623 typedef typename subtract_typeof_helper<Unit1,Unit2>::type unit_type;
|
Chris@16
|
624 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
625 };
|
Chris@16
|
626
|
Chris@16
|
627 // Force adding different units to fail on sun.
|
Chris@16
|
628 template<class Dim1, class System1,
|
Chris@16
|
629 class Dim2, class System2,
|
Chris@16
|
630 class X,
|
Chris@16
|
631 class Y>
|
Chris@16
|
632 struct subtract_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> >
|
Chris@16
|
633 {
|
Chris@16
|
634 };
|
Chris@16
|
635
|
Chris@16
|
636 template<class Dim,
|
Chris@16
|
637 class System,
|
Chris@16
|
638 class X,
|
Chris@16
|
639 class Y>
|
Chris@16
|
640 struct subtract_typeof_helper< quantity<unit<Dim, System>,X>,quantity<unit<Dim, System>,Y> >
|
Chris@16
|
641 {
|
Chris@16
|
642 typedef typename subtract_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
643 typedef unit<Dim, System> unit_type;
|
Chris@16
|
644 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
645 };
|
Chris@16
|
646
|
Chris@16
|
647 /// scalar times unit typeof helper
|
Chris@16
|
648 /// INTERNAL ONLY
|
Chris@16
|
649 template<class System,
|
Chris@16
|
650 class Dim,
|
Chris@16
|
651 class X>
|
Chris@16
|
652 struct multiply_typeof_helper< X,unit<Dim,System> >
|
Chris@16
|
653 {
|
Chris@16
|
654 typedef X value_type;
|
Chris@16
|
655 typedef unit<Dim,System> unit_type;
|
Chris@16
|
656 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
657 };
|
Chris@16
|
658
|
Chris@16
|
659 /// unit times scalar typeof helper
|
Chris@16
|
660 /// INTERNAL ONLY
|
Chris@16
|
661 template<class System,
|
Chris@16
|
662 class Dim,
|
Chris@16
|
663 class X>
|
Chris@16
|
664 struct multiply_typeof_helper< unit<Dim,System>,X >
|
Chris@16
|
665 {
|
Chris@16
|
666 typedef X value_type;
|
Chris@16
|
667 typedef unit<Dim,System> unit_type;
|
Chris@16
|
668 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
669 };
|
Chris@16
|
670
|
Chris@16
|
671 /// scalar times quantity typeof helper
|
Chris@16
|
672 /// INTERNAL ONLY
|
Chris@16
|
673 template<class Unit,
|
Chris@16
|
674 class X,
|
Chris@16
|
675 class Y>
|
Chris@16
|
676 struct multiply_typeof_helper< X,quantity<Unit,Y> >
|
Chris@16
|
677 {
|
Chris@16
|
678 typedef typename multiply_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
679 typedef Unit unit_type;
|
Chris@16
|
680 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
681 };
|
Chris@16
|
682
|
Chris@16
|
683 /// disambiguate
|
Chris@16
|
684 /// INTERNAL ONLY
|
Chris@16
|
685 template<class Unit,
|
Chris@16
|
686 class Y>
|
Chris@16
|
687 struct multiply_typeof_helper< one,quantity<Unit,Y> >
|
Chris@16
|
688 {
|
Chris@16
|
689 typedef quantity<Unit,Y> type;
|
Chris@16
|
690 };
|
Chris@16
|
691
|
Chris@16
|
692 /// quantity times scalar typeof helper
|
Chris@16
|
693 /// INTERNAL ONLY
|
Chris@16
|
694 template<class Unit,
|
Chris@16
|
695 class X,
|
Chris@16
|
696 class Y>
|
Chris@16
|
697 struct multiply_typeof_helper< quantity<Unit,X>,Y >
|
Chris@16
|
698 {
|
Chris@16
|
699 typedef typename multiply_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
700 typedef Unit unit_type;
|
Chris@16
|
701 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
702 };
|
Chris@16
|
703
|
Chris@16
|
704 /// disambiguate
|
Chris@16
|
705 /// INTERNAL ONLY
|
Chris@16
|
706 template<class Unit,
|
Chris@16
|
707 class X>
|
Chris@16
|
708 struct multiply_typeof_helper< quantity<Unit,X>,one >
|
Chris@16
|
709 {
|
Chris@16
|
710 typedef quantity<Unit,X> type;
|
Chris@16
|
711 };
|
Chris@16
|
712
|
Chris@16
|
713 /// unit times quantity typeof helper
|
Chris@16
|
714 /// INTERNAL ONLY
|
Chris@16
|
715 template<class Unit,
|
Chris@16
|
716 class System,
|
Chris@16
|
717 class Dim,
|
Chris@16
|
718 class X>
|
Chris@16
|
719 struct multiply_typeof_helper< unit<Dim,System>,quantity<Unit,X> >
|
Chris@16
|
720 {
|
Chris@16
|
721 typedef X value_type;
|
Chris@16
|
722 typedef typename multiply_typeof_helper< unit<Dim,System>,Unit >::type unit_type;
|
Chris@16
|
723 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
724 };
|
Chris@16
|
725
|
Chris@16
|
726 /// quantity times unit typeof helper
|
Chris@16
|
727 /// INTERNAL ONLY
|
Chris@16
|
728 template<class Unit,
|
Chris@16
|
729 class System,
|
Chris@16
|
730 class Dim,
|
Chris@16
|
731 class X>
|
Chris@16
|
732 struct multiply_typeof_helper< quantity<Unit,X>,unit<Dim,System> >
|
Chris@16
|
733 {
|
Chris@16
|
734 typedef X value_type;
|
Chris@16
|
735 typedef typename multiply_typeof_helper< Unit,unit<Dim,System> >::type unit_type;
|
Chris@16
|
736 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
737 };
|
Chris@16
|
738
|
Chris@16
|
739 /// quantity times quantity typeof helper
|
Chris@16
|
740 /// INTERNAL ONLY
|
Chris@16
|
741 template<class Unit1,
|
Chris@16
|
742 class Unit2,
|
Chris@16
|
743 class X,
|
Chris@16
|
744 class Y>
|
Chris@16
|
745 struct multiply_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
|
Chris@16
|
746 {
|
Chris@16
|
747 typedef typename multiply_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
748 typedef typename multiply_typeof_helper<Unit1,Unit2>::type unit_type;
|
Chris@16
|
749 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
750 };
|
Chris@16
|
751
|
Chris@16
|
752 /// scalar divided by unit typeof helper
|
Chris@16
|
753 /// INTERNAL ONLY
|
Chris@16
|
754 template<class System,
|
Chris@16
|
755 class Dim,
|
Chris@16
|
756 class X>
|
Chris@16
|
757 struct divide_typeof_helper< X,unit<Dim,System> >
|
Chris@16
|
758 {
|
Chris@16
|
759 typedef X value_type;
|
Chris@16
|
760 typedef typename power_typeof_helper< unit<Dim,System>,static_rational<-1> >::type unit_type;
|
Chris@16
|
761 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
762 };
|
Chris@16
|
763
|
Chris@16
|
764 /// unit divided by scalar typeof helper
|
Chris@16
|
765 /// INTERNAL ONLY
|
Chris@16
|
766 template<class System,
|
Chris@16
|
767 class Dim,
|
Chris@16
|
768 class X>
|
Chris@16
|
769 struct divide_typeof_helper< unit<Dim,System>,X >
|
Chris@16
|
770 {
|
Chris@16
|
771 typedef typename divide_typeof_helper<X,X>::type value_type;
|
Chris@16
|
772 typedef unit<Dim,System> unit_type;
|
Chris@16
|
773 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
774 };
|
Chris@16
|
775
|
Chris@16
|
776 /// scalar divided by quantity typeof helper
|
Chris@16
|
777 /// INTERNAL ONLY
|
Chris@16
|
778 template<class Unit,
|
Chris@16
|
779 class X,
|
Chris@16
|
780 class Y>
|
Chris@16
|
781 struct divide_typeof_helper< X,quantity<Unit,Y> >
|
Chris@16
|
782 {
|
Chris@16
|
783 typedef typename divide_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
784 typedef typename power_typeof_helper< Unit,static_rational<-1> >::type unit_type;
|
Chris@16
|
785 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
786 };
|
Chris@16
|
787
|
Chris@16
|
788 /// disambiguate
|
Chris@16
|
789 /// INTERNAL ONLY
|
Chris@16
|
790 template<class Unit,
|
Chris@16
|
791 class Y>
|
Chris@16
|
792 struct divide_typeof_helper< one,quantity<Unit,Y> >
|
Chris@16
|
793 {
|
Chris@16
|
794 typedef quantity<Unit,Y> type;
|
Chris@16
|
795 };
|
Chris@16
|
796
|
Chris@16
|
797 /// quantity divided by scalar typeof helper
|
Chris@16
|
798 /// INTERNAL ONLY
|
Chris@16
|
799 template<class Unit,
|
Chris@16
|
800 class X,
|
Chris@16
|
801 class Y>
|
Chris@16
|
802 struct divide_typeof_helper< quantity<Unit,X>,Y >
|
Chris@16
|
803 {
|
Chris@16
|
804 typedef typename divide_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
805 typedef Unit unit_type;
|
Chris@16
|
806 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
807 };
|
Chris@16
|
808
|
Chris@16
|
809 /// disambiguate
|
Chris@16
|
810 /// INTERNAL ONLY
|
Chris@16
|
811 template<class Unit,
|
Chris@16
|
812 class X>
|
Chris@16
|
813 struct divide_typeof_helper< quantity<Unit,X>,one >
|
Chris@16
|
814 {
|
Chris@16
|
815 typedef quantity<Unit,X> type;
|
Chris@16
|
816 };
|
Chris@16
|
817
|
Chris@16
|
818 /// unit divided by quantity typeof helper
|
Chris@16
|
819 /// INTERNAL ONLY
|
Chris@16
|
820 template<class Unit,
|
Chris@16
|
821 class System,
|
Chris@16
|
822 class Dim,
|
Chris@16
|
823 class X>
|
Chris@16
|
824 struct divide_typeof_helper< unit<Dim,System>,quantity<Unit,X> >
|
Chris@16
|
825 {
|
Chris@16
|
826 typedef typename divide_typeof_helper<X,X>::type value_type;
|
Chris@16
|
827 typedef typename divide_typeof_helper< unit<Dim,System>,Unit >::type unit_type;
|
Chris@16
|
828 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
829 };
|
Chris@16
|
830
|
Chris@16
|
831 /// quantity divided by unit typeof helper
|
Chris@16
|
832 /// INTERNAL ONLY
|
Chris@16
|
833 template<class Unit,
|
Chris@16
|
834 class System,
|
Chris@16
|
835 class Dim,
|
Chris@16
|
836 class X>
|
Chris@16
|
837 struct divide_typeof_helper< quantity<Unit,X>,unit<Dim,System> >
|
Chris@16
|
838 {
|
Chris@16
|
839 typedef X value_type;
|
Chris@16
|
840 typedef typename divide_typeof_helper< Unit,unit<Dim,System> >::type unit_type;
|
Chris@16
|
841 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
842 };
|
Chris@16
|
843
|
Chris@16
|
844 /// quantity divided by quantity typeof helper
|
Chris@16
|
845 /// INTERNAL ONLY
|
Chris@16
|
846 template<class Unit1,
|
Chris@16
|
847 class Unit2,
|
Chris@16
|
848 class X,
|
Chris@16
|
849 class Y>
|
Chris@16
|
850 struct divide_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
|
Chris@16
|
851 {
|
Chris@16
|
852 typedef typename divide_typeof_helper<X,Y>::type value_type;
|
Chris@16
|
853 typedef typename divide_typeof_helper<Unit1,Unit2>::type unit_type;
|
Chris@16
|
854 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
855 };
|
Chris@16
|
856
|
Chris@16
|
857 /// specialize power typeof helper
|
Chris@16
|
858 /// INTERNAL ONLY
|
Chris@16
|
859 template<class Unit,long N,long D,class Y>
|
Chris@16
|
860 struct power_typeof_helper< quantity<Unit,Y>,static_rational<N,D> >
|
Chris@16
|
861 {
|
Chris@16
|
862 typedef typename power_typeof_helper<Y,static_rational<N,D> >::type value_type;
|
Chris@16
|
863 typedef typename power_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
|
Chris@16
|
864 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
865
|
Chris@16
|
866 static type value(const quantity<Unit,Y>& x)
|
Chris@16
|
867 {
|
Chris@16
|
868 return type::from_value(power_typeof_helper<Y,static_rational<N,D> >::value(x.value()));
|
Chris@16
|
869 }
|
Chris@16
|
870 };
|
Chris@16
|
871
|
Chris@16
|
872 /// specialize root typeof helper
|
Chris@16
|
873 /// INTERNAL ONLY
|
Chris@16
|
874 template<class Unit,long N,long D,class Y>
|
Chris@16
|
875 struct root_typeof_helper< quantity<Unit,Y>,static_rational<N,D> >
|
Chris@16
|
876 {
|
Chris@16
|
877 typedef typename root_typeof_helper<Y,static_rational<N,D> >::type value_type;
|
Chris@16
|
878 typedef typename root_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
|
Chris@16
|
879 typedef quantity<unit_type,value_type> type;
|
Chris@16
|
880
|
Chris@16
|
881 static type value(const quantity<Unit,Y>& x)
|
Chris@16
|
882 {
|
Chris@16
|
883 return type::from_value(root_typeof_helper<Y,static_rational<N,D> >::value(x.value()));
|
Chris@16
|
884 }
|
Chris@16
|
885 };
|
Chris@16
|
886
|
Chris@16
|
887 /// runtime unit times scalar
|
Chris@16
|
888 /// INTERNAL ONLY
|
Chris@16
|
889 template<class System,
|
Chris@16
|
890 class Dim,
|
Chris@16
|
891 class Y>
|
Chris@16
|
892 inline
|
Chris@16
|
893 typename multiply_typeof_helper< unit<Dim,System>,Y >::type
|
Chris@16
|
894 operator*(const unit<Dim,System>&,const Y& rhs)
|
Chris@16
|
895 {
|
Chris@16
|
896 typedef typename multiply_typeof_helper< unit<Dim,System>,Y >::type type;
|
Chris@16
|
897
|
Chris@16
|
898 return type::from_value(rhs);
|
Chris@16
|
899 }
|
Chris@16
|
900
|
Chris@16
|
901 /// runtime unit divided by scalar
|
Chris@16
|
902 template<class System,
|
Chris@16
|
903 class Dim,
|
Chris@16
|
904 class Y>
|
Chris@16
|
905 inline
|
Chris@16
|
906 typename divide_typeof_helper< unit<Dim,System>,Y >::type
|
Chris@16
|
907 operator/(const unit<Dim,System>&,const Y& rhs)
|
Chris@16
|
908 {
|
Chris@16
|
909 typedef typename divide_typeof_helper<unit<Dim,System>,Y>::type type;
|
Chris@16
|
910
|
Chris@16
|
911 return type::from_value(Y(1)/rhs);
|
Chris@16
|
912 }
|
Chris@16
|
913
|
Chris@16
|
914 /// runtime scalar times unit
|
Chris@16
|
915 template<class System,
|
Chris@16
|
916 class Dim,
|
Chris@16
|
917 class Y>
|
Chris@16
|
918 inline
|
Chris@16
|
919 typename multiply_typeof_helper< Y,unit<Dim,System> >::type
|
Chris@16
|
920 operator*(const Y& lhs,const unit<Dim,System>&)
|
Chris@16
|
921 {
|
Chris@16
|
922 typedef typename multiply_typeof_helper< Y,unit<Dim,System> >::type type;
|
Chris@16
|
923
|
Chris@16
|
924 return type::from_value(lhs);
|
Chris@16
|
925 }
|
Chris@16
|
926
|
Chris@16
|
927 /// runtime scalar divided by unit
|
Chris@16
|
928 template<class System,
|
Chris@16
|
929 class Dim,
|
Chris@16
|
930 class Y>
|
Chris@16
|
931 inline
|
Chris@16
|
932 typename divide_typeof_helper< Y,unit<Dim,System> >::type
|
Chris@16
|
933 operator/(const Y& lhs,const unit<Dim,System>&)
|
Chris@16
|
934 {
|
Chris@16
|
935 typedef typename divide_typeof_helper< Y,unit<Dim,System> >::type type;
|
Chris@16
|
936
|
Chris@16
|
937 return type::from_value(lhs);
|
Chris@16
|
938 }
|
Chris@16
|
939
|
Chris@16
|
940 ///// runtime quantity times scalar
|
Chris@16
|
941 //template<class Unit,
|
Chris@16
|
942 // class X,
|
Chris@16
|
943 // class Y>
|
Chris@16
|
944 //inline
|
Chris@16
|
945 //typename multiply_typeof_helper< quantity<Unit,X>,Y >::type
|
Chris@16
|
946 //operator*(const quantity<Unit,X>& lhs,const Y& rhs)
|
Chris@16
|
947 //{
|
Chris@16
|
948 // typedef typename multiply_typeof_helper< quantity<Unit,X>,Y >::type type;
|
Chris@16
|
949 //
|
Chris@16
|
950 // return type::from_value(lhs.value()*rhs);
|
Chris@16
|
951 //}
|
Chris@16
|
952 //
|
Chris@16
|
953 ///// runtime scalar times quantity
|
Chris@16
|
954 //template<class Unit,
|
Chris@16
|
955 // class X,
|
Chris@16
|
956 // class Y>
|
Chris@16
|
957 //inline
|
Chris@16
|
958 //typename multiply_typeof_helper< X,quantity<Unit,Y> >::type
|
Chris@16
|
959 //operator*(const X& lhs,const quantity<Unit,Y>& rhs)
|
Chris@16
|
960 //{
|
Chris@16
|
961 // typedef typename multiply_typeof_helper< X,quantity<Unit,Y> >::type type;
|
Chris@16
|
962 //
|
Chris@16
|
963 // return type::from_value(lhs*rhs.value());
|
Chris@16
|
964 //}
|
Chris@16
|
965
|
Chris@16
|
966 /// runtime quantity times scalar
|
Chris@16
|
967 template<class Unit,
|
Chris@16
|
968 class X>
|
Chris@16
|
969 inline
|
Chris@16
|
970 typename multiply_typeof_helper< quantity<Unit,X>,X >::type
|
Chris@16
|
971 operator*(const quantity<Unit,X>& lhs,const X& rhs)
|
Chris@16
|
972 {
|
Chris@16
|
973 typedef typename multiply_typeof_helper< quantity<Unit,X>,X >::type type;
|
Chris@16
|
974
|
Chris@16
|
975 return type::from_value(lhs.value()*rhs);
|
Chris@16
|
976 }
|
Chris@16
|
977
|
Chris@16
|
978 /// runtime scalar times quantity
|
Chris@16
|
979 template<class Unit,
|
Chris@16
|
980 class X>
|
Chris@16
|
981 inline
|
Chris@16
|
982 typename multiply_typeof_helper< X,quantity<Unit,X> >::type
|
Chris@16
|
983 operator*(const X& lhs,const quantity<Unit,X>& rhs)
|
Chris@16
|
984 {
|
Chris@16
|
985 typedef typename multiply_typeof_helper< X,quantity<Unit,X> >::type type;
|
Chris@16
|
986
|
Chris@16
|
987 return type::from_value(lhs*rhs.value());
|
Chris@16
|
988 }
|
Chris@16
|
989
|
Chris@16
|
990 ///// runtime quantity divided by scalar
|
Chris@16
|
991 //template<class Unit,
|
Chris@16
|
992 // class X,
|
Chris@16
|
993 // class Y>
|
Chris@16
|
994 //inline
|
Chris@16
|
995 //typename divide_typeof_helper< quantity<Unit,X>,Y >::type
|
Chris@16
|
996 //operator/(const quantity<Unit,X>& lhs,const Y& rhs)
|
Chris@16
|
997 //{
|
Chris@16
|
998 // typedef typename divide_typeof_helper< quantity<Unit,X>,Y >::type type;
|
Chris@16
|
999 //
|
Chris@16
|
1000 // return type::from_value(lhs.value()/rhs);
|
Chris@16
|
1001 //}
|
Chris@16
|
1002 //
|
Chris@16
|
1003 ///// runtime scalar divided by quantity
|
Chris@16
|
1004 //template<class Unit,
|
Chris@16
|
1005 // class X,
|
Chris@16
|
1006 // class Y>
|
Chris@16
|
1007 //inline
|
Chris@16
|
1008 //typename divide_typeof_helper< X,quantity<Unit,Y> >::type
|
Chris@16
|
1009 //operator/(const X& lhs,const quantity<Unit,Y>& rhs)
|
Chris@16
|
1010 //{
|
Chris@16
|
1011 // typedef typename divide_typeof_helper< X,quantity<Unit,Y> >::type type;
|
Chris@16
|
1012 //
|
Chris@16
|
1013 // return type::from_value(lhs/rhs.value());
|
Chris@16
|
1014 //}
|
Chris@16
|
1015
|
Chris@16
|
1016 /// runtime quantity divided by scalar
|
Chris@16
|
1017 template<class Unit,
|
Chris@16
|
1018 class X>
|
Chris@16
|
1019 inline
|
Chris@16
|
1020 typename divide_typeof_helper< quantity<Unit,X>,X >::type
|
Chris@16
|
1021 operator/(const quantity<Unit,X>& lhs,const X& rhs)
|
Chris@16
|
1022 {
|
Chris@16
|
1023 typedef typename divide_typeof_helper< quantity<Unit,X>,X >::type type;
|
Chris@16
|
1024
|
Chris@16
|
1025 return type::from_value(lhs.value()/rhs);
|
Chris@16
|
1026 }
|
Chris@16
|
1027
|
Chris@16
|
1028 /// runtime scalar divided by quantity
|
Chris@16
|
1029 template<class Unit,
|
Chris@16
|
1030 class X>
|
Chris@16
|
1031 inline
|
Chris@16
|
1032 typename divide_typeof_helper< X,quantity<Unit,X> >::type
|
Chris@16
|
1033 operator/(const X& lhs,const quantity<Unit,X>& rhs)
|
Chris@16
|
1034 {
|
Chris@16
|
1035 typedef typename divide_typeof_helper< X,quantity<Unit,X> >::type type;
|
Chris@16
|
1036
|
Chris@16
|
1037 return type::from_value(lhs/rhs.value());
|
Chris@16
|
1038 }
|
Chris@16
|
1039
|
Chris@16
|
1040 /// runtime unit times quantity
|
Chris@16
|
1041 template<class System1,
|
Chris@16
|
1042 class Dim1,
|
Chris@16
|
1043 class Unit2,
|
Chris@16
|
1044 class Y>
|
Chris@16
|
1045 inline
|
Chris@16
|
1046 typename multiply_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type
|
Chris@16
|
1047 operator*(const unit<Dim1,System1>&,const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1048 {
|
Chris@16
|
1049 typedef typename multiply_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type type;
|
Chris@16
|
1050
|
Chris@16
|
1051 return type::from_value(rhs.value());
|
Chris@16
|
1052 }
|
Chris@16
|
1053
|
Chris@16
|
1054 /// runtime unit divided by quantity
|
Chris@16
|
1055 template<class System1,
|
Chris@16
|
1056 class Dim1,
|
Chris@16
|
1057 class Unit2,
|
Chris@16
|
1058 class Y>
|
Chris@16
|
1059 inline
|
Chris@16
|
1060 typename divide_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type
|
Chris@16
|
1061 operator/(const unit<Dim1,System1>&,const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1062 {
|
Chris@16
|
1063 typedef typename divide_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type type;
|
Chris@16
|
1064
|
Chris@16
|
1065 return type::from_value(Y(1)/rhs.value());
|
Chris@16
|
1066 }
|
Chris@16
|
1067
|
Chris@16
|
1068 /// runtime quantity times unit
|
Chris@16
|
1069 template<class Unit1,
|
Chris@16
|
1070 class System2,
|
Chris@16
|
1071 class Dim2,
|
Chris@16
|
1072 class Y>
|
Chris@16
|
1073 inline
|
Chris@16
|
1074 typename multiply_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type
|
Chris@16
|
1075 operator*(const quantity<Unit1,Y>& lhs,const unit<Dim2,System2>&)
|
Chris@16
|
1076 {
|
Chris@16
|
1077 typedef typename multiply_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type type;
|
Chris@16
|
1078
|
Chris@16
|
1079 return type::from_value(lhs.value());
|
Chris@16
|
1080 }
|
Chris@16
|
1081
|
Chris@16
|
1082 /// runtime quantity divided by unit
|
Chris@16
|
1083 template<class Unit1,
|
Chris@16
|
1084 class System2,
|
Chris@16
|
1085 class Dim2,
|
Chris@16
|
1086 class Y>
|
Chris@16
|
1087 inline
|
Chris@16
|
1088 typename divide_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type
|
Chris@16
|
1089 operator/(const quantity<Unit1,Y>& lhs,const unit<Dim2,System2>&)
|
Chris@16
|
1090 {
|
Chris@16
|
1091 typedef typename divide_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type type;
|
Chris@16
|
1092
|
Chris@16
|
1093 return type::from_value(lhs.value());
|
Chris@16
|
1094 }
|
Chris@16
|
1095
|
Chris@16
|
1096 /// runtime unary plus quantity
|
Chris@16
|
1097 template<class Unit,class Y>
|
Chris@16
|
1098 typename unary_plus_typeof_helper< quantity<Unit,Y> >::type
|
Chris@16
|
1099 operator+(const quantity<Unit,Y>& val)
|
Chris@16
|
1100 {
|
Chris@16
|
1101 typedef typename unary_plus_typeof_helper< quantity<Unit,Y> >::type type;
|
Chris@16
|
1102
|
Chris@16
|
1103 return type::from_value(+val.value());
|
Chris@16
|
1104 }
|
Chris@16
|
1105
|
Chris@16
|
1106 /// runtime unary minus quantity
|
Chris@16
|
1107 template<class Unit,class Y>
|
Chris@16
|
1108 typename unary_minus_typeof_helper< quantity<Unit,Y> >::type
|
Chris@16
|
1109 operator-(const quantity<Unit,Y>& val)
|
Chris@16
|
1110 {
|
Chris@16
|
1111 typedef typename unary_minus_typeof_helper< quantity<Unit,Y> >::type type;
|
Chris@16
|
1112
|
Chris@16
|
1113 return type::from_value(-val.value());
|
Chris@16
|
1114 }
|
Chris@16
|
1115
|
Chris@16
|
1116 /// runtime quantity plus quantity
|
Chris@16
|
1117 template<class Unit1,
|
Chris@16
|
1118 class Unit2,
|
Chris@16
|
1119 class X,
|
Chris@16
|
1120 class Y>
|
Chris@16
|
1121 inline
|
Chris@16
|
1122 typename add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
|
Chris@16
|
1123 operator+(const quantity<Unit1,X>& lhs,
|
Chris@16
|
1124 const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1125 {
|
Chris@16
|
1126 typedef typename add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type type;
|
Chris@16
|
1127
|
Chris@16
|
1128 return type::from_value(lhs.value()+rhs.value());
|
Chris@16
|
1129 }
|
Chris@16
|
1130
|
Chris@16
|
1131 /// runtime quantity minus quantity
|
Chris@16
|
1132 template<class Unit1,
|
Chris@16
|
1133 class Unit2,
|
Chris@16
|
1134 class X,
|
Chris@16
|
1135 class Y>
|
Chris@16
|
1136 inline
|
Chris@16
|
1137 typename subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
|
Chris@16
|
1138 operator-(const quantity<Unit1,X>& lhs,
|
Chris@16
|
1139 const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1140 {
|
Chris@16
|
1141 typedef typename subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type type;
|
Chris@16
|
1142
|
Chris@16
|
1143 return type::from_value(lhs.value()-rhs.value());
|
Chris@16
|
1144 }
|
Chris@16
|
1145
|
Chris@16
|
1146 /// runtime quantity times quantity
|
Chris@16
|
1147 template<class Unit1,
|
Chris@16
|
1148 class Unit2,
|
Chris@16
|
1149 class X,
|
Chris@16
|
1150 class Y>
|
Chris@16
|
1151 inline
|
Chris@16
|
1152 typename multiply_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
|
Chris@16
|
1153 operator*(const quantity<Unit1,X>& lhs,
|
Chris@16
|
1154 const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1155 {
|
Chris@16
|
1156 typedef typename multiply_typeof_helper< quantity<Unit1,X>,
|
Chris@16
|
1157 quantity<Unit2,Y> >::type type;
|
Chris@16
|
1158
|
Chris@16
|
1159 return type::from_value(lhs.value()*rhs.value());
|
Chris@16
|
1160 }
|
Chris@16
|
1161
|
Chris@16
|
1162 /// runtime quantity divided by quantity
|
Chris@16
|
1163 template<class Unit1,
|
Chris@16
|
1164 class Unit2,
|
Chris@16
|
1165 class X,
|
Chris@16
|
1166 class Y>
|
Chris@16
|
1167 inline
|
Chris@16
|
1168 typename divide_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
|
Chris@16
|
1169 operator/(const quantity<Unit1,X>& lhs,
|
Chris@16
|
1170 const quantity<Unit2,Y>& rhs)
|
Chris@16
|
1171 {
|
Chris@16
|
1172 typedef typename divide_typeof_helper< quantity<Unit1,X>,
|
Chris@16
|
1173 quantity<Unit2,Y> >::type type;
|
Chris@16
|
1174
|
Chris@16
|
1175 return type::from_value(lhs.value()/rhs.value());
|
Chris@16
|
1176 }
|
Chris@16
|
1177
|
Chris@16
|
1178 /// runtime operator==
|
Chris@16
|
1179 template<class Unit,
|
Chris@16
|
1180 class X,
|
Chris@16
|
1181 class Y>
|
Chris@16
|
1182 inline
|
Chris@16
|
1183 bool
|
Chris@16
|
1184 operator==(const quantity<Unit,X>& val1,
|
Chris@16
|
1185 const quantity<Unit,Y>& val2)
|
Chris@16
|
1186 {
|
Chris@16
|
1187 return val1.value() == val2.value();
|
Chris@16
|
1188 }
|
Chris@16
|
1189
|
Chris@16
|
1190 /// runtime operator!=
|
Chris@16
|
1191 template<class Unit,
|
Chris@16
|
1192 class X,
|
Chris@16
|
1193 class Y>
|
Chris@16
|
1194 inline
|
Chris@16
|
1195 bool
|
Chris@16
|
1196 operator!=(const quantity<Unit,X>& val1,
|
Chris@16
|
1197 const quantity<Unit,Y>& val2)
|
Chris@16
|
1198 {
|
Chris@16
|
1199 return val1.value() != val2.value();
|
Chris@16
|
1200 }
|
Chris@16
|
1201
|
Chris@16
|
1202 /// runtime operator<
|
Chris@16
|
1203 template<class Unit,
|
Chris@16
|
1204 class X,
|
Chris@16
|
1205 class Y>
|
Chris@16
|
1206 inline
|
Chris@16
|
1207 bool
|
Chris@16
|
1208 operator<(const quantity<Unit,X>& val1,
|
Chris@16
|
1209 const quantity<Unit,Y>& val2)
|
Chris@16
|
1210 {
|
Chris@16
|
1211 return val1.value() < val2.value();
|
Chris@16
|
1212 }
|
Chris@16
|
1213
|
Chris@16
|
1214 /// runtime operator<=
|
Chris@16
|
1215 template<class Unit,
|
Chris@16
|
1216 class X,
|
Chris@16
|
1217 class Y>
|
Chris@16
|
1218 inline
|
Chris@16
|
1219 bool
|
Chris@16
|
1220 operator<=(const quantity<Unit,X>& val1,
|
Chris@16
|
1221 const quantity<Unit,Y>& val2)
|
Chris@16
|
1222 {
|
Chris@16
|
1223 return val1.value() <= val2.value();
|
Chris@16
|
1224 }
|
Chris@16
|
1225
|
Chris@16
|
1226 /// runtime operator>
|
Chris@16
|
1227 template<class Unit,
|
Chris@16
|
1228 class X,
|
Chris@16
|
1229 class Y>
|
Chris@16
|
1230 inline
|
Chris@16
|
1231 bool
|
Chris@16
|
1232 operator>(const quantity<Unit,X>& val1,
|
Chris@16
|
1233 const quantity<Unit,Y>& val2)
|
Chris@16
|
1234 {
|
Chris@16
|
1235 return val1.value() > val2.value();
|
Chris@16
|
1236 }
|
Chris@16
|
1237
|
Chris@16
|
1238 /// runtime operator>=
|
Chris@16
|
1239 template<class Unit,
|
Chris@16
|
1240 class X,
|
Chris@16
|
1241 class Y>
|
Chris@16
|
1242 inline
|
Chris@16
|
1243 bool
|
Chris@16
|
1244 operator>=(const quantity<Unit,X>& val1,
|
Chris@16
|
1245 const quantity<Unit,Y>& val2)
|
Chris@16
|
1246 {
|
Chris@16
|
1247 return val1.value() >= val2.value();
|
Chris@16
|
1248 }
|
Chris@16
|
1249
|
Chris@16
|
1250 } // namespace units
|
Chris@16
|
1251
|
Chris@16
|
1252 } // namespace boost
|
Chris@16
|
1253
|
Chris@16
|
1254 #endif // BOOST_UNITS_QUANTITY_HPP
|