the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1254 lines 41 kB view raw
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 37namespace boost { 38 39namespace units { 40 41namespace detail { 42 43template<class T, class Enable = void> 44struct is_base_unit : mpl::false_ {}; 45 46template<class T> 47struct is_base_unit<T, typename T::boost_units_is_base_unit_type> : mpl::true_ {}; 48 49template<class Source, class Destination> 50struct is_narrowing_conversion_impl : mpl::bool_<(sizeof(Source) > sizeof(Destination))> {}; 51 52template<class Source, class Destination> 53struct 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 72template<> 73struct is_non_narrowing_conversion<long double, double> : mpl::false_ {}; 74 75// msvc 7.1 needs extra disambiguation 76template<class T, class U> 77struct disable_if_is_same 78{ 79 typedef void type; 80}; 81 82template<class T> 83struct disable_if_is_same<T, T> {}; 84 85} 86 87/// class declaration 88template<class Unit,class Y = double> 89class 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. 297template<class System,class Y> 298class 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 483template<class System, class T> 484class quantity<unit<int, System>, T> {}; 485template<class T> 486class 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 497BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::quantity, 2) 498 499#endif 500 501namespace boost { 502 503namespace units { 504 505namespace detail { 506 507/// helper class for quantity_cast 508template<class X,class Y> struct quantity_cast_helper; 509 510/// specialization for casting to the value type 511template<class Y,class X,class Unit> 512struct 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 520template<class Y,class X,class Unit> 521struct 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 531template<class X,class Y> 532inline 533X 534quantity_cast(Y& source) 535{ 536 detail::quantity_cast_helper<X,Y> qch; 537 538 return qch(source); 539} 540 541template<class X,class Y> 542inline 543X 544quantity_cast(const Y& source) 545{ 546 detail::quantity_cast_helper<X,const Y> qch; 547 548 return qch(source); 549} 550 551/// swap quantities 552template<class Unit,class Y> 553inline 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 561template<class Unit,class Y> 562struct 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 571template<class Unit,class Y> 572struct 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 581template<class Unit1, 582 class Unit2, 583 class X, 584 class Y> 585struct 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. 595template<class Dim1, class System1, 596 class Dim2, class System2, 597 class X, 598 class Y> 599struct add_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> > 600{ 601}; 602 603template<class Dim, 604 class System, 605 class X, 606 class Y> 607struct 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 616template<class Unit1, 617 class Unit2, 618 class X, 619 class Y> 620struct 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. 628template<class Dim1, class System1, 629 class Dim2, class System2, 630 class X, 631 class Y> 632struct subtract_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> > 633{ 634}; 635 636template<class Dim, 637 class System, 638 class X, 639 class Y> 640struct 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 649template<class System, 650 class Dim, 651 class X> 652struct 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 661template<class System, 662 class Dim, 663 class X> 664struct 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 673template<class Unit, 674 class X, 675 class Y> 676struct 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 685template<class Unit, 686 class Y> 687struct 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 694template<class Unit, 695 class X, 696 class Y> 697struct 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 706template<class Unit, 707 class X> 708struct 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 715template<class Unit, 716 class System, 717 class Dim, 718 class X> 719struct 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 728template<class Unit, 729 class System, 730 class Dim, 731 class X> 732struct 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 741template<class Unit1, 742 class Unit2, 743 class X, 744 class Y> 745struct 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 754template<class System, 755 class Dim, 756 class X> 757struct 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 766template<class System, 767 class Dim, 768 class X> 769struct 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 778template<class Unit, 779 class X, 780 class Y> 781struct 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 790template<class Unit, 791 class Y> 792struct 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 799template<class Unit, 800 class X, 801 class Y> 802struct 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 811template<class Unit, 812 class X> 813struct 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 820template<class Unit, 821 class System, 822 class Dim, 823 class X> 824struct 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 833template<class Unit, 834 class System, 835 class Dim, 836 class X> 837struct 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 846template<class Unit1, 847 class Unit2, 848 class X, 849 class Y> 850struct 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 859template<class Unit,long N,long D,class Y> 860struct 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 874template<class Unit,long N,long D,class Y> 875struct 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 889template<class System, 890 class Dim, 891 class Y> 892inline 893typename multiply_typeof_helper< unit<Dim,System>,Y >::type 894operator*(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 902template<class System, 903 class Dim, 904 class Y> 905inline 906typename divide_typeof_helper< unit<Dim,System>,Y >::type 907operator/(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 915template<class System, 916 class Dim, 917 class Y> 918inline 919typename multiply_typeof_helper< Y,unit<Dim,System> >::type 920operator*(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 928template<class System, 929 class Dim, 930 class Y> 931inline 932typename divide_typeof_helper< Y,unit<Dim,System> >::type 933operator/(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 967template<class Unit, 968 class X> 969inline 970typename multiply_typeof_helper< quantity<Unit,X>,X >::type 971operator*(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 979template<class Unit, 980 class X> 981inline 982typename multiply_typeof_helper< X,quantity<Unit,X> >::type 983operator*(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 1017template<class Unit, 1018 class X> 1019inline 1020typename divide_typeof_helper< quantity<Unit,X>,X >::type 1021operator/(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 1029template<class Unit, 1030 class X> 1031inline 1032typename divide_typeof_helper< X,quantity<Unit,X> >::type 1033operator/(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 1041template<class System1, 1042 class Dim1, 1043 class Unit2, 1044 class Y> 1045inline 1046typename multiply_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type 1047operator*(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 1055template<class System1, 1056 class Dim1, 1057 class Unit2, 1058 class Y> 1059inline 1060typename divide_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type 1061operator/(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 1069template<class Unit1, 1070 class System2, 1071 class Dim2, 1072 class Y> 1073inline 1074typename multiply_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type 1075operator*(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 1083template<class Unit1, 1084 class System2, 1085 class Dim2, 1086 class Y> 1087inline 1088typename divide_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type 1089operator/(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 1097template<class Unit,class Y> 1098typename unary_plus_typeof_helper< quantity<Unit,Y> >::type 1099operator+(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 1107template<class Unit,class Y> 1108typename unary_minus_typeof_helper< quantity<Unit,Y> >::type 1109operator-(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 1117template<class Unit1, 1118 class Unit2, 1119 class X, 1120 class Y> 1121inline 1122typename add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type 1123operator+(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 1132template<class Unit1, 1133 class Unit2, 1134 class X, 1135 class Y> 1136inline 1137typename subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type 1138operator-(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 1147template<class Unit1, 1148 class Unit2, 1149 class X, 1150 class Y> 1151inline 1152typename multiply_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type 1153operator*(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 1163template<class Unit1, 1164 class Unit2, 1165 class X, 1166 class Y> 1167inline 1168typename divide_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type 1169operator/(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== 1179template<class Unit, 1180 class X, 1181 class Y> 1182inline 1183bool 1184operator==(const quantity<Unit,X>& val1, 1185 const quantity<Unit,Y>& val2) 1186{ 1187 return val1.value() == val2.value(); 1188} 1189 1190/// runtime operator!= 1191template<class Unit, 1192 class X, 1193 class Y> 1194inline 1195bool 1196operator!=(const quantity<Unit,X>& val1, 1197 const quantity<Unit,Y>& val2) 1198{ 1199 return val1.value() != val2.value(); 1200} 1201 1202/// runtime operator< 1203template<class Unit, 1204 class X, 1205 class Y> 1206inline 1207bool 1208operator<(const quantity<Unit,X>& val1, 1209 const quantity<Unit,Y>& val2) 1210{ 1211 return val1.value() < val2.value(); 1212} 1213 1214/// runtime operator<= 1215template<class Unit, 1216 class X, 1217 class Y> 1218inline 1219bool 1220operator<=(const quantity<Unit,X>& val1, 1221 const quantity<Unit,Y>& val2) 1222{ 1223 return val1.value() <= val2.value(); 1224} 1225 1226/// runtime operator> 1227template<class Unit, 1228 class X, 1229 class Y> 1230inline 1231bool 1232operator>(const quantity<Unit,X>& val1, 1233 const quantity<Unit,Y>& val2) 1234{ 1235 return val1.value() > val2.value(); 1236} 1237 1238/// runtime operator>= 1239template<class Unit, 1240 class X, 1241 class Y> 1242inline 1243bool 1244operator>=(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