annotate DEPENDENCIES/generic/include/boost/units/quantity.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
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