Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | Related Pages

Variable.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2002 - 2004, 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 _Variable_h
00025 #define _Variable_h
00026 
00027 #include "Quantity/Quantity.h"
00028 #include "Quantity/Generic.h"
00029 
00030 namespace Quantities {
00031 
00033 //
00034 //  Helper classes and structs 
00035 //
00037 
00039 
00042 template<class Q1, class Q2> struct GenerateVariable;
00043 
00045 //
00046 //  the Variable classes
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 // NOTE: make general!!!! use something like a `GenerateRational'
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 // NOTE: make general!!!! use something like a `GenerateRational'
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 /* if no unit symbol string is present in input, assume one or use
01470    storage unit
01471 */
01472       if (start == std::string::npos)
01473       {
01474         std::string assume_unit;
01475 
01476 /* if a unit has been set, use this for conversion of intermediate
01477    (value); else do nothing, since we assume that the value is in 
01478    the storage unit and can be stored directly. 
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 /* if unit symbol string is present in input, use it for conversion
01496    of intermediate (value)
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         template <template<class, class> class Q1, class GT1, 
01609           class DU1, class SU1,
01610                   template<class, class> class Q2, class GT2,
01611                                          class DU2, class SU2, class ST>
01612           Variable<Quantity<GT1, 
01613             Loki::Typelist<Units::NonPrefixable<GT1, Units::GenericUnit,
01614                                ST>, Loki::NullType>, DU1, ST>, SU1> fmod
01615             (const Variable<Quantity<GT1,
01616               Loki::Typelist<Units::NonPrefixable<GT1, 
01617                 Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, SU1>
01618                                                              &variable1,
01619                   const Variable<Quantity<GT2, 
01620                     Loki::Typelist<Units::NonPrefixable<GT2, 
01621                       Units::GenericUnit, ST>, Loki::NullType>, DU2, 
01622                                                    ST>, SU2> &variable2)
01623             {
01624              return Variable<Quantity<GT1, 
01625                Loki::Typelist<Units::NonPrefixable<GT1, 
01626                  Units::GenericUnit, ST>, Loki::NullType>, DU1, ST>, 
01627                                                                     SU1>
01628                (SU1::Reverse (std::fmod (variable1.standard_value (),
01629                  CheckSecondDimension<Variable<Quantity<GT1, 
01630                    Loki::Typelist<Units::NonPrefixable<GT1,
01631                      Units::GenericUnit, ST>, Loki::NullType>, 
01632                                                          DU1, ST>, SU1>,
01633                        Variable<Quantity<GT2, 
01634                          Loki::Typelist<Units::NonPrefixable<GT2, 
01635                            Units::GenericUnit, ST>, Loki::NullType>, 
01636                              DU2, ST>, SU2> >::RET::Unit::Standard 
01637                                                 (variable2.value ()))));
01638             }
01639 */
01640 
01641 }
01642 
01643 #endif /* _Variable_h */

Generated on Sun Jan 15 13:58:00 2006 for Quantity by doxygen 1.3.6