00001 00005 /* Copyright (C) 2006, Bernd Speiser */ 00006 /* This file is part of Quantity. 00007 00008 Quantity is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU General Public License 00010 as published by the Free Software Foundation; either version 2 00011 of the License, or (at your option) any later version. 00012 00013 Quantity is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00021 02111-1307, USA. 00022 */ 00023 00024 #ifndef _DedimensionalizedVariable_h 00025 #define _DedimensionalizedVariable_h 00026 00027 #include "Quantity/Unit.h" 00028 #include "Quantity/Variable.h" 00029 #include "Quantity/Dedimensionalization.h" 00030 00031 #include "Functor.h" 00032 #include "NullType.h" 00033 #include "Typelist.h" 00034 #include "HierarchyGenerators.h" 00035 00036 namespace quantity { 00037 00039 // 00040 // Helper classes and structs 00041 // 00043 00044 typedef BSUtilities::Rational<0> DedimensionalizedLE; 00045 typedef BSUtilities::Rational<0> DedimensionalizedM; 00046 typedef BSUtilities::Rational<0> DedimensionalizedTI; 00047 typedef BSUtilities::Rational<0> DedimensionalizedE; 00048 typedef BSUtilities::Rational<0> DedimensionalizedTE; 00049 typedef BSUtilities::Rational<0> DedimensionalizedA; 00050 typedef BSUtilities::Rational<0> DedimensionalizedLU; 00051 00053 00056 typedef dimension::Dimension<DedimensionalizedLE, DedimensionalizedM, 00057 DedimensionalizedTI, DedimensionalizedE, DedimensionalizedTE, 00058 DedimensionalizedA, DedimensionalizedLU> 00059 DedimensionalizedVariableDimension; 00060 } 00061 00062 namespace unit { 00064 class DedimensionalizedUnit; 00065 00067 class DedimensionalizedUnityUnit; 00068 00069 typedef NonPrefixable<DedimensionalizedUnit, DedimensionalizedUnityUnit> 00070 DedimensionalizedUnity; 00071 00072 typedef LOKI_TYPELIST_1(DedimensionalizedUnity) DedimensionalizedUnits; 00073 00074 } 00075 00076 namespace quantity { 00077 00079 // 00080 // the DedimensionalizedVariable classes 00081 // 00083 00085 00093 template<class PQ, class SU = typename PQ::DefaultUnit::Unit, 00094 class DD = typename DefaultDedimensionalizer<PQ, SU>::F> 00095 class DedimensionalizedVariable; 00096 00098 00103 template<long RL_N, long RL_D, long RM_N, long RM_D, 00104 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D, 00105 long RA_N, long RA_D, long RLU_N, long RLU_D, 00106 class BT, class UL, class DU, class SU, class ST, class R, 00107 class DDH, class DDT> 00108 class DedimensionalizedVariable< 00109 Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>, 00110 BSUtilities::Rational<RM_N, RM_D>, 00111 BSUtilities::Rational<RT_N, RT_D>, 00112 BSUtilities::Rational<RE_N, RE_D>, 00113 BSUtilities::Rational<RTE_N, RTE_D>, 00114 BSUtilities::Rational<RA_N, RA_D>, 00115 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>, 00116 SU, Loki::Functor<R, Loki::Typelist<DDH, DDT> > > 00117 : public Quantity<DedimensionalizedVariableDimension, 00118 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 00119 unit::DedimensionalizedUnity, ST> 00120 { 00121 public: 00123 00125 typedef DedimensionalizedVariableDimension DIM; 00126 00128 typedef typename Loki::Typelist<DDH, DDT> DDL; 00129 00131 00138 typedef typename Loki::TL::TypeAt<DDL, 0>::Result DDP; 00139 00141 typedef typename Loki::Functor<R, DDL> DD; 00142 00144 00147 typedef Quantity<DedimensionalizedVariableDimension, 00148 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 00149 unit::DedimensionalizedUnity, ST> ABQ; 00150 00152 typedef Variable< 00153 Quantity<dimension::Dimension< 00154 BSUtilities::Rational<RL_N, RL_D>, 00155 BSUtilities::Rational<RM_N, RM_D>, 00156 BSUtilities::Rational<RT_N, RT_D>, 00157 BSUtilities::Rational<RE_N, RE_D>, 00158 BSUtilities::Rational<RTE_N, RTE_D>, 00159 BSUtilities::Rational<RA_N, RA_D>, 00160 BSUtilities::Rational<RLU_N, RLU_D> >, 00161 BT, UL, DU, ST>, SU, DD> V; 00162 00164 00170 typedef Quantity<dimension::Dimension< 00171 BSUtilities::Rational<RL_N, RL_D>, 00172 BSUtilities::Rational<RM_N, RM_D>, 00173 BSUtilities::Rational<RT_N, RT_D>, 00174 BSUtilities::Rational<RE_N, RE_D>, 00175 BSUtilities::Rational<RTE_N, RTE_D>, 00176 BSUtilities::Rational<RA_N, RA_D>, 00177 BSUtilities::Rational<RLU_N, RLU_D> >, 00178 BT, UL, DU, ST> PQ; 00179 00181 00183 typedef 00184 typename unit::CheckUnit<unit::Unit<BT>, SU>::Check Unit; 00185 00186 00188 typedef typename BSUtilities::IF<BSUtilities::SameType 00189 <DD, typename DefaultDedimensionalizer<PQ, SU>::F>::sameType, 00190 DedimReturn<PQ, SU>, V>::RET DDR; 00191 00192 private: 00194 00198 static DDR defaultDedimensionalizer (DDP) {return DDR(ST(1.));} 00199 00201 00203 static const DD _defaultDD; 00204 00206 00213 DD _dedimensionalizer; 00214 00216 00220 ST _value; 00221 00222 public: 00224 00227 DedimensionalizedVariable (void) 00228 : ABQ(), _dedimensionalizer (_defaultDD), _value (ST(0)){} 00229 00231 00234 DedimensionalizedVariable (const DD &dedimensionalizer) 00235 : ABQ (), _dedimensionalizer (dedimensionalizer), 00236 _value (ST(0)) {} 00237 00239 00244 DedimensionalizedVariable (const ST value) 00245 : ABQ (), _dedimensionalizer (_defaultDD), _value (value) {} 00246 00248 00253 DedimensionalizedVariable 00254 (const ST value, const DD &dedimensionalizer) 00255 : ABQ (), _dedimensionalizer (dedimensionalizer), 00256 _value (value) {} 00257 00259 00264 DedimensionalizedVariable 00265 (const V &value, const V &dedimensionalizationValue, 00266 const DD &dedimensionalizer) 00267 : ABQ (), _dedimensionalizer (dedimensionalizer) , 00268 _value (value.value ()/dedimensionalizationValue.value ()) 00269 {} 00270 00272 00275 template<class SU1> 00276 DedimensionalizedVariable 00277 (const V &value, const Variable< 00278 Quantity<dimension::Dimension< 00279 BSUtilities::Rational<RL_N, RL_D>, 00280 BSUtilities::Rational<RM_N, RM_D>, 00281 BSUtilities::Rational<RT_N, RT_D>, 00282 BSUtilities::Rational<RE_N, RE_D>, 00283 BSUtilities::Rational<RTE_N, RTE_D>, 00284 BSUtilities::Rational<RA_N, RA_D>, 00285 BSUtilities::Rational<RLU_N, RLU_D> >, 00286 BT, UL, DU, ST>, SU1> 00287 &dedimensionalizationValue, const DD &dedimensionalizer) 00288 : ABQ (), _dedimensionalizer (dedimensionalizer), 00289 _value (value.value ()/ Reverse<SU, ST>::VAL 00290 (dedimensionalizationValue.standard_value())) {} 00291 00293 00296 DedimensionalizedVariable 00297 (const DedimensionalizedVariable &variable) 00298 : ABQ (), _dedimensionalizer (variable._dedimensionalizer), 00299 _value (variable.value ()) 00300 {ABQ::namestring = variable.name (); 00301 ABQ::symbolstring = variable.symbol (); 00302 } 00303 00306 // dedimensionalizationValue; then copy the name and symbol string 00307 //*/ 00308 // template<template<class, class> class Q1> 00309 // DedimensionalizedVariable (const Q1<PQ, unit::DedimensionalizedUnity> 00310 // &quantity) 00311 // : ABQ (), _value (quantity.value ()) 00312 // {ABQ::namestring = quantity.name (); 00313 // ABQ::symbolstring = quantity.symbol (); 00314 // } 00315 // 00318 // unit list typical for a generated quantity using a GenericUnit; 00319 // this special case is the only exception when a quantity of 00320 // different base unit type can be converted into the target 00321 // dedimensionalized variable, 00322 // provided the dimensions of the two objects are equal. This is 00323 // tested with CheckSecondDimension. 00324 // It is assumed that the storage type of the two objects is identical. 00325 //*/ 00326 // template<template<class, class> class Q1, 00327 // class BT1, class DIM1, class DU1, class SU1> 00328 // DedimensionalizedVariable (const Q1<Quantity<DIM1, BT1, 00329 // Loki::Typelist<unit::NonPrefixable<BT1, unit::GenericUnit>, 00330 // Loki::NullType>, DU1, ST>, SU1> &quantity, 00331 // V dedimensionalizationValue) 00332 // : ABQ (), _value (Reverse<Unit, ST>::VAL 00333 // (Standardize<typename 00334 // CheckSecondDimension<DedimensionalizedVariable, 00335 // Q1<Quantity<DIM1, BT1, 00336 // Loki::Typelist<unit::NonPrefixable<BT1, 00337 // unit::GenericUnit>, Loki::NullType>, 00338 // DU1, ST>, SU1> >::RET::Unit, ST>::VAL 00339 // (quantity.value ())/ 00340 // dedimensionalizationValue.standard_value ())) 00341 // {namestring = quantity.name (); 00342 // symbolstring = quantity.symbol (); 00343 // } 00344 // 00347 // dimensional information in Dynamic; the Dynamic must have the 00348 // same dimension as dedimensionalizationValue; 00349 //*/ 00350 // DedimensionalizedVariable 00351 // (const Dynamic<ST> &dynamic, V &dedimensionalizationValue) 00352 // : ABQ () 00353 // {if (dynamic._rl_n == RL_N && dynamic._rl_d == RL_D 00354 // && dynamic._rm_n == RM_N && dynamic._rm_d == RM_D 00355 // && dynamic._rt_n == RT_N && dynamic._rt_d == RT_D 00356 // && dynamic._re_n == RE_N && dynamic._re_d == RE_D 00357 // && dynamic._rte_n == RTE_N && dynamic._rte_d == RTE_D 00358 // && dynamic._ra_n == RA_N && dynamic._ra_d == RA_D 00359 // && dynamic._rlu_n == RLU_N 00360 // && dynamic._rlu_d == RLU_D) 00361 // _value = dynamic.value ()/ 00362 // dedimensionalizationValue.standard_value (); 00363 // 00364 // else 00365 // {throw DimensionMismatch ();} 00366 // 00367 // } 00368 // 00371 // can be done by direct comparison of pointers; no need to convert 00372 // values, since unit must be the same; raw value of new_variable 00373 // is used, since no conversion into default unit is desired; 00374 // only the variable value and the dedimensionalization value are assigned, 00375 // name and symbol are not touched. 00376 //*/ 00377 // DedimensionalizedVariable & operator= 00378 // (const DedimensionalizedVariable &new_variable) 00379 // {if (this != &new_variable) 00380 // {_value = new_variable.value (); 00381 // } 00382 // 00383 // return *this; 00384 // } 00385 // 00388 //?????????????????? correct ??????????????????????????? 00389 // if trying to instantiate, PQ and PQ1 should be different, since 00390 // the case of PQ and PQ1 being the same type is handled by the 00391 // assignment operator given above. Thus, 00392 // SameType<>::sameType is always false and the IF construct tries to 00393 // instantiate DimensionError<true> which is never defined. 00394 // Consequently, this should never be instantiated correctly. 00395 // This should also avoid assignment from GenericQuantity and Dynamic, 00396 // which is impossible since no dedimensionalizationValue can be supplied. 00397 //*/ 00398 // template<template<class, class> class Q1, class PQ1, class SU1> 00399 // DedimensionalizedVariable & operator= (const Q1<PQ1, SU1> &quantity) 00400 // { 00401 // static const bool RET = BSUtilities::IF<BSUtilities:: 00402 // SameType<DedimensionalizedVariable, Q1<PQ1, SU1> >::sameType, 00403 // AssignmentError<false>, AssignmentError<true> 00404 // >::RET::RET; 00405 // return *this; 00406 // } 00407 00409 00411 ST value (void) const {return _value;} 00412 00414 00417 ST standard_value (void) const {return _value;} 00418 00420 00424 ST value (const unit::DedimensionalizedUnity &) const 00425 {return _value;} 00426 00429 // Variable defining the DedimensionalizedVariable is returned with the 00430 // resulting value; since DedimensionalizedUnity 00431 // is the only unit and the standardization factor is unity, no 00432 // recalculation is necessary. 00433 //*/ 00434 // V deDimensionalize (V dedimensionalizationValue) const 00435 // {return V(_value * dedimensionalizationValue);} 00436 // 00439 // Consequently, when supplying an incorrect string for the symbol, 00440 // this can not be detected at compile time, but only at run time. 00441 // Only empty string is possible for symbol. If symbol is not found by 00442 // findBySymbol, a UnitMismatch exception is thrown. 00443 //*/ 00444 // ST value (const std::string &symbol) 00445 // { 00446 // ::unit::Unit<BT> *unitp = PQ::findBySymbol (symbol); 00447 // delete (unitp); 00448 // 00449 // return _value; 00450 // } 00451 // 00454 // present for analogy to Variable, just makes a copy. 00455 //*/ 00456 // DedimensionalizedVariable operator () 00457 // (const unit::DedimensionalizedUnity &) const 00458 // {return DedimensionalizedVariable (_value);} 00459 // 00461 00463 const std::string unitsymbol (void) const 00464 {return unit::DedimensionalizedUnity::Symbol ();} 00465 00467 00469 static std::string Unitsymbol (void) 00470 {return unit::DedimensionalizedUnity::Symbol ();} 00471 00473 00475 const std::string unitname (void) const 00476 {return unit::DedimensionalizedUnity::Name ();} 00477 00479 00481 static std::string Unitname (void) 00482 {return unit::DedimensionalizedUnity::Name ();} 00483 00485 00494 DedimensionalizedVariable & operator+= 00495 (const DedimensionalizedVariable &variable) 00496 {_value += variable.value (); 00497 return *this; 00498 } 00499 00501 00511 template <template<class, class> class Q1, class BT1, 00512 class DIM1, class DU1, class SU1> 00513 DedimensionalizedVariable & operator+= 00514 (const Q1<Quantity<DIM1, BT1, 00515 Loki::Typelist<unit::NonPrefixable<BT1, unit::GenericUnit>, 00516 Loki::NullType>, DU1, ST>, SU1> &quantity) 00517 {_value += 00518 Standardize<typename CheckSecondDimension< 00519 DedimensionalizedVariable, Q1<Quantity<DIM1, BT1, 00520 Loki::Typelist<unit::NonPrefixable<BT1, 00521 unit::GenericUnit>, Loki::NullType>, DU1, ST>, 00522 SU1> >::RET::Unit, ST>::VAL (quantity.value ()); 00523 return *this; 00524 } 00525 00527 00532 template<template<class, class> class Q1, class PQ1, class SU1> 00533 DedimensionalizedVariable & operator+= 00534 (const Q1<PQ1, SU1> &quantity) 00535 { 00536 static const bool RET = 00537 BSUtilities::IF<BSUtilities::SameType<PQ, PQ1>::sameType, 00538 DimensionError<false>, DimensionError<true> >::RET::RET; 00539 return *this; 00540 } 00541 00543 00552 DedimensionalizedVariable & operator-= 00553 (const DedimensionalizedVariable &new_variable) 00554 { 00555 _value -= new_variable.value (); 00556 return *this; 00557 } 00558 00561 // for a right hand side operand which is a generated quantity having a 00562 // generic unit and the same dimension as the left hand side operand; 00563 // value of both operands recalculated into standard unit, reverse 00564 // standardization of the result before stored in _value. 00565 //*/ 00566 // template <template<class, class> class Q1, class BT1, 00567 // class DIM1, class DU1, class SU1> 00568 // DedimensionalizedVariable & operator-= (const Q1<Quantity<DIM1, BT1, 00569 // Loki::Typelist<unit::NonPrefixable<BT1, unit::GenericUnit>, 00570 // Loki::NullType>, DU1, ST>, SU1> &quantity) 00571 // {_value -= 00572 // Standardize<typename CheckSecondDimension< 00573 // DedimensionalizedVariable, Q1<Quantity<DIM1, BT1, 00574 // Loki::Typelist<unit::NonPrefixable<BT1, 00575 // unit::GenericUnit>, Loki::NullType>, DU1, ST>, 00576 // SU1> >::RET::Unit, ST>::VAL 00577 // (quantity.value ()); 00578 // return *this; 00579 // } 00580 // 00583 // where the second is NOT a generated quantity; should never compile, 00584 // but rather yield a DimensionError<true> compiler error message 00585 //*/ 00586 // template<template<class, class> class Q1, class PQ1, class SU1> 00587 // DedimensionalizedVariable & operator-= (const Q1<PQ1, SU1> &quantity) 00588 // { 00589 // static const bool RET = 00590 // BSUtilities::IF<BSUtilities::SameType<PQ, PQ1>::sameType, 00591 // DimensionError<false>, DimensionError<true> >::RET::RET; 00592 // return *this; 00593 // } 00594 // 00597 // assigned to a ST in general 00598 //*/ 00599 // DedimensionalizedVariable & operator*= (const ST factor) 00600 // {_value *= factor; 00601 // return *this; 00602 // } 00603 // 00606 // operation with a left hand side ST can not be assigned to a ST 00607 // in general 00608 //*/ 00609 // DedimensionalizedVariable & operator/= (const ST divisor) 00610 // {_value /= divisor; 00611 // return *this; 00612 // } 00613 // 00615 00617 DedimensionalizedVariable operator+ (void) const 00618 {return DedimensionalizedVariable (*this);} 00619 00621 00623 DedimensionalizedVariable operator- (void) const 00624 {return DedimensionalizedVariable (*this) *= ST(-1.0);} 00625 00627 00631 template <template<class, class> class Q1, class DIM1, 00632 class BT1, class UL1, class DU1, class SU1> 00633 DedimensionalizedVariable operator+ 00634 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> &quantity) 00635 const 00636 {DedimensionalizedVariable new_object (*this); 00637 return new_object += quantity; 00638 } 00639 00642 // side of the operator; this is converted into an object of the left 00643 // hand side type; this is only successful at run time, if the Dynamic 00644 // object is commensurate; failure is indicated by a DimensionMismatch 00645 // exception; finally addition is forwarded to the `generic' addition 00646 // operator above. 00647 //*/ 00648 // DedimensionalizedVariable operator+ (const Dynamic<ST> &quantity) const 00649 // {DedimensionalizedVariable new_variable (quantity); 00650 // return *this + new_variable; 00651 // } 00652 // 00653 // 00655 00659 template <template<class, class> class Q1, class DIM1, 00660 class BT1, class UL1, class DU1, class SU1> 00661 DedimensionalizedVariable operator- 00662 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> &quantity) 00663 const 00664 {DedimensionalizedVariable new_object (*this); 00665 return new_object -= quantity; 00666 } 00667 00670 // side of the operator; this is converted into an object of the left 00671 // hand side type; this is only successful at run time, if the Dynamic 00672 // object is commensurate; failure is indicated by a DimensionMismatch 00673 // exception; finally addition is forwarded to the `generic' addition 00674 // operator above. 00675 //*/ 00676 // DedimensionalizedVariable operator- (const Dynamic<ST> &quantity) const 00677 // {DedimensionalizedVariable new_variable (quantity); 00678 // return *this - new_variable; 00679 // } 00680 // 00683 //*/ 00684 // DedimensionalizedVariable operator* (const ST factor) const 00685 // {DedimensionalizedVariable new_object (*this); 00686 // return new_object *= factor; 00687 // } 00688 // 00691 //*/ 00692 // DedimensionalizedVariable operator/ (const ST divisor) const 00693 // {DedimensionalizedVariable new_object (*this); 00694 // return new_object /= divisor; 00695 // } 00696 // 00699 // conversions, this may also work for factors with a type different 00700 // from ST, as long as it can be matched; 00701 // out of class declaration without friend does not work with 00702 // factor type different from storage type, since in that case 00703 // first the template argument ST is deducted from the first 00704 // function argument, and 'this deduction does not consider ... 00705 // conversions' (Vandevoorde/Josuttis, p. 489); 00706 // second argument can be quantity object of any mode. 00707 //*/ 00708 // template <template<class, class> class Q1> 00709 // friend DedimensionalizedVariable operator* 00710 // (const ST factor, 00711 // const Q1<PQ, unit::DedimensionalizedUnity> &variable) 00712 // {return DedimensionalizedVariable (variable) *= factor;} 00713 00715 00720 bool operator== 00721 (const DedimensionalizedVariable &rhs_variable) const 00722 {return _value == rhs_variable.value ();} 00723 00725 00731 template <template<class, class> class Q1, 00732 class DIM1, class BT1, class UL1, class DU1, class SU1> 00733 bool operator== 00734 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00735 &rhs_variable) const 00736 { 00737 return standard_value () == Standardize<typename 00738 CheckSecondDimension<DedimensionalizedVariable, 00739 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00740 >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00741 } 00742 00744 00749 bool operator!= 00750 (const DedimensionalizedVariable &rhs_variable) const 00751 {return _value != rhs_variable.value ();} 00752 00754 00760 template <template<class, class> class Q1, 00761 class DIM1, class BT1, class UL1, class DU1, class SU1> 00762 bool operator!= 00763 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00764 &rhs_variable) const 00765 { 00766 return standard_value () != Standardize<typename 00767 CheckSecondDimension<DedimensionalizedVariable, 00768 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00769 >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00770 } 00771 00774 // use value to retrieve the variabler value of the right hand side 00775 // Variable and directly compare to _value. 00776 //*/ 00777 // bool operator> (const DedimensionalizedVariable &rhs_variable) const 00778 // {return _value > rhs_variable.value ();} 00779 // 00782 // possibly different storage units SU and SU1; 00783 // compares the values in the standard unit; we can be sure 00784 // that values can be recalculated between SU and SU1. 00785 //*/ 00786 // template <template<class, class> class Q1, class SU1> 00787 // bool operator> (const Q1<PQ, SU1> &rhs_variable) const 00788 // {return standard_value () > rhs_variable.standard_value (); 00789 // } 00790 // 00793 // compares the values in the standard unit; to check dimension, 00794 // the standardization call is generated through a compile time check; 00795 // this should handle generated transient quantities as rhs argument. 00796 //*/ 00797 // template <template<class, class> class Q1, 00798 // class DIM1, class BT1, class UL1, class DU1, class SU1> 00799 // bool operator> 00800 // (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00801 // &rhs_variable) const 00802 // { 00803 // return standard_value () > Standardize<typename 00804 // CheckSecondDimension<DedimensionalizedVariable, 00805 // Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00806 // >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00807 // } 00808 // 00811 // use value to retrieve the variabler value of the right hand side 00812 // Variable and directly compare to _value. 00813 //*/ 00814 // bool operator< (const DedimensionalizedVariable &rhs_variable) const 00815 // {return _value < rhs_variable.value ();} 00816 // 00819 // possibly different storage units SU and SU1; 00820 // compares the values in the standard unit; we can be sure 00821 // that values can be recalculated between SU and SU1. 00822 //*/ 00823 // template <template<class, class> class Q1, class SU1> 00824 // bool operator< (const Q1<PQ, SU1> &rhs_variable) const 00825 // {return standard_value () < rhs_variable.standard_value (); 00826 // } 00827 // 00830 // compares the values in the standard unit; to check dimension, 00831 // the standardization call is generated through a compile time check; 00832 // this should handle generated transient quantities as rhs argument. 00833 //*/ 00834 // template <template<class, class> class Q1, 00835 // class DIM1, class BT1, class UL1, class DU1, class SU1> 00836 // bool operator< 00837 // (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00838 // &rhs_variable) const 00839 // { 00840 // return standard_value () < Standardize<typename 00841 // CheckSecondDimension<DedimensionalizedVariable, 00842 // Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00843 // >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00844 // } 00845 // 00848 // use value to retrieve the variabler value of the right hand side 00849 // Variable and directly compare to _value. 00850 //*/ 00851 // bool operator>= (const DedimensionalizedVariable &rhs_variable) const 00852 // {return _value >= rhs_variable.value ();} 00853 // 00856 // possibly different storage units SU and SU1; 00857 // compares the values in the standard unit; we can be sure 00858 // that values can be recalculated between SU and SU1. 00859 //*/ 00860 // template <template<class, class> class Q1, class SU1> 00861 // bool operator>= (const Q1<PQ, SU1> &rhs_variable) const 00862 // {return standard_value () >= rhs_variable.standard_value (); 00863 // } 00864 // 00867 // compares the values in the standard unit; to check dimension, 00868 // the standardization call is generated through a compile time check; 00869 // this should handle generated transient quantities as rhs argument. 00870 //*/ 00871 // template <template<class, class> class Q1, 00872 // class DIM1, class BT1, class UL1, class DU1, class SU1> 00873 // bool operator>= 00874 // (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00875 // &rhs_variable) const 00876 // { 00877 // return standard_value () >= Standardize<typename 00878 // CheckSecondDimension<DedimensionalizedVariable, 00879 // Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00880 // >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00881 // } 00882 // 00885 // use value to retrieve the variabler value of the right hand side 00886 // Variable and directly compare to _value. 00887 //*/ 00888 // bool operator<= (const DedimensionalizedVariable &rhs_variable) const 00889 // {return _value <= rhs_variable.value ();} 00890 // 00893 // possibly different storage units SU and SU1; 00894 // compares the values in the standard unit; we can be sure 00895 // that values can be recalculated between SU and SU1. 00896 //*/ 00897 // template <template<class, class> class Q1, class SU1> 00898 // bool operator<= (const Q1<PQ, SU1> &rhs_variable) const 00899 // {return standard_value () <= rhs_variable.standard_value (); 00900 // } 00901 // 00904 // compares the values in the standard unit; to check dimension, 00905 // the standardization call is generated through a compile time check; 00906 // this should handle generated transient quantities as rhs argument. 00907 //*/ 00908 // template <template<class, class> class Q1, 00909 // class DIM1, class BT1, class UL1, class DU1, class SU1> 00910 // bool operator<= 00911 // (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00912 // &rhs_variable) const 00913 // { 00914 // return standard_value () <= Standardize<typename 00915 // CheckSecondDimension<DedimensionalizedVariable, 00916 // Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1> 00917 // >::RET::Unit, ST>::VAL (rhs_variable.value ()); 00918 // } 00919 // 00922 // adding the dimensions of the two quantities; 00923 // only GenerateVariable with two quantities as arguments does 00924 // have an Add typedef, thus, Q does not need to be specified. 00925 //*/ 00926 // template<class Q> 00927 // Q operator* (const Q &factor) const 00928 // {return Q (standard_value () * factor.standard_value ());} 00929 // 00932 // subtracting the dimensions of the two quantities; 00933 // only GenerateVariable with two quantities as arguments does 00934 // have an Sub typedef, thus, Q does not need to be specified. 00935 //*/ 00936 // template<class Q> 00937 // typename GenerateVariable<Q, Loki::NullType>::Inv 00938 // operator/ (const Q &factor) const 00939 // { 00940 // return typename 00941 // GenerateVariable<Q, Loki::NullType>::Inv 00942 // (standard_value () / factor.standard_value ()); 00943 // } 00944 // 00947 // negating the dimension of the variable; 00948 //*/ 00949 // friend typename 00950 // GenerateVariable<DedimensionalizedVariable, Loki::NullType>::Inv 00951 // operator/ (const ST numerator, 00952 // const DedimensionalizedVariable &factor) 00953 // { 00954 // return typename 00955 // GenerateVariable<DedimensionalizedVariable, Loki::NullType>::Inv 00956 // (numerator / factor.standard_value ()); 00957 // } 00958 // 00961 // first argument multiplied by Rational<N, D>; 00962 // used as object.pow (r); 00963 // forwards action to pow function with quantity and rational 00964 // exponent (in namespace quantities). 00965 //*/ 00966 // template<long N, long D> 00967 // typename GenerateVariable<DedimensionalizedVariable, 00968 // BSUtilities::Rational<N, D> >::Mult 00969 // pow (const BSUtilities::Rational<N, D> &) 00970 // {return 00971 // ::quantity::pow (*this, BSUtilities::Rational<N, D> ());} 00972 // 00975 // first argument multiplied by I; 00976 // used as object.pow (r); 00977 // forwards action to pow function with quantity and static integer 00978 // exponent (in namespace quantities). 00979 //*/ 00980 // template<int I> 00981 // typename GenerateVariable<DedimensionalizedVariable, 00982 // BSUtilities::Rational<I, long(1)> >::Mult 00983 // pow (typename Loki::Int2Type<I>) 00984 // {return ::quantity::pow (*this, Loki::Int2Type<I> ());} 00985 // 00988 // first argument multiplied by exp; 00989 // alternative formulation; 00990 // forwards action to pow function with quantity and dynamic 00991 // exponent (friend functions in Dynamic for specific T's). 00992 //*/ 00993 // template<class T> 00994 // Dynamic<ST> pow (const T &exp) const 00995 // {return ::quantity::pow (*this, exp);} 00996 // 00999 //*/ 01000 // friend typename 01001 // GenerateVariable<DedimensionalizedVariable, 01002 // BSUtilities::Rational<1, 2> >::Mult sqrt 01003 // (const DedimensionalizedVariable &variable) 01004 // { 01005 // return typename 01006 // GenerateVariable<DedimensionalizedVariable, 01007 // BSUtilities::Rational<1, 2> >::Mult 01008 // (std::sqrt(variable.standard_value ())); 01009 // } 01010 // 01013 //*/ 01014 // typename GenerateVariable<DedimensionalizedVariable, 01015 // BSUtilities::Rational<1, 2> >::Mult sqrt (void) const 01016 // { 01017 // return typename 01018 // GenerateVariable<DedimensionalizedVariable, 01019 // BSUtilities::Rational<1, 2> >::Mult 01020 // (std::sqrt(standard_value ())); 01021 // } 01022 01024 01028 std::ostream & print_value (std::ostream &os) const 01029 {return os << _value << " " 01030 << unit::DedimensionalizedUnity::Symbol ();} 01031 01033 01035 void operator>> (std::string &str) const 01036 {str = BSUtilities::Conversion<DedimensionalizedVariable>::to_string 01037 (*this);} 01038 01040 01044 std::ostream & operator>> (std::ostream &os) const 01045 {return this->print (os);} 01046 // 01049 //*/ 01050 // void read_value (const std::string &str); 01051 // 01054 //*/ 01055 // friend void operator>> 01056 // (const std::string &str, DedimensionalizedVariable &variable) 01057 // {variable.read_value (str);} 01058 // 01060 // void operator<< (const std::string &str) {read_value (str);} 01061 // 01063 // void operator= (const std::string &str) {this->read_value (str);} 01064 // 01067 // are subsequently interpreted with read_value; the reference to 01068 // the istream object is returned to allow chaining. 01069 //*/ 01070 // std::istream & operator<< (std::istream &is) 01071 // {std::string string; getline (is, string); 01072 // this->read_value (string); return is;} 01073 // 01076 // object; uses read from istream to the right of operator<<. 01077 //*/ 01078 // friend std::istream & operator>> 01079 // (std::istream &is, DedimensionalizedVariable &variable) 01080 // {return variable << is;} 01081 // 01082 01084 01088 void save (BSUtilities::xmlw::XmlStream &os) const 01089 { 01090 os << BSUtilities::xmlw::tag (Quantities::TAG) 01091 << BSUtilities::xmlw::attr (Quantities::MODETAG) << MODE 01092 // to be added ... 01093 << BSUtilities::xmlw::endtag (Quantities::TAG); 01094 } 01095 01097 01100 void load (const TiXmlHandle node) const 01101 { 01102 TiXmlElement *element = node.Element(); 01103 01104 if (element 01105 && (element->ValueStr () == Quantities::TAG) 01106 && (element->Attribute(Quantities::MODETAG) == MODE)) 01107 { 01108 // to be added ... 01109 } 01110 else 01111 throw LoadError 01112 ("error loading dedimensionalized variable quantity: incorrect element"); 01113 } 01114 01116 01120 // PQ (???) * create (void) {return new DedimensionalizedVariable;} 01121 // to be implemented 01122 01124 01126 static const std::string MODE; 01127 01128 }; 01129 01131 template<long RL_N, long RL_D, long RM_N, long RM_D, 01132 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D, 01133 long RA_N, long RA_D, long RLU_N, long RLU_D, 01134 class BT, class UL, class DU, class SU, class ST, class R, 01135 class DDH, class DDT> 01136 const std::string DedimensionalizedVariable< 01137 Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>, 01138 BSUtilities::Rational<RM_N, RM_D>, 01139 BSUtilities::Rational<RT_N, RT_D>, 01140 BSUtilities::Rational<RE_N, RE_D>, 01141 BSUtilities::Rational<RTE_N, RTE_D>, 01142 BSUtilities::Rational<RA_N, RA_D>, 01143 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>, 01144 SU, Loki::Functor<R, Loki::Typelist<DDH, DDT> > > ::MODE = 01145 "dedimensionalizedVariable"; 01146 01147 template<long RL_N, long RL_D, long RM_N, long RM_D, 01148 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D, 01149 long RA_N, long RA_D, long RLU_N, long RLU_D, 01150 class BT, class UL, class DU, class SU, class ST, class R, 01151 class DDH, class DDT> 01152 const typename Loki::Functor<R, typename Loki::Typelist<DDH, DDT> > 01153 DedimensionalizedVariable< 01154 Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>, 01155 BSUtilities::Rational<RM_N, RM_D>, 01156 BSUtilities::Rational<RT_N, RT_D>, 01157 BSUtilities::Rational<RE_N, RE_D>, 01158 BSUtilities::Rational<RTE_N, RTE_D>, 01159 BSUtilities::Rational<RA_N, RA_D>, 01160 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>, 01161 SU, Loki::Functor<R, Loki::Typelist<DDH, DDT> > >::_defaultDD = 01162 typename Loki::Functor<R, typename Loki::Typelist<DDH, DDT> > 01163 (defaultDedimensionalizer); 01164 01166 // important note: if a name is to be read, a corresponding string 01167 // token has to be present, similar for symbol! 01168 // */ 01169 //template<long RL_N, long RL_D, long RM_N, long RM_D, 01170 // long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D, 01171 // long RA_N, long RA_D, long RLU_N, long RLU_D, 01172 // class BT, class UL, class DU, class SU, class ST, class NFL> 01173 // void DedimensionalizedVariable< 01174 // Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>, 01175 // BSUtilities::Rational<RM_N, RM_D>, 01176 // BSUtilities::Rational<RT_N, RT_D>, 01177 // BSUtilities::Rational<RE_N, RE_D>, 01178 // BSUtilities::Rational<RTE_N, RTE_D>, 01179 // BSUtilities::Rational<RA_N, RA_D>, 01180 // BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>, 01181 // SU, 01182 // Loki::Functor<Variable< 01183 // Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>, 01184 // BSUtilities::Rational<RM_N, RM_D>, 01185 // BSUtilities::Rational<RT_N, RT_D>, 01186 // BSUtilities::Rational<RE_N, RE_D>, 01187 // BSUtilities::Rational<RTE_N, RTE_D>, 01188 // BSUtilities::Rational<RA_N, RA_D>, 01189 // BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, 01190 // ST>, SU>, NFL> >::read_value 01191 // (const std::string &str) 01192 // { 01193 // std::string value; 01194 // std::string unit; 01195 // 01196 // std::string::size_type start; 01197 // std::string::size_type end; 01198 // 01199 // start = str.find_first_not_of (" \0"); 01200 // end = start; 01201 // 01202 // if (RS.name ()) 01203 // { 01204 // if (start == std::string::npos) 01205 // throw InputError (); 01206 // 01207 // else 01208 // { 01209 // end = str.find_first_of (" \0", start); 01210 // 01211 // if (end == std::string::npos) 01212 // namestring = str.substr (start); 01213 // 01214 // else 01215 // namestring = (str.substr (start, end - start)); 01216 // } 01217 // } 01218 // 01219 // start = str.find_first_not_of (" \0", end); 01220 // end = start; 01221 // 01222 // if (RS.symbol ()) 01223 // { 01224 // if (start == std::string::npos) 01225 // throw InputError (); 01226 // 01227 // else 01228 // { 01229 // end = str.find_first_of (" \0", start); 01230 // 01231 // if (end == std::string::npos) 01232 // symbolstring = str.substr (start); 01233 // 01234 // else 01235 // symbolstring = (str.substr (start, end - start)); 01236 // } 01237 // } 01238 // 01239 // start = str.find_first_not_of (" \0", end); 01240 // end = start; 01241 // 01242 // if (RS.equal () && (RS.name () || RS.symbol ())) 01243 // { 01244 // if (start == std::string::npos) 01245 // throw InputError (); 01246 // 01247 // else 01248 // { 01249 // end = str.find_first_of (" \0", start); 01250 // 01251 // if (end == std::string::npos) 01252 // throw InputError (); 01253 // 01254 // else if (str.substr (start, end - start) != "=") 01255 // throw InputError (); 01256 // } 01257 // } 01258 // 01259 // start = str.find_first_not_of (" \0", end); 01260 // end = start; 01261 // 01262 // if (start == std::string::npos) 01263 // throw InputError (); 01264 // 01265 // else 01266 // { 01267 // end = str.find_first_of (" \0", start); 01268 // 01269 // if (end == std::string::npos) 01270 // value = str.substr (start); 01271 // 01272 // else 01273 // value = str.substr (start, end - start); 01274 // 01275 // start = str.find_first_not_of (" \0", end); 01276 // 01277 // if (start == std::string::npos) 01278 // unit = ""; 01279 // 01280 // else 01281 // { 01282 // end = str.find_first_of (" \0\n", start); 01283 // 01284 // if (end = std::string::npos) 01285 // unit = str.substr (start); 01286 // 01287 // else 01288 // unit = str.substr (start, end - start); 01289 // } 01290 // } 01291 // 01292 // ST intermediate; 01293 // 01294 // try { 01295 // intermediate = BSUtilities::Conversion<ST>::string_to (value); 01296 // } 01297 // 01298 // catch (BSUtilities::ConversionFailure) {throw InputError ();} 01299 // 01300 // start = unit.find_first_not_of (" \0"); 01301 // end = start; 01302 // 01304 // storage unit 01305 //*/ 01306 // if (start == std::string::npos) 01307 // { 01308 // std::string assume_unit; 01309 // 01311 // (value); else do nothing, since we assume that the value is in 01312 // the storage unit and can be stored directly. 01313 //*/ 01314 // if ((assume_unit = RS.unit ()) != "") 01315 // { 01316 // try { 01317 // ::unit::Unit<BT> *unitp = PQ::findBySymbol (assume_unit); 01318 // intermediate 01319 // = Reverse<SU, ST>::VAL 01320 // (dynamic_standardize<UL>::VAL (intermediate, *unitp)); 01321 // 01322 // delete (unitp); 01323 // } 01324 // 01325 // catch (UnitMismatch) {throw InputError ();} 01326 // 01327 // } 01328 // } 01329 // 01331 // of intermediate (value) 01332 //*/ 01333 // else 01334 // { 01335 // end = unit.find_first_of (" \0", start); 01336 // try { 01337 // ::unit::Unit<BT> *unitp 01338 // = PQ::findBySymbol (unit.substr (start, end - start)); 01339 // 01340 // intermediate 01341 // = Reverse<SU, ST>::VAL 01342 // (dynamic_standardize<UL>::VAL (intermediate, *unitp)); 01343 // 01344 // delete (unitp); 01345 // } 01346 // catch (UnitMismatch) {throw InputError ();} 01347 // } 01348 // 01349 // 01350 // 01351 // } 01352 01354 template<class ST> 01355 struct Name<Quantity<DedimensionalizedVariableDimension, 01356 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 01357 unit::DedimensionalizedUnity, ST> > 01358 { 01359 static const std::string String; 01360 }; 01361 01363 template<class ST> 01364 const std::string 01365 Name<Quantity<DedimensionalizedVariableDimension, 01366 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 01367 unit::DedimensionalizedUnity, ST> >::String = ""; 01368 01370 template<class ST> 01371 struct Symbol<Quantity<DedimensionalizedVariableDimension, 01372 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 01373 unit::DedimensionalizedUnity, ST> > 01374 { 01375 static const std::string String; 01376 }; 01377 01379 template<class ST> 01380 const std::string 01381 Symbol<Quantity<DedimensionalizedVariableDimension, 01382 unit::DedimensionalizedUnit, unit::DedimensionalizedUnits, 01383 unit::DedimensionalizedUnity, ST> >::String = ""; 01384 } 01385 01386 #endif /* _DedimensionalizedVariable_h */