00001 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef _Variable_h
00025 #define _Variable_h
00026 
00027 #include "Quantity/Quantity.h"
00028 #include "Quantity/Generic.h"
00029 
00030 namespace Quantities {
00031 
00033 
00034 
00035 
00037 
00039 
00042 template<class Q1, class Q2> struct GenerateVariable;
00043 
00045 
00046 
00047 
00049 
00051 
00055 template<class PQ, class SU = typename PQ::DefaultUnit::Unit> 
00056                                                         class Variable;
00058 
00061 template<class GT, class Head, class Tail, class DU, class SU, class ST>
00062   class Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, SU>
00063               : public Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>
00064     {
00065       private:
00067 
00071         typedef typename 
00072                Units::CheckUnit<Units::Unit<GT, ST>, SU>::Check Checked;
00073       public:
00075 
00077         typedef Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST> PQ;
00078 
00080         typedef SU Unit;
00081 
00082       protected:
00084 
00087         ST variable_value;
00088 
00089       public:
00091 
00094         Variable (void) : variable_value (ST(0.0)) {};
00095 
00097 
00099         Variable (const ST new_value) : variable_value (new_value) {}
00100 
00102 
00105         Variable (const ST new_value, const SU &) 
00106                                         : variable_value (new_value) {}
00107             
00108 
00110 
00116         template<class NU>
00117           Variable (const ST new_value, const NU &) 
00118             : PQ (), variable_value (SU::Reverse 
00119               (CheckAgainstAllUnits<NU, Loki::Typelist<Head, Tail> 
00120                                        >::RET::Standard (new_value))) {}
00121 
00123 
00128         Variable (const ST new_value, const std::string &unitsymbol) 
00129             : PQ ()
00130         { 
00131           ::Units::Unit<GT, ST> *unitp = PQ::findBySymbol (unitsymbol);
00132           variable_value = SU::Reverse (unitp->standard (new_value));
00133 
00134           delete (unitp);
00135         }
00136 
00138 
00143         Variable (const ST new_value, const char * unitsymbol) 
00144             : PQ ()
00145         { 
00146           ::Units::Unit<GT, ST> *unitp 
00147                           = PQ::findBySymbol (std::string (unitsymbol));
00148           variable_value = SU::Reverse (unitp->standard (new_value));
00149 
00150           delete (unitp);
00151         }
00152 
00154 
00157         Variable (const Variable &new_variable) 
00158           : PQ (), variable_value (new_variable.variable_value)
00159             { 
00160               namestring = new_variable.namestring;
00161               symbolstring = new_variable.symbolstring;
00162             }
00163  
00165 
00177         template<template<class, class> class Q1, class SU1>
00178             Variable (const Q1<PQ, SU1> &source_quantity)
00179             : PQ (), variable_value (SU::Reverse 
00180               (SU1::Standard (source_quantity.value ())))
00181               { 
00182                 namestring = source_quantity.name ();
00183                 symbolstring = source_quantity.symbol ();
00184               }
00185 
00187 
00195         template<template<class, class> class Q1, class GT1, 
00196                                                    class DU1, class SU1>
00197           Variable (const Q1<Quantity<GT1, 
00198             Loki::Typelist<Units::NonPrefixable<GT1, 
00199               Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1> 
00200                                                        &source_quantity)
00201             : PQ (), variable_value (Unit::Reverse 
00202               (Units::NonPrefixable<typename
00203                  CheckSecondDimension<Variable<PQ, SU>, 
00204                    Q1<Quantity<GT1, Loki::Typelist<Units::NonPrefixable
00205                       <GT1, Units::GenericUnit, ST>, 
00206                         Loki::NullType>, DU1, ST>, SU1> >::RET::Type, 
00207                           Units::GenericUnit, ST>::Standard 
00208                                         (source_quantity.value ())))
00209               { 
00210                 namestring = source_quantity.name ();
00211                 symbolstring = source_quantity.symbol ();
00212               }
00213 
00215 
00220         template<template<class, class> class Q1, class PQ1, class SU1>
00221                                         Variable (const Q1<PQ1, SU1> &);
00222 
00224 
00227         ST standard_value (void) const 
00228                                  {return SU::Standard (variable_value);}
00229 
00231 
00233         ST value (void) const {return variable_value;}
00234 
00236 
00241         template<class NU>
00242           ST value (const Units::NonPrefixable<GT, NU, ST> &) const 
00243             {return 
00244               CheckAgainstAllUnits<Units::NonPrefixable<GT, NU, ST>, 
00245                 Loki::Typelist<Head, Tail> >::RET::Reverse 
00246                                        (SU::Standard (variable_value));}
00247 
00249 
00254         template<class NU, class P>
00255           ST value 
00256             (const Units::Prefixed<Units::Prefixable<GT, NU, ST>, P> &)
00257                                                                    const
00258             {return 
00259                CheckAgainstAllUnits
00260                      <Units::Prefixed<Units::Prefixable<GT, NU, ST>, P>,
00261                  Loki::Typelist<Head, Tail> >::RET::Reverse 
00262                                        (SU::Standard (variable_value));}
00263 
00265 
00270         template<class CUL, class EL>
00271           ST value 
00272             (const Units::Composed<Units::Compound<GT, CUL, ST>, EL> &)
00273                                                                    const
00274             {return 
00275               CheckAgainstAllUnits
00276                      <Units::Composed<Units::Compound<GT, CUL, ST>, EL>,
00277                 Loki::Typelist<Head, Tail> >::RET::Reverse 
00278                                        (SU::Standard (variable_value));}
00279 
00281 
00288         ST value (const std::string &symbol)
00289           {ST value;
00290             ::Units::Unit<GT, ST> *unitp = PQ::findBySymbol (symbol);
00291 
00292             value = unitp->reverse (SU::Standard (variable_value));
00293 
00294             delete (unitp);
00295 
00296             return value;
00297           }
00298 
00300 
00305         template<class NU>
00306           Variable<PQ, NU> operator () (const NU &) const 
00307             {return Variable<PQ, NU> (variable_value, SU());}
00308 
00310 
00312         const std::string unitsymbol (void) const 
00313                                                  {return SU::Symbol ();}
00314 
00316 
00318         static std::string Unitsymbol (void) {return SU::Symbol ();}
00319 
00321 
00323         const std::string unitname (void) const {return SU::Name ();}
00324 
00326 
00328         static std::string Unitname (void) {return SU::Name ();}
00329 
00331 
00349         template<template<class, class> class Q1, class SU1>
00350             Variable & operator= (const Q1<PQ, SU1> &source_quantity)
00351              {
00352                void *this_pointer = this;
00353                const void *new_pointer = &source_quantity;
00354 
00355                if (this_pointer != new_pointer)
00356                {
00357                  variable_value = SU::Reverse 
00358                          (SU1::Standard (source_quantity.value ()));
00359                }
00360 
00361                return *this;
00362              }
00363 
00365 
00385         template<template<class, class> class Q1, class GT1, 
00386                                                    class DU1, class SU1>
00387           Variable & operator= (const Q1<Quantity<GT1, 
00388             Loki::Typelist<Units::NonPrefixable<GT1, 
00389                 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
00390                                                        &source_quantity)
00391              {
00392                void *this_pointer = this;
00393                const void *new_pointer = &source_quantity;
00394 
00395                if (this_pointer != new_pointer)
00396                {
00397                  variable_value = SU::Reverse 
00398                    (Units::NonPrefixable<typename
00399                      CheckSecondDimension<Variable<PQ, SU>, 
00400                        Q1<Quantity<GT1, 
00401                          Loki::Typelist<Units::NonPrefixable<GT1,
00402                            Units::GenericUnit, ST>, Loki::NullType>, 
00403                              DU1, ST>, SU1> >::RET::Type, 
00404                                Units::GenericUnit, ST>::Standard
00405                                         (source_quantity.value ()));
00406                }
00407 
00408                return *this;
00409              }
00410 
00412 
00419         Variable & operator= (const Variable &new_variable)
00420           {
00421             if (this != &new_variable)
00422               {variable_value = new_variable.value ();}
00423 
00424             return *this;
00425           }
00426 
00428 
00436         template <template<class, class> class Q1, class SU1>
00437           Variable & operator+= (const Q1<PQ, SU1> &new_variable)
00438              {ST val = Unit::Standard (variable_value);
00439               variable_value = SU::Reverse (val += 
00440                              SU1::Standard (new_variable.value ()));
00441                return *this;
00442              }
00443 
00445 
00451         template <template<class, class> class Q1, class GT1, 
00452                                                    class DU1, class SU1>
00453           Variable & operator+= (const Q1<Quantity<GT1,
00454             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00455               ST>, Loki::NullType>, DU1, ST>, SU1> &new_variable)
00456              {ST val = Unit::Standard (variable_value);
00457               variable_value = SU::Reverse (val += 
00458                 Units::NonPrefixable<typename
00459                   CheckSecondDimension<Variable<PQ, SU>, 
00460                     Q1<Quantity<GT1, 
00461                       Loki::Typelist<Units::NonPrefixable<GT1, 
00462                         Units::GenericUnit, ST>, Loki::NullType>, 
00463                           DU1, ST>, SU1> >::RET::Type, 
00464                             Units::GenericUnit, ST>::Standard 
00465                                            (new_variable.value ()));
00466                return *this;
00467              }
00468 
00470 
00476         template <template<class, class> class Q1, 
00477               class GT1, class Head1, class Tail1, class DU1, class SU1>
00478           Variable & operator+= 
00479             (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, 
00480                                            DU1, ST>, SU1> &new_variable)
00481              {ST val = BSUtilities::IF<BSUtilities::SameType<SU,
00482                Units::NonPrefixable<GT, Units::GenericUnit, ST> 
00483                 >::sameType, SU, Units::UnitError<false> 
00484                   >::RET::Standard (variable_value);
00485               variable_value = SU::Reverse (val += 
00486                 CheckSecondDimension<Variable<PQ, SU>, 
00487                   Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, DU1, 
00488                     ST>, SU1> >
00489                      ::RET::Unit::Standard (new_variable.value ()));
00490                return *this;
00491              }
00492 
00494 
00502         template <template<class, class> class Q1, class SU1>
00503           Variable & operator-= (const Q1<PQ, SU1> &new_variable)
00504              {ST val = SU::Standard (variable_value);
00505                variable_value = SU::Reverse (val -=
00506                              SU1::Standard (new_variable.value ()));
00507                return *this;
00508              }
00509 
00511 
00517         template <template<class, class> class Q1, class GT1,
00518                                                    class DU1, class SU1>
00519           Variable & operator-= (const Q1<Quantity<GT1,
00520             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00521               ST>, Loki::NullType>, DU1, ST>, SU1> &new_variable)
00522              {ST val = SU::Standard (variable_value);
00523               variable_value = SU::Reverse (val -=
00524                 Units::NonPrefixable<typename
00525                   CheckSecondDimension<Variable<PQ, SU>,
00526                     Q1<Quantity<GT1, 
00527                       Loki::Typelist<Units::NonPrefixable<GT1,
00528                         Units::GenericUnit, ST>, Loki::NullType>, 
00529                           DU1, ST>, SU1> >::RET::Type, 
00530                                        Units::GenericUnit, ST>::Standard
00531                                            (new_variable.value ()));
00532                return *this;
00533              }
00534 
00536 
00542         template <class Q>
00543           Variable & operator-= (const Q &new_variable)
00544              {ST val = BSUtilities::IF<BSUtilities::SameType<Unit,
00545                Units::NonPrefixable<GT, Units::GenericUnit, ST> 
00546                  >::sameType, Unit, Units::UnitError<false> 
00547                                       >::RET::Standard (variable_value);
00548               variable_value = Unit::Reverse (val -=
00549                 CheckSecondDimension<Variable<PQ, SU>, Q>
00550                      ::RET::Unit::Standard (new_variable.value ()));
00551                return *this;
00552              }
00553 
00555         Variable & operator*= (const ST factor)
00556            {variable_value *= factor;
00557              return *this;
00558            }
00559 
00561         Variable & operator/= (const ST factor)
00562            {variable_value /= factor;
00563              return *this;
00564            }
00565   
00567 
00569         Variable operator+ (void) const
00570            {Variable<PQ, SU> new_variable (*this);
00571              return new_variable;
00572            }
00573 
00575 
00577         Variable operator- (void) const
00578            {Variable<PQ, SU> new_variable (*this);
00579              return new_variable *= -1.0;
00580            }
00581 
00583 
00587         template <class Q>
00588           Variable operator+ (const Q &new_variable) const
00589             {Variable<PQ, SU> new_object (*this);
00590               return new_object += new_variable;
00591             }
00592 
00594 
00598         template <class Q>
00599           Variable operator- (const Q &new_variable) const
00600             {Variable<PQ, SU> new_object (*this);
00601               return new_object -= new_variable;
00602             }
00603 
00605 
00607         Variable operator* (const ST factor) const
00608           {Variable<PQ, SU> new_object (*this);
00609             return new_object *= factor;
00610           }
00611 
00613 
00615         Variable operator/ (const ST factor) const
00616           {Variable<PQ, SU> new_object (*this);
00617             return new_object /= factor;
00618           }
00619 
00621 
00623         friend Variable operator* 
00624                 (const ST factor, const Variable &variable)
00625         {Variable<PQ, SU> new_variable (variable);
00626            return new_variable *= factor;
00627         }
00628 
00630 
00632         friend Variable abs (const Variable &variable)
00633         {Variable<PQ, SU> new_variable (variable);
00634            return new_variable.variable_value 
00635                                          = std::abs (variable.value ());
00636         }
00637 
00639 
00641         friend Variable ceil (const Variable &variable)
00642         {Variable<PQ, SU> new_variable (variable);
00643            return new_variable.variable_value 
00644                                         = std::ceil (variable.value ());
00645         }
00646 
00648 
00650         friend Variable floor (const Variable &variable)
00651         {Variable<PQ, SU> new_variable (variable);
00652            return new_variable.variable_value 
00653                                        = std::floor (variable.value ());
00654         }
00655 
00657 
00661         friend Variable modf 
00662                           (const Variable &variable, Variable *integral)
00663         {Variable<PQ, SU> new_variable (variable);
00664           ST i_ptr; 
00665             new_variable.variable_value 
00666                                 = std::modf (variable.value (), &i_ptr);
00667               Variable<PQ, SU> int_quantity (i_ptr); 
00668                 *integral = int_quantity; return new_variable;
00669         }
00670 
00672 
00674         friend Variable frexp (const Variable &variable, int *exponent)
00675         {Variable<PQ, SU> new_variable (variable);
00676            return new_variable.variable_value 
00677                              = std::frexp (variable.value (), exponent);
00678         }
00679 
00681 
00683         friend Variable ldexp (const Variable &variable, int exponent)
00684         {Variable<PQ, SU> new_variable (variable);
00685            return new_variable.variable_value 
00686                              = std::ldexp (variable.value (), exponent);
00687         }
00688 
00690 
00696         template <template<class, class> class Q1, class SU1>
00697           friend Variable fmod 
00698                 (const Variable &variable, const Q1<PQ, SU1> &quantity)
00699           {return Variable<PQ, SU>
00700             (SU::Reverse (std::fmod (variable.standard_value (), 
00701                                          quantity.standard_value ())));
00702           }
00703 
00705 
00710         template <template<class, class> class Q1, class GT1, 
00711                                                    class DU1, class SU1>
00712           friend Variable fmod 
00713             (const Variable &variable, const Q1<Quantity<GT1,
00714               Loki::Typelist<Units::NonPrefixable<GT1, 
00715                 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
00716                                                               &quantity)
00717             {
00718              return Variable<PQ,SU>
00719                (SU::Reverse 
00720                  (std::fmod (variable.standard_value (),
00721                    CheckSecondDimension<Variable<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                                                  (quantity.value ()))));
00727             }
00728 
00730 
00735         template <template<class, class> class Q1, class GT1, 
00736           class DU1, class SU1>
00737           friend Q1<Quantity<GT1, 
00738             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00739                                ST>, Loki::NullType>, DU1, ST>, SU1> fmod
00740             (const Q1<Quantity<GT1,
00741               Loki::Typelist<Units::NonPrefixable<GT1, 
00742                 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
00743                                  &variable1, const Variable &variable2)
00744             {
00745              return Q1<Quantity<GT1, 
00746                Loki::Typelist<Units::NonPrefixable<GT1, 
00747                  Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, 
00748                                                                     SU1>
00749                (SU1::Reverse (std::fmod (variable1.standard_value (),
00750                  CheckSecondDimension< Q1<Quantity<GT1, 
00751                    Loki::Typelist<Units::NonPrefixable<GT1,
00752                      Units::GenericUnit, ST>, Loki::NullType>, 
00753                        DU1, ST>, SU1>, Variable
00754                          >::RET::Unit::Standard (variable2.value ()))));
00755             }
00756 
00758 
00762         bool operator== (const Variable &rhs_variable) const
00763                    {return variable_value == rhs_variable.value ();}
00764 
00766 
00771         template <template<class, class> class Q1, class SU1>
00772           bool operator== (const Q1<PQ, SU1> &rhs_variable) const
00773             {return standard_value () == rhs_variable.standard_value ();
00774             }
00775 
00777 
00782         template <template<class, class> class Q1, class GT1, 
00783                                                    class DU1, class SU1>
00784           bool operator== (const Q1<Quantity<GT1, 
00785             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00786               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00787             {
00788              return standard_value () == 
00789                CheckSecondDimension<Variable<PQ, SU>, 
00790                  Q1<Quantity<GT1, 
00791                    Loki::Typelist<Units::NonPrefixable<GT1,
00792                      Units::GenericUnit, ST>, Loki::NullType>, 
00793                        DU1, ST>, SU1> >::RET::Unit::Standard 
00794                                                 (rhs_variable.value ());
00795             }
00796 
00798 
00805         template <template<class, class> class Q1, class GT1, 
00806                          class Head1, class Tail1, class DU1, class SU1>
00807           bool operator== 
00808            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00809                                      DU1, ST>, SU1> &rhs_variable) const
00810             {
00811              return 
00812                BSUtilities::IF<BSUtilities::SameType<SU, 
00813                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
00814                    >::sameType, SU, Units::UnitError<false> 
00815                      >::RET::Standard (variable_value) == 
00816                CheckSecondDimension<Variable<PQ, SU>, 
00817                  Q1<Quantity<GT1, 
00818                    Loki::Typelist<Units::NonPrefixable<GT1,
00819                      Units::GenericUnit, ST>, Loki::NullType>, 
00820                        DU1, ST>, SU1> >::RET::Unit::Standard 
00821                                                 (rhs_variable.value ());
00822             }
00823 
00825 
00829         bool operator!= (const Variable &rhs_variable) const
00830                    {return variable_value != rhs_variable.value ();}
00831 
00833 
00838         template <template<class, class> class Q1, class SU1>
00839           bool operator!= (const Q1<PQ, SU1> &rhs_variable) const
00840             {return standard_value () != rhs_variable.standard_value ();
00841             }
00842 
00844 
00849         template <template<class, class> class Q1, class GT1,
00850                                                    class DU1, class SU1>
00851           bool operator!= (const Q1<Quantity<GT1,
00852             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00853               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00854             {
00855              return standard_value () !=
00856                CheckSecondDimension<Variable<PQ, SU>,
00857                  Q1<Quantity<GT1, 
00858                    Loki::Typelist<Units::NonPrefixable<GT1,
00859                      Units::GenericUnit, ST>, Loki::NullType>, 
00860                        DU1, ST>, SU1> >::RET::Unit::Standard
00861                                                 (rhs_variable.value ());
00862             }
00863 
00865 
00872         template <template<class, class> class Q1, class GT1,
00873                          class Head1, class Tail1, class DU1, class SU1>
00874           bool operator!=
00875            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00876                                      DU1, ST>, SU1> &rhs_variable) const
00877             {
00878              return 
00879                BSUtilities::IF<BSUtilities::SameType<SU, 
00880                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
00881                    >::sameType, SU, Units::UnitError<false> 
00882                      >::RET::Standard (variable_value) !=
00883                CheckSecondDimension<Variable<PQ, SU>,
00884                  Q1<Quantity<GT1, 
00885                    Loki::Typelist<Units::NonPrefixable<GT1,
00886                      Units::GenericUnit, ST>, Loki::NullType>, 
00887                        DU1, ST>, SU1> >::RET::Unit::Standard
00888                                                 (rhs_variable.value ());
00889             }
00890 
00892 
00896         bool operator> (const Variable &rhs_variable) const
00897                    {return variable_value > rhs_variable.value ();}
00898 
00900 
00905         template <template<class, class> class Q1, class SU1>
00906           bool operator> (const Q1<PQ, SU1> &rhs_variable) const
00907             {return standard_value () > rhs_variable.standard_value ();
00908             }
00909 
00911 
00916         template <template<class, class> class Q1, class GT1,
00917                                                    class DU1, class SU1>
00918           bool operator> (const Q1<Quantity<GT1,
00919             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00920               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00921             {
00922              return standard_value () >
00923                CheckSecondDimension<Variable<PQ, SU>,
00924                  Q1<Quantity<GT1, 
00925                    Loki::Typelist<Units::NonPrefixable<GT1,
00926                     Units:: GenericUnit, ST>, Loki::NullType>, 
00927                       DU1, ST>, SU1> >::RET::Unit::Standard
00928                                                 (rhs_variable.value ());
00929             }
00930 
00932 
00939         template <template<class, class> class Q1, class GT1,
00940                          class Head1, class Tail1, class DU1, class SU1>
00941           bool operator>
00942            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
00943                                      DU1, ST>, SU1> &rhs_variable) const
00944             {
00945              return 
00946                BSUtilities::IF<BSUtilities::SameType<SU, 
00947                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
00948                    >::sameType, SU, Units::UnitError<false> 
00949                      >::RET::Standard (variable_value) >
00950                CheckSecondDimension<Variable<PQ, SU>,
00951                  Q1<Quantity<GT1, 
00952                    Loki::Typelist<Units::NonPrefixable<GT1,
00953                      Units::GenericUnit, ST>, Loki::NullType>, 
00954                        DU1, ST>, SU1> >::RET::Unit::Standard
00955                                                 (rhs_variable.value ());
00956             }
00957 
00959 
00963         bool operator< (const Variable &rhs_variable) const
00964                    {return variable_value < rhs_variable.value ();}
00965 
00967 
00972         template <template<class, class> class Q1, class SU1>
00973           bool operator< (const Q1<PQ, SU1> &rhs_variable) const
00974             {return standard_value () < rhs_variable.standard_value ();
00975             }
00976 
00978 
00983         template <template<class, class> class Q1, class GT1,
00984                                                    class DU1, class SU1>
00985           bool operator< (const Q1<Quantity<GT1,
00986             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
00987               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
00988             {
00989              return standard_value () <
00990                CheckSecondDimension<Variable<PQ, SU>,
00991                  Q1<Quantity<GT1, 
00992                    Loki::Typelist<Units::NonPrefixable<GT1,
00993                      Units::GenericUnit, ST>, Loki::NullType>, 
00994                        DU1, ST>, SU1> >::RET::Unit::Standard
00995                                                 (rhs_variable.value ());
00996             }
00997 
00999 
01006         template <template<class, class> class Q1, class GT1,
01007                          class Head1, class Tail1, class DU1, class SU1>
01008           bool operator<
01009            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
01010                                      DU1, ST>, SU1> &rhs_variable) const
01011             {
01012              return 
01013                BSUtilities::IF<BSUtilities::SameType<SU, 
01014                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
01015                    >::sameType, SU, Units::UnitError<false> 
01016                      >::RET::Standard (variable_value) <
01017                CheckSecondDimension<Variable<PQ, SU>,
01018                  Q1<Quantity<GT1, 
01019                    Loki::Typelist<Units::NonPrefixable<GT1,
01020                      Units::GenericUnit, ST>, Loki::NullType>, 
01021                        DU1, ST>, SU1> >::RET::Unit::Standard
01022                                                 (rhs_variable.value ());
01023             }
01024 
01026 
01030         bool operator>= (const Variable &rhs_variable) const
01031                    {return variable_value >= rhs_variable.value ();}
01032 
01034 
01039         template <template<class, class> class Q1, class SU1>
01040           bool operator>= (const Q1<PQ, SU1> &rhs_variable) const
01041             {return standard_value () >= rhs_variable.standard_value ();
01042             }
01043 
01045 
01050         template <template<class, class> class Q1, class GT1,
01051                                                    class DU1, class SU1>
01052           bool operator>= (const Q1<Quantity<GT1,
01053             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
01054               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
01055             {
01056              return standard_value () >=
01057                CheckSecondDimension<Variable<PQ, SU>,
01058                  Q1<Quantity<GT1, 
01059                    Loki::Typelist<Units::NonPrefixable<GT1,
01060                      Units::GenericUnit, ST>, Loki::NullType>, 
01061                        DU1, ST>, SU1> >::RET::Unit::Standard
01062                                                 (rhs_variable.value ());
01063             }
01064 
01066 
01073         template <template<class, class> class Q1, class GT1,
01074                          class Head1, class Tail1, class DU1, class SU1>
01075           bool operator>=
01076            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
01077                                      DU1, ST>, SU1> &rhs_variable) const
01078             {
01079              return 
01080                BSUtilities::IF<BSUtilities::SameType<SU, 
01081                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
01082                    >::sameType, SU, Units::UnitError<false> 
01083                      >::RET::Standard (variable_value) >=
01084                CheckSecondDimension<Variable<PQ, SU>,
01085                  Q1<Quantity<GT1, 
01086                    Loki::Typelist<Units::NonPrefixable<GT1,
01087                      Units::GenericUnit, ST>, Loki::NullType>, 
01088                        DU1, ST>, SU1> >::RET::Unit::Standard
01089                                                 (rhs_variable.value ());
01090             }
01091 
01093 
01097         bool operator<= (const Variable &rhs_variable) const
01098                    {return variable_value <= rhs_variable.value ();}
01099 
01101 
01106         template <template<class, class> class Q1, class SU1>
01107           bool operator<= (const Q1<PQ, SU1> &rhs_variable) const
01108             {return standard_value () <= rhs_variable.standard_value ();
01109             }
01110 
01112 
01117         template <template<class, class> class Q1, class GT1,
01118                                                    class DU1, class SU1>
01119           bool operator<= (const Q1<Quantity<GT1,
01120             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
01121               ST>, Loki::NullType>, DU1, ST>, SU1> &rhs_variable) const
01122             {
01123              return standard_value () <=
01124                CheckSecondDimension<Variable<PQ, SU>,
01125                  Q1<Quantity<GT1, 
01126                    Loki::Typelist<Units::NonPrefixable<GT1,
01127                      Units::GenericUnit, ST>, Loki::NullType>, 
01128                        DU1, ST>, SU1> >::RET::Unit::Standard
01129                                                 (rhs_variable.value ());
01130             }
01131 
01133 
01140         template <template<class, class> class Q1, class GT1,
01141                          class Head1, class Tail1, class DU1, class SU1>
01142           bool operator<=
01143            (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>,
01144                                      DU1, ST>, SU1> &rhs_variable) const
01145             {
01146              return 
01147                BSUtilities::IF<BSUtilities::SameType<SU, 
01148                  Units::NonPrefixable<GT, Units::GenericUnit, ST> 
01149                    >::sameType, SU, Units::UnitError<false> 
01150                      >::RET::Standard (variable_value) <=
01151                CheckSecondDimension<Variable<PQ, SU>,
01152                  Q1<Quantity<GT1, 
01153                    Loki::Typelist<Units::NonPrefixable<GT1,
01154                      Units::GenericUnit, ST>, Loki::NullType>, 
01155                        DU1, ST>, SU1> >::RET::Unit::Standard
01156                                                 (rhs_variable.value ());
01157             }
01158 
01160 
01165         template<class Q>
01166           typename GenerateVariable<Variable, Q>::Add operator* 
01167                                                 (const Q &factor) const
01168             {
01169               return typename GenerateVariable<Variable, Q>::Add 
01170                          (standard_value () * factor.standard_value ());
01171             }
01172 
01174 
01179         template<class Q>
01180           typename GenerateVariable<Variable, Q>::Sub operator/ 
01181                                                 (const Q &factor) const
01182             {
01183               return typename GenerateVariable<Variable, Q>::Sub 
01184                          (standard_value () / factor.standard_value ());
01185             }
01186 
01188 
01191         friend
01192           typename GenerateVariable<Variable, Loki::NullType>::Neg 
01193             operator/ (const ST numerator, const Variable &factor)
01194           {
01195             return typename 
01196               GenerateVariable<Variable, Loki::NullType>::Neg 
01197                                  (numerator / factor.standard_value ());
01198           }
01199 
01201 
01203         template<long N, long D>
01204           friend typename 
01205             GenerateVariable<Variable, 
01206               BSUtilities::Rational<N, D> >::Mult 
01207                 pow (const Variable &variable, 
01208                                     const BSUtilities::Rational<N, D> &)
01209           {
01210             return typename 
01211               GenerateVariable<Variable, 
01212                                      BSUtilities::Rational<N, D> >::Mult
01213                (std::pow(variable.standard_value (), 
01214                         static_cast<double>(N)/static_cast<double>(D)));
01215           }
01216 
01218         template<int I>
01219           friend typename 
01220             GenerateVariable<Variable, 
01221               BSUtilities::Rational<I, long(1)> >::Mult 
01222                 Pow (const Variable &variable, 
01223                                              typename Loki::Int2Type<I>)
01224           {
01225             return typename 
01226               GenerateVariable<Variable, 
01227                                BSUtilities::Rational<I, long(1)> >::Mult
01228                               (std::pow(variable.standard_value (), I));
01229           }
01230 
01232 
01233         friend typename 
01234           GenerateVariable<Variable, BSUtilities::Rational<3, 1> >::Mult
01235             pow (const Variable &variable, const double &exponent)
01236           {
01237             return typename 
01238               GenerateVariable<Variable, 
01239                                      BSUtilities::Rational<3, 1> >::Mult
01240                        (std::pow(variable.standard_value (), exponent));
01241           }
01242 
01244 
01246         template<long N, long D>
01247           typename GenerateVariable<Variable, 
01248                                      BSUtilities::Rational<N, D> >::Mult
01249                                pow (const BSUtilities::Rational<N, D> &)
01250           {
01251             return typename 
01252               GenerateVariable<Variable, 
01253                                      BSUtilities::Rational<N, D> >::Mult
01254                 (std::pow(standard_value (), 
01255                         static_cast<double>(N)/static_cast<double>(D)));
01256           }
01257 
01259 
01260         typename 
01261           GenerateVariable<Variable, BSUtilities::Rational<3, 1> >::Mult
01262                                             pow (const double &exponent)
01263         {
01264           return typename 
01265             GenerateVariable<Variable, BSUtilities::Rational<3, 1> 
01266                         >::Mult (std::pow(standard_value (), exponent));
01267         }
01268 
01270 
01272         friend typename 
01273           GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01274                                  >::Mult sqrt (const Variable &variable)
01275           {
01276             return typename 
01277               GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01278                         >::Mult (std::sqrt(variable.standard_value ()));
01279           }
01280 
01282 
01284         typename 
01285           GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01286                                                >::Mult sqrt (void) const
01287           {
01288             return typename 
01289               GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01290                                  >::Mult (std::sqrt(standard_value ()));
01291           }
01292 
01294 
01297       std::ostream & print_value (std::ostream &os) const
01298         {return os << variable_value << " " << SU::Symbol ();}
01299 
01301 
01303       void operator>> (std::string &str) const
01304           {str = BSUtilities::Conversion<Variable>::to_string (*this);}
01305 
01307 
01311       std::ostream & operator>> (std::ostream &os) const
01312                    {return this->print (os);}
01313 
01315 
01317       void read_value (const std::string &str);
01318 
01320 
01322       friend void operator>> 
01323         (const std::string &str, Variable &variable) 
01324                                             {variable.read_value (str);}
01325 
01327       void operator<< (const std::string &str) {read_value (str);}
01328 
01330       void operator= (const std::string &str) {this->read_value (str);}
01331 
01333 
01337       std::istream & operator<< (std::istream &is) 
01338         {std::string string; getline (is, string); 
01339                                   this->read_value (string); return is;}
01340 
01342 
01345       friend std::istream & operator>> 
01346         (std::istream &is, Variable &variable) {return variable << is;}
01347 
01348     };
01349 
01354 template<class GT, class Head, class Tail, class DU, class SU, class ST>
01355   void 
01356     Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, SU>
01357                                    ::read_value (const std::string &str)
01358     {
01359       std::string value;
01360       std::string unit;
01361 
01362       std::string::size_type start;
01363       std::string::size_type end;
01364 
01365       start = str.find_first_not_of (" \0");
01366       end = start;
01367 
01368       if (RS.name ())
01369       {
01370         if (start == std::string::npos)
01371           throw InputError ();
01372 
01373         else
01374         {
01375           end = str.find_first_of (" \0", start);
01376 
01377           if (end == std::string::npos)
01378             namestring = str.substr (start);
01379 
01380           else
01381             namestring = (str.substr (start, end - start));
01382         }
01383       }
01384 
01385       start = str.find_first_not_of (" \0", end);
01386       end = start;
01387  
01388       if (RS.symbol ())
01389       {
01390         if (start == std::string::npos)
01391           throw InputError ();
01392 
01393         else
01394         {
01395           end = str.find_first_of (" \0", start);
01396 
01397           if (end == std::string::npos)
01398             symbolstring = str.substr (start);
01399 
01400           else
01401             symbolstring = (str.substr (start, end - start));
01402         }
01403       }
01404 
01405       start = str.find_first_not_of (" \0", end);
01406       end = start;
01407 
01408       if (RS.equal () && (RS.name () || RS.symbol ()))
01409       {
01410         if (start == std::string::npos)
01411           throw InputError ();
01412 
01413         else
01414         {
01415           end = str.find_first_of (" \0", start);
01416 
01417           if (end == std::string::npos)
01418             throw InputError ();
01419 
01420           else if (str.substr (start, end - start) != "=")
01421             throw InputError ();
01422         }
01423       }
01424 
01425       start = str.find_first_not_of (" \0", end);
01426       end = start;
01427  
01428       if (start == std::string::npos)
01429         throw InputError ();
01430 
01431       else
01432       {
01433         end = str.find_first_of (" \0", start);
01434 
01435         if (end == std::string::npos)
01436           value = str.substr (start);
01437 
01438         else
01439           value = str.substr (start, end - start);
01440 
01441         start = str.find_first_not_of (" \0", end);
01442 
01443         if (start == std::string::npos)
01444           unit = "";
01445 
01446         else
01447         {
01448           end = str.find_first_of (" \0\n", start);
01449 
01450           if (end = std::string::npos)
01451             unit = str.substr (start);
01452 
01453           else
01454             unit = str.substr (start, end - start);
01455         }
01456       }
01457    
01458       ST intermediate;
01459 
01460       try {
01461         intermediate = BSUtilities::Conversion<ST>::string_to (value);
01462           }
01463 
01464       catch (BSUtilities::ConversionFailure) {throw InputError ();}
01465 
01466       start = unit.find_first_not_of (" \0");
01467       end = start;
01468  
01469 
01470 
01471 
01472       if (start == std::string::npos)
01473       {
01474         std::string assume_unit;
01475 
01476 
01477 
01478 
01479 
01480         if ((assume_unit = RS.unit ()) != "")
01481         {
01482           try {
01483             ::Units::Unit<GT, ST> *unitp 
01484                                        = PQ::findBySymbol (assume_unit);
01485             intermediate = SU::Reverse (unitp->standard (intermediate));
01486 
01487             delete (unitp);
01488               }
01489 
01490           catch (UnitMismatch) {throw InputError ();}
01491 
01492         }
01493       }
01494 
01495 
01496 
01497 
01498       else
01499       {
01500         end = unit.find_first_of (" \0", start);
01501         try {
01502           ::Units::Unit<GT, ST> *unitp 
01503                   = PQ::findBySymbol (unit.substr (start, end - start));
01504 
01505           intermediate = SU::Reverse (unitp->standard (intermediate));
01506 
01507           delete (unitp);
01508             }
01509         catch (UnitMismatch) {throw InputError ();}
01510       }
01511       
01512 
01513       variable_value = intermediate;
01514 
01515     }
01516 
01518 
01521 template<template<class, class> class Q1, class GT1, class Head1, 
01522            class Tail1, class DU1, class SU1,
01523          template<class, class> class Q2, class GT2, class Head2, 
01524            class Tail2, class DU2, class SU2, class ST>
01525   struct GenerateVariable
01526     <Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, DU1, ST>, SU1>, 
01527          Q2<Quantity<GT2, Loki::Typelist<Head2, Tail2>, DU2, ST>, SU2> >
01528   {
01529      private:
01531        typedef typename 
01532          Dimensions::Dimension<GT1>::template 
01533                            Add<Dimensions::Dimension<GT2> >::Class AddT;
01534        typedef Units::NonPrefixable<GenericClass<AddT>, 
01535                                            Units::GenericUnit, ST> AddU;
01536        typedef Loki::Typelist<AddU, Loki::NullType> AddUnits;
01537        typedef Quantity<GenericClass<AddT>, AddUnits, AddU, ST> 
01538                                                                 AddNewQ;
01539 
01541        typedef typename 
01542          Dimensions::Dimension<GT1>::template 
01543                            Sub<Dimensions::Dimension<GT2> >::Class SubT;
01544        typedef Units::NonPrefixable<GenericClass<SubT>, 
01545                                            Units::GenericUnit, ST> SubU;
01546        typedef Loki::Typelist<SubU, Loki::NullType> SubUnits;
01547        typedef Quantity<GenericClass<SubT>, SubUnits, SubU, ST> SubNewQ;
01548 
01549      public:
01550        typedef Variable<AddNewQ, AddU> Add;
01551        typedef Variable<SubNewQ, SubU> Sub;
01552   };
01553 
01555 
01558 template<template<class, class> class Q1, class GT1, class Head1, 
01559            class Tail1, class DU1, class SU1, class ST1> 
01560   struct GenerateVariable
01561     <Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>, 
01562                                                          Loki::NullType>
01563   {
01564      private:
01566        typedef typename Dimensions::Dimension<GT1>::Neg::Class NegT;
01567        typedef Units::NonPrefixable<GenericClass<NegT>, 
01568                                           Units::GenericUnit, ST1> NegU;
01569        typedef Loki::Typelist<NegU, Loki::NullType> NegUnits;
01570        typedef Quantity<GenericClass<NegT>, NegUnits, NegU, ST1> 
01571                                                                 NegNewQ;
01572 
01573      public:
01574        typedef Variable<NegNewQ, NegU> Neg;
01575   };
01576 
01578 
01581 template<template<class, class> class Q1, class GT1, class Head1, 
01582            class Tail1, class DU1, class ST1, class SU1, long N, long D>
01583   struct GenerateVariable
01584     <Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>, 
01585                                            BSUtilities::Rational<N, D> >
01586   {
01587      private:
01589        typedef typename 
01590          Dimensions::Dimension<GT1>::template Mult<N, D>::Class MultT;
01591        typedef Units::NonPrefixable<GenericClass<MultT>, 
01592                                          Units::GenericUnit, ST1> MultU;
01593        typedef Loki::Typelist<MultU, Loki::NullType> MultUnits;
01594        typedef Quantity<GenericClass<MultT>, MultUnits, MultU, ST1> 
01595                                                                MultNewQ;
01596 
01597      public:
01598        typedef Variable<MultNewQ, MultU> Mult;
01599   };
01600 
01602 
01607 
01608 
01609 
01610 
01611 
01612 
01613 
01614 
01615 
01616 
01617 
01618 
01619 
01620 
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 
01629 
01630 
01631 
01632 
01633 
01634 
01635 
01636 
01637 
01638 
01639 
01640 
01641 }
01642 
01643 #endif