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