00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _UniqueConstant_h
00025 #define _UniqueConstant_h
00026
00027 #include "Quantity/Quantity.h"
00028 #include "Quantity/Variable.h"
00029
00030 #include "Singleton.h"
00031
00032 namespace Quantities {
00033
00035
00036
00037
00039
00041
00046 template<class PQ, class SU = typename PQ::DefaultUnit::Unit>
00047 class UniqueConstant;
00049
00052 template<class GT, class Head, class Tail, class DU, class SU, class ST>
00053 class UniqueConstant<Quantity<GT, Loki::Typelist<Head, Tail>,
00054 DU, ST>, SU>
00055 : public Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>
00056 {
00057 private:
00059
00063 typedef typename
00064 Units::CheckUnit<Units::Unit<GT, ST>, SU>::Check Checked;
00066
00068 typedef Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST> PQ;
00069
00071 typedef
00072 UniqueConstant<Quantity<GT, Loki::Typelist<Head, Tail>,
00073 DU, ST>, SU> SC;
00074
00076
00079 friend class Loki::CreateUsingNew<SC>;
00080
00081 public:
00083
00085 typedef SU Unit;
00086
00087 private:
00089
00093 static const ST default_value_;
00094
00096
00099 ST constant_value;
00100
00101 private:
00103
00108 UniqueConstant (void) : constant_value (default_value_) {};
00109
00110 private:
00112
00116 UniqueConstant (const UniqueConstant &new_constant)
00117 : PQ (), constant_value (default_value_)
00118 {
00119 namestring = new_constant.name ();
00120 symbolstring = new_constant.symbol ();
00121 };
00122
00123 public:
00125
00128 ST standard_value (void) const
00129 {return SU::Standard (constant_value);}
00130
00132
00134 ST value (void) const {return constant_value;}
00135
00137
00142 template<class NU>
00143 ST value (const Units::NonPrefixable<GT, NU, ST> &) const
00144 {return
00145 CheckAgainstAllUnits<Units::NonPrefixable<GT, NU, ST>,
00146 Loki::Typelist<Head, Tail> >::RET::Reverse
00147 (SU::Standard (constant_value));}
00148
00150
00155
00156 template<class NU, class P>
00157 ST value
00158 (const Units::Prefixed<Units::Prefixable<GT, NU, ST>, P> &)
00159 const
00160 {return
00161 CheckAgainstAllUnits
00162 <Units::Prefixed<Units::Prefixable<GT, NU, ST>, P>,
00163 Loki::Typelist<Head, Tail> >::RET::Reverse
00164 (SU::Standard (constant_value));}
00165
00167
00172
00173 template<class CUL, class EL>
00174 ST value
00175 (const Units::Composed<Units::Compound<GT, CUL, ST>, EL> &)
00176 const
00177 {return
00178 CheckAgainstAllUnits
00179 <Units::Composed<Units::Compound<GT, CUL, ST>, EL>,
00180 Loki::Typelist<Head, Tail> >::RET::Reverse
00181 (SU::Standard (constant_value));}
00182
00184
00191 ST value (const std::string &symbol)
00192 {ST value;
00193 ::Units::Unit<GT, ST> *unitp = PQ::findBySymbol (symbol);
00194
00195 value = unitp->reverse (SU::Standard (constant_value));
00196
00197 delete (unitp);
00198
00199 return value;
00200 }
00201
00203
00208 template<class NU>
00209 Variable<PQ, NU> operator () (const NU &) const
00210 {return Variable<PQ, NU> (constant_value, SU());}
00211
00213
00215 const std::string unitsymbol (void) const
00216 {return SU::Symbol ();}
00217
00219
00221 static std::string Unitsymbol (void) {return SU::Symbol ();}
00222
00224
00226 const std::string unitname (void) const {return SU::Name ();}
00227
00229
00231 static std::string Unitname (void) {return SU::Name ();}
00232
00234
00237 Variable<PQ, SU> operator+ (void) const
00238 {Variable<PQ, SU> new_constant (*this);
00239 return new_constant;
00240 }
00241
00243
00246 Variable<PQ, SU> operator- (void) const
00247 {Variable<PQ, SU> new_constant (*this);
00248 return new_constant * -1.0;
00249 }
00250
00252
00254 template <class Q>
00255 Variable<PQ, SU> operator+ (const Q &new_variable) const
00256 {Variable<PQ, SU> new_object = *this;
00257 return new_object += new_variable;
00258 }
00259
00261
00263 template <class Q>
00264 Variable<PQ, SU> operator- (const Q &new_variable) const
00265 {Variable<PQ, SU> new_object = *this;
00266 return new_object -= new_variable;
00267 }
00268
00270
00272 Variable<PQ, SU> operator* (const ST factor) const
00273 {Variable<PQ, SU> new_object = *this;
00274 return new_object *= factor;
00275 }
00276
00278
00280 Variable<PQ, SU> operator/ (const ST factor) const
00281 {Variable<PQ, SU> new_object = *this;
00282 return new_object /= factor;
00283 }
00284
00286
00288 friend Variable<PQ, SU> operator*
00289 (const ST factor, const UniqueConstant &constant)
00290 {Variable<PQ, SU> new_variable = constant;
00291 return new_variable *= factor;
00292 }
00293
00295
00297 friend Variable<PQ, SU> abs (const UniqueConstant &constant)
00298 {Variable<PQ, SU> new_variable
00299 = std::abs (constant.value ()); return new_variable;}
00300
00302
00304 friend Variable<PQ, SU> ceil (const UniqueConstant &constant)
00305 {Variable<PQ, SU> new_variable
00306 = std::ceil (constant.value ()); return new_variable;}
00307
00309
00311 friend Variable<PQ, SU> floor (const UniqueConstant &constant)
00312 {Variable<PQ, SU> new_variable
00313 = std::floor (constant.value ()); return new_variable;}
00314
00316
00320 friend Variable<PQ, SU> modf
00321 (const UniqueConstant &constant, Variable<PQ, SU> *integral)
00322 {Variable<PQ, SU> new_variable = constant;
00323 ST i_ptr;
00324 new_variable.variable_value
00325 = std::modf (constant.value (), &i_ptr);
00326 Variable<PQ, SU> int_quantity (i_ptr);
00327 *integral = int_quantity; return new_variable;
00328 }
00329
00331
00333 friend Variable<PQ, SU>
00334 frexp (const UniqueConstant &constant, int *exponent)
00335 {Variable<PQ, SU> new_variable
00336 = std::frexp (constant.value (), exponent);
00337 return new_variable;
00338 }
00339
00341
00343 friend Variable<PQ, SU>
00344 ldexp (const UniqueConstant &constant, int *exponent)
00345 {Variable<PQ, SU> new_variable = constant;
00346 return new_variable.variable_value
00347 = std::ldexp (constant.value (), exponent);
00348 }
00349
00351
00357 template <template<class, class> class Q1, class SU1>
00358 friend Variable<PQ, SU> fmod
00359 (const UniqueConstant &constant,
00360 const Q1<PQ, SU1> &quantity)
00361 {return Variable<PQ, SU>
00362 (SU::Reverse (std::fmod (constant.standard_value (),
00363 quantity.standard_value ())));
00364 }
00365
00367
00372 template <template<class, class> class Q1, class GT1,
00373 class DU1, class SU1>
00374 friend Variable<PQ,SU> fmod
00375 (const UniqueConstant &constant, const Q1<Quantity<GT1,
00376 Loki::Typelist<Units::NonPrefixable<GT1,
00377 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
00378 &quantity)
00379 {
00380 return Variable<PQ,SU>
00381 (SU::Reverse
00382 (std::fmod (constant.standard_value (),
00383 CheckSecondDimension<Variable<PQ, SU>,
00384 Q1<Quantity<GT1,
00385 Loki::Typelist<Units::NonPrefixable<GT1,
00386 Units::GenericUnit, ST>, Loki::NullType>,
00387 DU1, ST>, SU1> >::RET::Unit::Standard
00388 (quantity.value ()))));
00389 }
00390
00392
00397 template <template<class, class> class Q1, class GT1,
00398 class DU1, class SU1>
00399 friend Q1<Quantity<GT1,
00400 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00401 ST>, Loki::NullType>, DU1, ST>, SU1> fmod
00402 (const Q1<Quantity<GT1,
00403 Loki::Typelist<Units::NonPrefixable<GT1,
00404 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
00405 &variable1, const UniqueConstant &constant)
00406 {
00407 return Q1<Quantity<GT1,
00408 Loki::Typelist<Units::NonPrefixable<GT1,
00409 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>,
00410 SU1>
00411 (SU::Reverse
00412 (std::fmod (variable1.standard_value (),
00413 CheckSecondDimension< Q1<Quantity<GT1,
00414 Loki::Typelist<Units::NonPrefixable<GT1,
00415 Units::GenericUnit, ST>, Loki::NullType>,
00416 DU1, ST>, SU1>, UniqueConstant
00417 >::RET::Unit::Standard
00418 (constant.value ()))));
00419 }
00420
00422
00426 bool operator== (const UniqueConstant &rhs_variable) const
00427 {return variable_value == rhs_variable.value ();}
00428
00430
00435 template <template<class, class> class Q1, class SU1>
00436 bool operator== (const Q1<PQ, SU1> &rhs_variable) const
00437 {return standard_value () == rhs_variable.standard_value ();
00438 }
00439
00441
00446 template <template<class, class> class Q1, class GT1,
00447 class DU1, class SU1>
00448 bool operator== (const Q1<Quantity<GT1,
00449 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00450 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00451 {
00452 return standard_value () ==
00453 CheckSecondDimension<Variable<PQ, SU>,
00454 Q1<Quantity<GT1,
00455 Loki::Typelist<Units::NonPrefixable<GT1,
00456 Units::GenericUnit, ST>, Loki::NullType>,
00457 DU1, ST>, SU1> >::RET::Unit::Standard
00458 (rhs_variable.value ());
00459 }
00460
00462
00469 template <template<class, class> class Q1, class GT1,
00470 class Head1, class Tail1, class DU1, class SU1>
00471 bool operator==
00472 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00473 DU1, ST>, SU1> &rhs_variable) const
00474 {
00475 return
00476 BSUtilities::IF<BSUtilities::SameType<SU,
00477 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00478 >::sameType, SU, Units::UnitError<false>
00479 >::RET::Standard (variable_value) ==
00480 CheckSecondDimension<Variable<PQ, SU>,
00481 Q1<Quantity<GT1,
00482 Loki::Typelist<Units::NonPrefixable<GT1,
00483 Units::GenericUnit, ST>, Loki::NullType>,
00484 DU1, ST>, SU1> >::RET::Unit::Standard
00485 (rhs_variable.value ());
00486 }
00487
00489
00493 bool operator!= (const UniqueConstant &rhs_variable) const
00494 {return variable_value != rhs_variable.value ();}
00495
00497
00502 template <template<class, class> class Q1, class SU1>
00503 bool operator!= (const Q1<PQ, SU1> &rhs_variable) const
00504 {return standard_value () != rhs_variable.standard_value ();
00505 }
00506
00508
00513 template <template<class, class> class Q1, class GT1,
00514 class DU1, class SU1>
00515 bool operator!= (const Q1<Quantity<GT1,
00516 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00517 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00518 {
00519 return standard_value () !=
00520 CheckSecondDimension<Variable<PQ, SU>,
00521 Q1<Quantity<GT1,
00522 Loki::Typelist<Units::NonPrefixable<GT1,
00523 Units::GenericUnit, ST>, Loki::NullType>,
00524 DU1, ST>, SU1> >::RET::Unit::Standard
00525 (rhs_variable.value ());
00526 }
00527
00529
00536 template <template<class, class> class Q1, class GT1,
00537 class Head1, class Tail1, class DU1, class SU1>
00538 bool operator!=
00539 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00540 DU1, ST>, SU1> &rhs_variable) const
00541 {
00542 return
00543 BSUtilities::IF<BSUtilities::SameType<SU,
00544 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00545 >::sameType, SU, Units::UnitError<false>
00546 >::RET::Standard (variable_value) !=
00547 CheckSecondDimension<Variable<PQ, SU>,
00548 Q1<Quantity<GT1,
00549 Loki::Typelist<Units::NonPrefixable<GT1,
00550 Units::GenericUnit, ST>, Loki::NullType>,
00551 DU1, ST>, SU1> >::RET::Unit::Standard
00552 (rhs_variable.value ());
00553 }
00554
00556
00560 bool operator> (const UniqueConstant &rhs_variable) const
00561 {return variable_value > rhs_variable.value ();}
00562
00564
00569 template <template<class, class> class Q1, class SU1>
00570 bool operator> (const Q1<PQ, SU1> &rhs_variable) const
00571 {return standard_value () > rhs_variable.standard_value ();
00572 }
00573
00575
00580 template <template<class, class> class Q1, class GT1,
00581 class DU1, class SU1>
00582 bool operator> (const Q1<Quantity<GT1,
00583 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00584 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00585 {
00586 return standard_value () >
00587 CheckSecondDimension<UniqueConstant<PQ, SU>,
00588 Q1<Quantity<GT1,
00589 Loki::Typelist<Units::NonPrefixable<GT1,
00590 Units::GenericUnit, ST>, Loki::NullType>,
00591 DU1, ST>, SU1> >::RET::Unit::Standard
00592 (rhs_variable.value ());
00593 }
00594
00596
00603 template <template<class, class> class Q1, class GT1,
00604 class Head1, class Tail1, class DU1, class SU1>
00605 bool operator>
00606 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00607 DU1, ST>, SU1> &rhs_variable) const
00608 {
00609 return
00610 BSUtilities::IF<BSUtilities::SameType<SU,
00611 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00612 >::sameType, SU, Units::UnitError<false>
00613 >::RET::Standard (variable_value) >
00614 CheckSecondDimension<UniqueConstant<PQ, SU>,
00615 Q1<Quantity<GT1,
00616 Loki::Typelist<Units::NonPrefixable<GT1,
00617 Units::GenericUnit, ST>, Loki::NullType>,
00618 DU1, ST>, SU1> >::RET::Unit::Standard
00619 (rhs_variable.value ());
00620 }
00621
00623
00627 bool operator< (const UniqueConstant &rhs_variable) const
00628 {return variable_value < rhs_variable.value ();}
00629
00631
00636 template <template<class, class> class Q1, class SU1>
00637 bool operator< (const Q1<PQ, SU1> &rhs_variable) const
00638 {return standard_value () < rhs_variable.standard_value ();
00639 }
00640
00642
00647 template <template<class, class> class Q1, class GT1,
00648 class DU1, class SU1>
00649 bool operator< (const Q1<Quantity<GT1,
00650 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00651 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00652 {
00653 return standard_value () <
00654 CheckSecondDimension<UniqueConstant<PQ, SU>,
00655 Q1<Quantity<GT1,
00656 Loki::Typelist<Units::NonPrefixable<GT1,
00657 Units::GenericUnit, ST>, Loki::NullType>,
00658 DU1, ST>, SU1> >::RET::Unit::Standard
00659 (rhs_variable.value ());
00660 }
00661
00663
00670 template <template<class, class> class Q1, class GT1,
00671 class Head1, class Tail1, class DU1, class SU1>
00672 bool operator<
00673 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00674 DU1, ST>, SU1> &rhs_variable) const
00675 {
00676 return
00677 BSUtilities::IF<BSUtilities::SameType<SU,
00678 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00679 >::sameType, SU, Units::UnitError<false>
00680 >::RET::Standard (variable_value) <
00681 CheckSecondDimension<UniqueConstant<PQ, SU>,
00682 Q1<Quantity<GT1,
00683 Loki::Typelist<Units::NonPrefixable<GT1,
00684 Units::GenericUnit, ST>, Loki::NullType>,
00685 DU1, ST>, SU1> >::RET::Unit::Standard
00686 (rhs_variable.value ());
00687 }
00688
00690
00694 bool operator>= (const UniqueConstant &rhs_variable) const
00695 {return variable_value >= rhs_variable.value ();}
00696
00698
00703 template <template<class, class> class Q1, class SU1>
00704 bool operator>= (const Q1<PQ, SU1> &rhs_variable) const
00705 {return standard_value () >= rhs_variable.standard_value ();
00706 }
00707
00709
00714 template <template<class, class> class Q1, class GT1,
00715 class DU1, class SU1>
00716 bool operator>= (const Q1<Quantity<GT1,
00717 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00718 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00719 {
00720 return standard_value () >=
00721 CheckSecondDimension<UniqueConstant<PQ, SU>,
00722 Q1<Quantity<GT1,
00723 Loki::Typelist<Units::NonPrefixable<GT1,
00724 Units::GenericUnit, ST>, Loki::NullType>,
00725 DU1, ST>, SU1> >::RET::Unit::Standard
00726 (rhs_variable.value ());
00727 }
00728
00730
00737 template <template<class, class> class Q1, class GT1,
00738 class Head1, class Tail1, class DU1, class SU1>
00739 bool operator>=
00740 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00741 DU1, ST>, SU1> &rhs_variable) const
00742 {
00743 return
00744 BSUtilities::IF<BSUtilities::SameType<SU,
00745 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00746 >::sameType, SU, Units::UnitError<false>
00747 >::RET::Standard (variable_value) >=
00748 CheckSecondDimension<UniqueConstant<PQ, SU>,
00749 Q1<Quantity<GT1,
00750 Loki::Typelist<Units::NonPrefixable<GT1,
00751 Units::GenericUnit, ST>, Loki::NullType>,
00752 DU1, ST>, SU1> >::RET::Unit::Standard
00753 (rhs_variable.value ());
00754 }
00755
00757
00761 bool operator<= (const UniqueConstant &rhs_variable) const
00762 {return variable_value <= rhs_variable.value ();}
00763
00765
00770 template <template<class, class> class Q1, class SU1>
00771 bool operator<= (const Q1<PQ, SU1> &rhs_variable) const
00772 {return standard_value () <= rhs_variable.standard_value ();
00773 }
00774
00776
00781 template <template<class, class> class Q1, class GT1,
00782 class DU1, class SU1>
00783 bool operator<= (const Q1<Quantity<GT1,
00784 Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00785 ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00786 {
00787 return standard_value () <=
00788 CheckSecondDimension<UniqueConstant<PQ, SU>,
00789 Q1<Quantity<GT1,
00790 Loki::Typelist<Units::NonPrefixable<GT1,
00791 Units::GenericUnit, ST>, Loki::NullType>,
00792 DU1, ST>, SU1> >::RET::Unit::Standard
00793 (rhs_variable.value ());
00794 }
00795
00797
00804 template <template<class, class> class Q1, class GT1,
00805 class Head1, class Tail1, class DU1, class SU1>
00806 bool operator<=
00807 (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00808 DU1, ST>, SU1> &rhs_variable) const
00809 {
00810 return
00811 BSUtilities::IF<BSUtilities::SameType<SU,
00812 Units::NonPrefixable<GT, Units::GenericUnit, ST>
00813 >::sameType, SU, Units::UnitError<false>
00814 >::RET::Standard (variable_value) <=
00815 CheckSecondDimension<UniqueConstant<PQ, SU>,
00816 Q1<Quantity<GT1,
00817 Loki::Typelist<Units::NonPrefixable<GT1,
00818 Units::GenericUnit, ST>, Loki::NullType>,
00819 DU1, ST>, SU1> >::RET::Unit::Standard
00820 (rhs_variable.value ());
00821 }
00822
00824
00829 template<class Q>
00830 typename GenerateVariable<UniqueConstant, Q>::Add operator*
00831 (const Q &factor)
00832 {
00833 return typename
00834 GenerateVariable<UniqueConstant, Q>::Add
00835 (standard_value () * factor.standard_value ());
00836 }
00837
00839
00844 template<class Q>
00845 typename GenerateVariable<UniqueConstant, Q>::Sub
00846 operator/ (const Q &factor)
00847 {
00848 return typename
00849 GenerateVariable<UniqueConstant, Q>::Sub
00850 (standard_value () / factor.standard_value ());
00851 }
00852
00854
00857 friend
00858 typename GenerateVariable<UniqueConstant, Loki::NullType>::Neg
00859 operator/ (const ST numerator, const UniqueConstant &factor)
00860 {
00861 return typename
00862 GenerateVariable<UniqueConstant, Loki::NullType>::Neg
00863 (numerator / factor.standard_value ());
00864 }
00865
00867
00869 template<long N, long D>
00870 friend typename
00871 GenerateVariable<UniqueConstant,
00872 BSUtilities::Rational<N, D> >::Mult
00873 pow (const UniqueConstant &variable,
00874 const BSUtilities::Rational<N, D> &)
00875 {
00876 return typename
00877 GenerateVariable<UniqueConstant,
00878 BSUtilities::Rational<N, D> >::Mult
00879 (std::pow(variable.standard_value (),
00880 static_cast<double>(N)/static_cast<double>(D)));
00881 }
00882
00884
00886 template<long N, long D>
00887 typename GenerateVariable<UniqueConstant,
00888 BSUtilities::Rational<N, D> >::Mult
00889 pow (const BSUtilities::Rational<N, D> &)
00890 {
00891 return typename
00892 GenerateVariable<UniqueConstant,
00893 BSUtilities::Rational<N, D> >::Mult
00894 (std::pow(standard_value (),
00895 static_cast<double>(N)/static_cast<double>(D)));
00896 }
00897
00899
00901 friend
00902 typename
00903 GenerateVariable<UniqueConstant,
00904 BSUtilities::Rational<1, 2> >::Mult
00905 sqrt (const UniqueConstant &constant)
00906 {
00907 return typename
00908 GenerateVariable<UniqueConstant,
00909 BSUtilities::Rational<1, 2> >::Mult
00910 (std::sqrt(constant.standard_value ()));
00911 }
00912
00914
00916 typename
00917 GenerateVariable<UniqueConstant,
00918 BSUtilities::Rational<1, 2> >::Mult
00919 sqrt (void)
00920 {
00921 return typename
00922 GenerateVariable<UniqueConstant,
00923 BSUtilities::Rational<1, 2> >::Mult
00924 (std::sqrt(standard_value ()));
00925 }
00926
00928
00931 std::ostream & print_value (std::ostream &os) const
00932 {return os << constant_value << " " << SU::Symbol ();}
00933
00934 void operator>> (std::string &str) const
00935 {str = BSUtilities::Conversion<UniqueConstant>::to_string
00936 (*this);}
00937 std::ostream & operator>> (std::ostream &os) const
00938 {return this->print (os);}
00939
00940 };
00941
00942 }
00943
00944 #endif