Warning, file /include/boost/units/quantity.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_QUANTITY_HPP
0012 #define BOOST_UNITS_QUANTITY_HPP
0013
0014 #include <algorithm>
0015
0016 #include <boost/config.hpp>
0017 #include <boost/static_assert.hpp>
0018 #include <boost/mpl/bool.hpp>
0019 #include <boost/mpl/and.hpp>
0020 #include <boost/mpl/not.hpp>
0021 #include <boost/mpl/or.hpp>
0022 #include <boost/mpl/assert.hpp>
0023 #include <boost/utility/enable_if.hpp>
0024 #include <boost/type_traits/is_arithmetic.hpp>
0025 #include <boost/type_traits/is_convertible.hpp>
0026 #include <boost/type_traits/is_integral.hpp>
0027 #include <boost/type_traits/is_same.hpp>
0028
0029 #include <boost/units/conversion.hpp>
0030 #include <boost/units/dimensionless_type.hpp>
0031 #include <boost/units/homogeneous_system.hpp>
0032 #include <boost/units/operators.hpp>
0033 #include <boost/units/static_rational.hpp>
0034 #include <boost/units/units_fwd.hpp>
0035 #include <boost/units/detail/dimensionless_unit.hpp>
0036
0037 namespace boost {
0038
0039 namespace units {
0040
0041 namespace detail {
0042
0043 template<class T, class Enable = void>
0044 struct is_base_unit : mpl::false_ {};
0045
0046 template<class T>
0047 struct is_base_unit<T, typename T::boost_units_is_base_unit_type> : mpl::true_ {};
0048
0049 template<class Source, class Destination>
0050 struct is_narrowing_conversion_impl : mpl::bool_<(sizeof(Source) > sizeof(Destination))> {};
0051
0052 template<class Source, class Destination>
0053 struct is_non_narrowing_conversion :
0054 mpl::and_<
0055 boost::is_convertible<Source, Destination>,
0056 mpl::not_<
0057 mpl::and_<
0058 boost::is_arithmetic<Source>,
0059 boost::is_arithmetic<Destination>,
0060 mpl::or_<
0061 mpl::and_<
0062 is_integral<Destination>,
0063 mpl::not_<is_integral<Source> >
0064 >,
0065 is_narrowing_conversion_impl<Source, Destination>
0066 >
0067 >
0068 >
0069 >
0070 {};
0071
0072 template<>
0073 struct is_non_narrowing_conversion<long double, double> : mpl::false_ {};
0074
0075
0076 template<class T, class U>
0077 struct disable_if_is_same
0078 {
0079 typedef void type;
0080 };
0081
0082 template<class T>
0083 struct disable_if_is_same<T, T> {};
0084
0085 }
0086
0087
0088 template<class Unit,class Y>
0089 class quantity
0090 {
0091
0092 BOOST_MPL_ASSERT_NOT((detail::is_base_unit<Unit>));
0093 enum { force_instantiation_of_unit = sizeof(Unit) };
0094 typedef void (quantity::*unspecified_null_pointer_constant_type)(int*******);
0095 public:
0096 typedef quantity<Unit,Y> this_type;
0097
0098 typedef Y value_type;
0099 typedef Unit unit_type;
0100
0101 BOOST_CONSTEXPR quantity() : val_()
0102 {
0103 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0104 }
0105
0106 BOOST_CONSTEXPR quantity(unspecified_null_pointer_constant_type) : val_()
0107 {
0108 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0109 }
0110
0111 BOOST_CONSTEXPR quantity(const this_type& source) : val_(source.val_)
0112 {
0113 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0114 }
0115
0116
0117
0118
0119 #ifdef __SUNPRO_CC
0120 ~quantity() {
0121 unit_type force_unit_instantiation;
0122 }
0123 #endif
0124
0125
0126
0127 BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type& source)
0128 {
0129 val_ = source.val_;
0130
0131 return *this;
0132 }
0133
0134 #ifndef BOOST_NO_SFINAE
0135
0136
0137 template<class YY>
0138 BOOST_CONSTEXPR quantity(const quantity<Unit,YY>& source,
0139 typename boost::enable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
0140 val_(source.value())
0141 {
0142 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0143 }
0144
0145
0146 template<class YY>
0147 explicit BOOST_CONSTEXPR quantity(const quantity<Unit,YY>& source,
0148 typename boost::disable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
0149 val_(static_cast<Y>(source.value()))
0150 {
0151 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0152 }
0153
0154 #else
0155
0156
0157 template<class YY>
0158 BOOST_CONSTEXPR quantity(const quantity<Unit,YY>& source) :
0159 val_(source.value())
0160 {
0161 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0162 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
0163 }
0164
0165 #endif
0166
0167
0168 template<class YY>
0169 BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity<Unit,YY>& source)
0170 {
0171 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
0172
0173 *this = this_type(source);
0174
0175 return *this;
0176 }
0177
0178 #ifndef BOOST_NO_SFINAE
0179
0180
0181 template<class Unit2,class YY>
0182 explicit
0183 BOOST_CONSTEXPR quantity(const quantity<Unit2,YY>& source,
0184 typename boost::disable_if<
0185 mpl::and_<
0186
0187
0188 typename is_implicitly_convertible<Unit2,Unit>::type,
0189 detail::is_non_narrowing_conversion<YY, Y>
0190 >,
0191 typename detail::disable_if_is_same<Unit, Unit2>::type
0192 >::type* = 0)
0193 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
0194 {
0195 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0196 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
0197 }
0198
0199
0200 template<class Unit2,class YY>
0201 BOOST_CONSTEXPR quantity(const quantity<Unit2,YY>& source,
0202 typename boost::enable_if<
0203 mpl::and_<
0204 typename is_implicitly_convertible<Unit2,Unit>::type,
0205 detail::is_non_narrowing_conversion<YY, Y>
0206 >,
0207 typename detail::disable_if_is_same<Unit, Unit2>::type
0208 >::type* = 0)
0209 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
0210 {
0211 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0212 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
0213 }
0214
0215 #else
0216
0217
0218
0219 template<class Unit2,class YY>
0220 explicit BOOST_CONSTEXPR quantity(const quantity<Unit2,YY>& source)
0221 : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
0222 {
0223 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0224 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
0225 }
0226
0227 #endif
0228
0229
0230 template<class Unit2,class YY>
0231 BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity<Unit2,YY>& source)
0232 {
0233
0234 BOOST_STATIC_ASSERT((is_implicitly_convertible<Unit2,unit_type>::value == true));
0235 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
0236
0237 *this = this_type(source);
0238
0239 return *this;
0240 }
0241
0242 BOOST_CONSTEXPR const value_type& value() const { return val_; }
0243
0244
0245 template<class Unit2, class YY>
0246 BOOST_CXX14_CONSTEXPR this_type& operator+=(const quantity<Unit2, YY>& source)
0247 {
0248 BOOST_STATIC_ASSERT((boost::is_same<typename add_typeof_helper<Unit, Unit2>::type, Unit>::value));
0249 val_ += source.value();
0250 return *this;
0251 }
0252
0253
0254 template<class Unit2, class YY>
0255 BOOST_CXX14_CONSTEXPR this_type& operator-=(const quantity<Unit2, YY>& source)
0256 {
0257 BOOST_STATIC_ASSERT((boost::is_same<typename subtract_typeof_helper<Unit, Unit2>::type, Unit>::value));
0258 val_ -= source.value();
0259 return *this;
0260 }
0261
0262 template<class Unit2, class YY>
0263 BOOST_CXX14_CONSTEXPR this_type& operator*=(const quantity<Unit2, YY>& source)
0264 {
0265 BOOST_STATIC_ASSERT((boost::is_same<typename multiply_typeof_helper<Unit, Unit2>::type, Unit>::value));
0266 val_ *= source.value();
0267 return *this;
0268 }
0269
0270 template<class Unit2, class YY>
0271 BOOST_CXX14_CONSTEXPR this_type& operator/=(const quantity<Unit2, YY>& source)
0272 {
0273 BOOST_STATIC_ASSERT((boost::is_same<typename divide_typeof_helper<Unit, Unit2>::type, Unit>::value));
0274 val_ /= source.value();
0275 return *this;
0276 }
0277
0278
0279 BOOST_CXX14_CONSTEXPR this_type& operator*=(const value_type& source) { val_ *= source; return *this; }
0280
0281 BOOST_CXX14_CONSTEXPR this_type& operator/=(const value_type& source) { val_ /= source; return *this; }
0282
0283
0284 static BOOST_CONSTEXPR this_type from_value(const value_type& val) { return this_type(val, 0); }
0285
0286 protected:
0287 explicit BOOST_CONSTEXPR quantity(const value_type& val, int) : val_(val) { }
0288
0289 private:
0290 value_type val_;
0291 };
0292
0293
0294
0295
0296
0297 template<class System,class Y>
0298 class quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System),Y>
0299 {
0300 public:
0301 typedef quantity<unit<dimensionless_type,System>,Y> this_type;
0302
0303 typedef Y value_type;
0304 typedef System system_type;
0305 typedef dimensionless_type dimension_type;
0306 typedef unit<dimension_type,system_type> unit_type;
0307
0308 BOOST_CONSTEXPR quantity() : val_()
0309 {
0310 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0311 }
0312
0313
0314 BOOST_CONSTEXPR quantity(value_type val) : val_(val)
0315 {
0316 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0317 }
0318
0319 BOOST_CONSTEXPR quantity(const this_type& source) : val_(source.val_)
0320 {
0321 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0322 }
0323
0324
0325
0326 BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type& source)
0327 {
0328 val_ = source.val_;
0329
0330 return *this;
0331 }
0332
0333 #ifndef BOOST_NO_SFINAE
0334
0335
0336 template<class YY>
0337 BOOST_CONSTEXPR quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
0338 typename boost::enable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
0339 val_(source.value())
0340 {
0341 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0342 }
0343
0344
0345 template<class YY>
0346 explicit BOOST_CONSTEXPR quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
0347 typename boost::disable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
0348 val_(static_cast<Y>(source.value()))
0349 {
0350 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0351 }
0352
0353 #else
0354
0355
0356 template<class YY>
0357 BOOST_CONSTEXPR quantity(const quantity<unit<dimension_type,system_type>,YY>& source) :
0358 val_(source.value())
0359 {
0360 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0361 BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
0362 }
0363
0364 #endif
0365
0366
0367 template<class YY>
0368 BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity<unit<dimension_type,system_type>,YY>& source)
0369 {
0370 BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
0371
0372 *this = this_type(source);
0373
0374 return *this;
0375 }
0376
0377 #if 1
0378
0379
0380 template<class System2, class Y2>
0381 BOOST_CONSTEXPR quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
0382 #ifdef __SUNPRO_CC
0383 typename boost::enable_if<
0384 boost::mpl::and_<
0385 detail::is_non_narrowing_conversion<Y2, Y>,
0386 detail::is_dimensionless_system<System2>
0387 >
0388 >::type* = 0
0389 #else
0390 typename boost::enable_if<detail::is_non_narrowing_conversion<Y2, Y> >::type* = 0,
0391 typename detail::disable_if_is_same<System, System2>::type* = 0,
0392 typename boost::enable_if<detail::is_dimensionless_system<System2> >::type* = 0
0393 #endif
0394 ) :
0395 val_(source.value())
0396 {
0397 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0398 }
0399
0400
0401 template<class System2, class Y2>
0402 explicit BOOST_CONSTEXPR quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
0403 #ifdef __SUNPRO_CC
0404 typename boost::enable_if<
0405 boost::mpl::and_<
0406 boost::mpl::not_<detail::is_non_narrowing_conversion<Y2, Y> >,
0407 detail::is_dimensionless_system<System2>
0408 >
0409 >::type* = 0
0410 #else
0411 typename boost::disable_if<detail::is_non_narrowing_conversion<Y2, Y> >::type* = 0,
0412 typename detail::disable_if_is_same<System, System2>::type* = 0,
0413 typename boost::enable_if<detail::is_dimensionless_system<System2> >::type* = 0
0414 #endif
0415 ) :
0416 val_(static_cast<Y>(source.value()))
0417 {
0418 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0419 }
0420
0421 #else
0422
0423
0424 template<class System2, class Y2>
0425 BOOST_CONSTEXPR quantity(const quantity<unit<dimensionless_type,homogeneous_system<System2> >,Y2>& source) :
0426 val_(source.value())
0427 {
0428 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0429 BOOST_STATIC_ASSERT((boost::is_convertible<Y2, Y>::value == true));
0430 }
0431
0432 #endif
0433
0434
0435
0436 template<class System2, class Y2>
0437 explicit BOOST_CONSTEXPR quantity(const quantity<unit<dimensionless_type, System2>,Y2>& source,
0438 typename boost::disable_if<detail::is_dimensionless_system<System2> >::type* = 0) :
0439 val_(conversion_helper<quantity<unit<dimensionless_type, System2>,Y2>, this_type>::convert(source).value())
0440 {
0441 BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
0442 }
0443
0444 #ifndef __SUNPRO_CC
0445
0446
0447 template<class System2>
0448 BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System2),Y>& source)
0449 {
0450 *this = this_type(source);
0451
0452 return *this;
0453 }
0454
0455 #endif
0456
0457
0458 BOOST_CONSTEXPR operator value_type() const { return val_; }
0459
0460 BOOST_CONSTEXPR const value_type& value() const { return val_; }
0461
0462
0463 BOOST_CXX14_CONSTEXPR this_type& operator+=(const this_type& source) { val_ += source.val_; return *this; }
0464
0465
0466 BOOST_CXX14_CONSTEXPR this_type& operator-=(const this_type& source) { val_ -= source.val_; return *this; }
0467
0468
0469 BOOST_CXX14_CONSTEXPR this_type& operator*=(const value_type& val) { val_ *= val; return *this; }
0470
0471
0472 BOOST_CXX14_CONSTEXPR this_type& operator/=(const value_type& val) { val_ /= val; return *this; }
0473
0474
0475 static BOOST_CONSTEXPR this_type from_value(const value_type& val) { return this_type(val); }
0476
0477 private:
0478 value_type val_;
0479 };
0480
0481 #ifdef BOOST_MSVC
0482
0483 template<class System, class T>
0484 class quantity<unit<int, System>, T> {};
0485 template<class T>
0486 class quantity<int, T> {};
0487 #endif
0488
0489 }
0490
0491 }
0492
0493 #if BOOST_UNITS_HAS_BOOST_TYPEOF
0494
0495 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
0496
0497 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::quantity, 2)
0498
0499 #endif
0500
0501 namespace boost {
0502
0503 namespace units {
0504
0505 namespace detail {
0506
0507
0508 template<class X,class Y> struct quantity_cast_helper;
0509
0510
0511 template<class Y,class X,class Unit>
0512 struct quantity_cast_helper<Y,quantity<Unit,X> >
0513 {
0514 typedef Y type;
0515
0516 BOOST_CONSTEXPR type operator()(quantity<Unit,X>& source) const { return const_cast<X&>(source.value()); }
0517 };
0518
0519
0520 template<class Y,class X,class Unit>
0521 struct quantity_cast_helper<Y,const quantity<Unit,X> >
0522 {
0523 typedef Y type;
0524
0525 BOOST_CONSTEXPR type operator()(const quantity<Unit,X>& source) const { return source.value(); }
0526 };
0527
0528 }
0529
0530
0531 template<class X,class Y>
0532 inline
0533 BOOST_CONSTEXPR
0534 X
0535 quantity_cast(Y& source)
0536 {
0537 return detail::quantity_cast_helper<X,Y>()(source);
0538 }
0539
0540 template<class X,class Y>
0541 inline
0542 BOOST_CONSTEXPR
0543 X
0544 quantity_cast(const Y& source)
0545 {
0546 return detail::quantity_cast_helper<X,const Y>()(source);
0547 }
0548
0549
0550 template<class Unit,class Y>
0551 inline void swap(quantity<Unit,Y>& lhs, quantity<Unit,Y>& rhs)
0552 {
0553 using std::swap;
0554 swap(quantity_cast<Y&>(lhs),quantity_cast<Y&>(rhs));
0555 }
0556
0557
0558
0559 template<class Unit,class Y>
0560 struct unary_plus_typeof_helper< quantity<Unit,Y> >
0561 {
0562 typedef typename unary_plus_typeof_helper<Y>::type value_type;
0563 typedef typename unary_plus_typeof_helper<Unit>::type unit_type;
0564 typedef quantity<unit_type,value_type> type;
0565 };
0566
0567
0568
0569 template<class Unit,class Y>
0570 struct unary_minus_typeof_helper< quantity<Unit,Y> >
0571 {
0572 typedef typename unary_minus_typeof_helper<Y>::type value_type;
0573 typedef typename unary_minus_typeof_helper<Unit>::type unit_type;
0574 typedef quantity<unit_type,value_type> type;
0575 };
0576
0577
0578
0579 template<class Unit1,
0580 class Unit2,
0581 class X,
0582 class Y>
0583 struct add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
0584 {
0585 typedef typename add_typeof_helper<X,Y>::type value_type;
0586 typedef typename add_typeof_helper<Unit1,Unit2>::type unit_type;
0587 typedef quantity<unit_type,value_type> type;
0588 };
0589
0590
0591
0592
0593 template<class Dim1, class System1,
0594 class Dim2, class System2,
0595 class X,
0596 class Y>
0597 struct add_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> >
0598 {
0599 };
0600
0601 template<class Dim,
0602 class System,
0603 class X,
0604 class Y>
0605 struct add_typeof_helper< quantity<unit<Dim, System>,X>,quantity<unit<Dim, System>,Y> >
0606 {
0607 typedef typename add_typeof_helper<X,Y>::type value_type;
0608 typedef unit<Dim, System> unit_type;
0609 typedef quantity<unit_type,value_type> type;
0610 };
0611
0612
0613
0614 template<class Unit1,
0615 class Unit2,
0616 class X,
0617 class Y>
0618 struct subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
0619 {
0620 typedef typename subtract_typeof_helper<X,Y>::type value_type;
0621 typedef typename subtract_typeof_helper<Unit1,Unit2>::type unit_type;
0622 typedef quantity<unit_type,value_type> type;
0623 };
0624
0625
0626 template<class Dim1, class System1,
0627 class Dim2, class System2,
0628 class X,
0629 class Y>
0630 struct subtract_typeof_helper< quantity<unit<Dim1, System1>,X>,quantity<unit<Dim2, System2>,Y> >
0631 {
0632 };
0633
0634 template<class Dim,
0635 class System,
0636 class X,
0637 class Y>
0638 struct subtract_typeof_helper< quantity<unit<Dim, System>,X>,quantity<unit<Dim, System>,Y> >
0639 {
0640 typedef typename subtract_typeof_helper<X,Y>::type value_type;
0641 typedef unit<Dim, System> unit_type;
0642 typedef quantity<unit_type,value_type> type;
0643 };
0644
0645
0646
0647 template<class System,
0648 class Dim,
0649 class X>
0650 struct multiply_typeof_helper< X,unit<Dim,System> >
0651 {
0652 typedef X value_type;
0653 typedef unit<Dim,System> unit_type;
0654 typedef quantity<unit_type,value_type> type;
0655 };
0656
0657
0658
0659 template<class System,
0660 class Dim,
0661 class X>
0662 struct multiply_typeof_helper< unit<Dim,System>,X >
0663 {
0664 typedef X value_type;
0665 typedef unit<Dim,System> unit_type;
0666 typedef quantity<unit_type,value_type> type;
0667 };
0668
0669
0670
0671 template<class Unit,
0672 class X,
0673 class Y>
0674 struct multiply_typeof_helper< X,quantity<Unit,Y> >
0675 {
0676 typedef typename multiply_typeof_helper<X,Y>::type value_type;
0677 typedef Unit unit_type;
0678 typedef quantity<unit_type,value_type> type;
0679 };
0680
0681
0682
0683 template<class Unit,
0684 class Y>
0685 struct multiply_typeof_helper< one,quantity<Unit,Y> >
0686 {
0687 typedef quantity<Unit,Y> type;
0688 };
0689
0690
0691
0692 template<class Unit,
0693 class X,
0694 class Y>
0695 struct multiply_typeof_helper< quantity<Unit,X>,Y >
0696 {
0697 typedef typename multiply_typeof_helper<X,Y>::type value_type;
0698 typedef Unit unit_type;
0699 typedef quantity<unit_type,value_type> type;
0700 };
0701
0702
0703
0704 template<class Unit,
0705 class X>
0706 struct multiply_typeof_helper< quantity<Unit,X>,one >
0707 {
0708 typedef quantity<Unit,X> type;
0709 };
0710
0711
0712
0713 template<class Unit,
0714 class System,
0715 class Dim,
0716 class X>
0717 struct multiply_typeof_helper< unit<Dim,System>,quantity<Unit,X> >
0718 {
0719 typedef X value_type;
0720 typedef typename multiply_typeof_helper< unit<Dim,System>,Unit >::type unit_type;
0721 typedef quantity<unit_type,value_type> type;
0722 };
0723
0724
0725
0726 template<class Unit,
0727 class System,
0728 class Dim,
0729 class X>
0730 struct multiply_typeof_helper< quantity<Unit,X>,unit<Dim,System> >
0731 {
0732 typedef X value_type;
0733 typedef typename multiply_typeof_helper< Unit,unit<Dim,System> >::type unit_type;
0734 typedef quantity<unit_type,value_type> type;
0735 };
0736
0737
0738
0739 template<class Unit1,
0740 class Unit2,
0741 class X,
0742 class Y>
0743 struct multiply_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
0744 {
0745 typedef typename multiply_typeof_helper<X,Y>::type value_type;
0746 typedef typename multiply_typeof_helper<Unit1,Unit2>::type unit_type;
0747 typedef quantity<unit_type,value_type> type;
0748 };
0749
0750
0751
0752 template<class System,
0753 class Dim,
0754 class X>
0755 struct divide_typeof_helper< X,unit<Dim,System> >
0756 {
0757 typedef X value_type;
0758 typedef typename power_typeof_helper< unit<Dim,System>,static_rational<-1> >::type unit_type;
0759 typedef quantity<unit_type,value_type> type;
0760 };
0761
0762
0763
0764 template<class System,
0765 class Dim,
0766 class X>
0767 struct divide_typeof_helper< unit<Dim,System>,X >
0768 {
0769 typedef typename divide_typeof_helper<X,X>::type value_type;
0770 typedef unit<Dim,System> unit_type;
0771 typedef quantity<unit_type,value_type> type;
0772 };
0773
0774
0775
0776 template<class Unit,
0777 class X,
0778 class Y>
0779 struct divide_typeof_helper< X,quantity<Unit,Y> >
0780 {
0781 typedef typename divide_typeof_helper<X,Y>::type value_type;
0782 typedef typename power_typeof_helper< Unit,static_rational<-1> >::type unit_type;
0783 typedef quantity<unit_type,value_type> type;
0784 };
0785
0786
0787
0788 template<class Unit,
0789 class Y>
0790 struct divide_typeof_helper< one,quantity<Unit,Y> >
0791 {
0792 typedef quantity<Unit,Y> type;
0793 };
0794
0795
0796
0797 template<class Unit,
0798 class X,
0799 class Y>
0800 struct divide_typeof_helper< quantity<Unit,X>,Y >
0801 {
0802 typedef typename divide_typeof_helper<X,Y>::type value_type;
0803 typedef Unit unit_type;
0804 typedef quantity<unit_type,value_type> type;
0805 };
0806
0807
0808
0809 template<class Unit,
0810 class X>
0811 struct divide_typeof_helper< quantity<Unit,X>,one >
0812 {
0813 typedef quantity<Unit,X> type;
0814 };
0815
0816
0817
0818 template<class Unit,
0819 class System,
0820 class Dim,
0821 class X>
0822 struct divide_typeof_helper< unit<Dim,System>,quantity<Unit,X> >
0823 {
0824 typedef typename divide_typeof_helper<X,X>::type value_type;
0825 typedef typename divide_typeof_helper< unit<Dim,System>,Unit >::type unit_type;
0826 typedef quantity<unit_type,value_type> type;
0827 };
0828
0829
0830
0831 template<class Unit,
0832 class System,
0833 class Dim,
0834 class X>
0835 struct divide_typeof_helper< quantity<Unit,X>,unit<Dim,System> >
0836 {
0837 typedef X value_type;
0838 typedef typename divide_typeof_helper< Unit,unit<Dim,System> >::type unit_type;
0839 typedef quantity<unit_type,value_type> type;
0840 };
0841
0842
0843
0844 template<class Unit1,
0845 class Unit2,
0846 class X,
0847 class Y>
0848 struct divide_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >
0849 {
0850 typedef typename divide_typeof_helper<X,Y>::type value_type;
0851 typedef typename divide_typeof_helper<Unit1,Unit2>::type unit_type;
0852 typedef quantity<unit_type,value_type> type;
0853 };
0854
0855
0856
0857 template<class Unit,long N,long D,class Y>
0858 struct power_typeof_helper< quantity<Unit,Y>,static_rational<N,D> >
0859 {
0860 typedef typename power_typeof_helper<Y,static_rational<N,D> >::type value_type;
0861 typedef typename power_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
0862 typedef quantity<unit_type,value_type> type;
0863
0864 static BOOST_CONSTEXPR type value(const quantity<Unit,Y>& x)
0865 {
0866 return type::from_value(power_typeof_helper<Y,static_rational<N,D> >::value(x.value()));
0867 }
0868 };
0869
0870
0871
0872 template<class Unit,long N,long D,class Y>
0873 struct root_typeof_helper< quantity<Unit,Y>,static_rational<N,D> >
0874 {
0875 typedef typename root_typeof_helper<Y,static_rational<N,D> >::type value_type;
0876 typedef typename root_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
0877 typedef quantity<unit_type,value_type> type;
0878
0879 static BOOST_CONSTEXPR type value(const quantity<Unit,Y>& x)
0880 {
0881 return type::from_value(root_typeof_helper<Y,static_rational<N,D> >::value(x.value()));
0882 }
0883 };
0884
0885
0886
0887 template<class System,
0888 class Dim,
0889 class Y>
0890 inline
0891 BOOST_CONSTEXPR
0892 typename multiply_typeof_helper< unit<Dim,System>,Y >::type
0893 operator*(const unit<Dim,System>&,const Y& rhs)
0894 {
0895 typedef typename multiply_typeof_helper< unit<Dim,System>,Y >::type type;
0896
0897 return type::from_value(rhs);
0898 }
0899
0900
0901 template<class System,
0902 class Dim,
0903 class Y>
0904 inline
0905 BOOST_CONSTEXPR
0906 typename divide_typeof_helper< unit<Dim,System>,Y >::type
0907 operator/(const unit<Dim,System>&,const Y& rhs)
0908 {
0909 typedef typename divide_typeof_helper<unit<Dim,System>,Y>::type type;
0910
0911 return type::from_value(Y(1)/rhs);
0912 }
0913
0914
0915 template<class System,
0916 class Dim,
0917 class Y>
0918 inline
0919 BOOST_CONSTEXPR
0920 typename multiply_typeof_helper< Y,unit<Dim,System> >::type
0921 operator*(const Y& lhs,const unit<Dim,System>&)
0922 {
0923 typedef typename multiply_typeof_helper< Y,unit<Dim,System> >::type type;
0924
0925 return type::from_value(lhs);
0926 }
0927
0928
0929 template<class System,
0930 class Dim,
0931 class Y>
0932 inline
0933 BOOST_CONSTEXPR
0934 typename divide_typeof_helper< Y,unit<Dim,System> >::type
0935 operator/(const Y& lhs,const unit<Dim,System>&)
0936 {
0937 typedef typename divide_typeof_helper< Y,unit<Dim,System> >::type type;
0938
0939 return type::from_value(lhs);
0940 }
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971 template<class Unit,
0972 class X>
0973 inline
0974 BOOST_CONSTEXPR
0975 typename multiply_typeof_helper< quantity<Unit,X>,X >::type
0976 operator*(const quantity<Unit,X>& lhs,const X& rhs)
0977 {
0978 typedef typename multiply_typeof_helper< quantity<Unit,X>,X >::type type;
0979
0980 return type::from_value(lhs.value()*rhs);
0981 }
0982
0983
0984 template<class Unit,
0985 class X>
0986 inline
0987 BOOST_CONSTEXPR
0988 typename multiply_typeof_helper< X,quantity<Unit,X> >::type
0989 operator*(const X& lhs,const quantity<Unit,X>& rhs)
0990 {
0991 typedef typename multiply_typeof_helper< X,quantity<Unit,X> >::type type;
0992
0993 return type::from_value(lhs*rhs.value());
0994 }
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025 template<class Unit,
1026 class X>
1027 inline
1028 BOOST_CONSTEXPR
1029 typename divide_typeof_helper< quantity<Unit,X>,X >::type
1030 operator/(const quantity<Unit,X>& lhs,const X& rhs)
1031 {
1032 typedef typename divide_typeof_helper< quantity<Unit,X>,X >::type type;
1033
1034 return type::from_value(lhs.value()/rhs);
1035 }
1036
1037
1038 template<class Unit,
1039 class X>
1040 inline
1041 BOOST_CONSTEXPR
1042 typename divide_typeof_helper< X,quantity<Unit,X> >::type
1043 operator/(const X& lhs,const quantity<Unit,X>& rhs)
1044 {
1045 typedef typename divide_typeof_helper< X,quantity<Unit,X> >::type type;
1046
1047 return type::from_value(lhs/rhs.value());
1048 }
1049
1050
1051 template<class System1,
1052 class Dim1,
1053 class Unit2,
1054 class Y>
1055 inline
1056 BOOST_CONSTEXPR
1057 typename multiply_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type
1058 operator*(const unit<Dim1,System1>&,const quantity<Unit2,Y>& rhs)
1059 {
1060 typedef typename multiply_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type type;
1061
1062 return type::from_value(rhs.value());
1063 }
1064
1065
1066 template<class System1,
1067 class Dim1,
1068 class Unit2,
1069 class Y>
1070 inline
1071 BOOST_CONSTEXPR
1072 typename divide_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type
1073 operator/(const unit<Dim1,System1>&,const quantity<Unit2,Y>& rhs)
1074 {
1075 typedef typename divide_typeof_helper< unit<Dim1,System1>,quantity<Unit2,Y> >::type type;
1076
1077 return type::from_value(Y(1)/rhs.value());
1078 }
1079
1080
1081 template<class Unit1,
1082 class System2,
1083 class Dim2,
1084 class Y>
1085 inline
1086 BOOST_CONSTEXPR
1087 typename multiply_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type
1088 operator*(const quantity<Unit1,Y>& lhs,const unit<Dim2,System2>&)
1089 {
1090 typedef typename multiply_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type type;
1091
1092 return type::from_value(lhs.value());
1093 }
1094
1095
1096 template<class Unit1,
1097 class System2,
1098 class Dim2,
1099 class Y>
1100 inline
1101 BOOST_CONSTEXPR
1102 typename divide_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type
1103 operator/(const quantity<Unit1,Y>& lhs,const unit<Dim2,System2>&)
1104 {
1105 typedef typename divide_typeof_helper< quantity<Unit1,Y>,unit<Dim2,System2> >::type type;
1106
1107 return type::from_value(lhs.value());
1108 }
1109
1110
1111 template<class Unit,class Y>
1112 BOOST_CONSTEXPR
1113 typename unary_plus_typeof_helper< quantity<Unit,Y> >::type
1114 operator+(const quantity<Unit,Y>& val)
1115 {
1116 typedef typename unary_plus_typeof_helper< quantity<Unit,Y> >::type type;
1117
1118 return type::from_value(+val.value());
1119 }
1120
1121
1122 template<class Unit,class Y>
1123 BOOST_CONSTEXPR
1124 typename unary_minus_typeof_helper< quantity<Unit,Y> >::type
1125 operator-(const quantity<Unit,Y>& val)
1126 {
1127 typedef typename unary_minus_typeof_helper< quantity<Unit,Y> >::type type;
1128
1129 return type::from_value(-val.value());
1130 }
1131
1132
1133 template<class Unit1,
1134 class Unit2,
1135 class X,
1136 class Y>
1137 inline
1138 BOOST_CONSTEXPR
1139 typename add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
1140 operator+(const quantity<Unit1,X>& lhs,
1141 const quantity<Unit2,Y>& rhs)
1142 {
1143 typedef typename add_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type type;
1144
1145 return type::from_value(lhs.value()+rhs.value());
1146 }
1147
1148
1149 template<class Unit1,
1150 class Unit2,
1151 class X,
1152 class Y>
1153 inline
1154 BOOST_CONSTEXPR
1155 typename subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
1156 operator-(const quantity<Unit1,X>& lhs,
1157 const quantity<Unit2,Y>& rhs)
1158 {
1159 typedef typename subtract_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type type;
1160
1161 return type::from_value(lhs.value()-rhs.value());
1162 }
1163
1164
1165 template<class Unit1,
1166 class Unit2,
1167 class X,
1168 class Y>
1169 inline
1170 BOOST_CONSTEXPR
1171 typename multiply_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
1172 operator*(const quantity<Unit1,X>& lhs,
1173 const quantity<Unit2,Y>& rhs)
1174 {
1175 typedef typename multiply_typeof_helper< quantity<Unit1,X>,
1176 quantity<Unit2,Y> >::type type;
1177
1178 return type::from_value(lhs.value()*rhs.value());
1179 }
1180
1181
1182 template<class Unit1,
1183 class Unit2,
1184 class X,
1185 class Y>
1186 inline
1187 BOOST_CONSTEXPR
1188 typename divide_typeof_helper< quantity<Unit1,X>,quantity<Unit2,Y> >::type
1189 operator/(const quantity<Unit1,X>& lhs,
1190 const quantity<Unit2,Y>& rhs)
1191 {
1192 typedef typename divide_typeof_helper< quantity<Unit1,X>,
1193 quantity<Unit2,Y> >::type type;
1194
1195 return type::from_value(lhs.value()/rhs.value());
1196 }
1197
1198
1199 template<class Unit,
1200 class X,
1201 class Y>
1202 inline
1203 BOOST_CONSTEXPR
1204 bool
1205 operator==(const quantity<Unit,X>& val1,
1206 const quantity<Unit,Y>& val2)
1207 {
1208 return val1.value() == val2.value();
1209 }
1210
1211
1212 template<class Unit,
1213 class X,
1214 class Y>
1215 inline
1216 BOOST_CONSTEXPR
1217 bool
1218 operator!=(const quantity<Unit,X>& val1,
1219 const quantity<Unit,Y>& val2)
1220 {
1221 return val1.value() != val2.value();
1222 }
1223
1224
1225 template<class Unit,
1226 class X,
1227 class Y>
1228 inline
1229 BOOST_CONSTEXPR
1230 bool
1231 operator<(const quantity<Unit,X>& val1,
1232 const quantity<Unit,Y>& val2)
1233 {
1234 return val1.value() < val2.value();
1235 }
1236
1237
1238 template<class Unit,
1239 class X,
1240 class Y>
1241 inline
1242 BOOST_CONSTEXPR
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
1251 template<class Unit,
1252 class X,
1253 class Y>
1254 inline
1255 BOOST_CONSTEXPR
1256 bool
1257 operator>(const quantity<Unit,X>& val1,
1258 const quantity<Unit,Y>& val2)
1259 {
1260 return val1.value() > val2.value();
1261 }
1262
1263
1264 template<class Unit,
1265 class X,
1266 class Y>
1267 inline
1268 BOOST_CONSTEXPR
1269 bool
1270 operator>=(const quantity<Unit,X>& val1,
1271 const quantity<Unit,Y>& val2)
1272 {
1273 return val1.value() >= val2.value();
1274 }
1275
1276 }
1277
1278 }
1279
1280 #endif