ReferencedVariable.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2004 - 2009, 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 _ReferencedVariable_h
00025 #define _ReferencedVariable_h
00026 
00027 // Quantity includes
00028 #include "Quantity/Quantity.h"
00029 #include "Quantity/Generic.h"
00030 
00031 namespace quantity {
00032 
00034 //
00035 //  the ReferencedVariable classes
00036 //
00038 
00040 
00044 template<class ABQ, class SU = typename ABQ::DefaultUnit::Unit>
00045   class ReferencedVariable;
00046 
00048 
00051 template<class BT, class DIM, class UL, class DU, class SU, class ST>
00052   class ReferencedVariable<Quantity<DIM, BT, UL, DU, ST>, SU>
00053                     : public Variable<Quantity<DIM, BT, UL, DU, ST>, SU>
00054 
00055     {
00056       private:
00058         typedef Variable<Quantity<DIM, BT, UL, DU, ST>, SU> V;
00059 
00061         typedef Quantity<DIM, BT, UL, DU, ST> Q;
00062 
00064         ST reference_value;
00065 
00066       public:
00068 
00071         ReferencedVariable (void) 
00072           : V (ST(0.0)), reference_value (ST(0.0)) {}
00073 
00075 
00078         ReferencedVariable (const ST new_value) : V (new_value) {}
00079 
00081 
00084         ReferencedVariable (const ST new_value, const ST new_reference)
00085           : V (new_value - new_reference), 
00086                                       reference_value (new_reference) {}
00087 
00089 
00095         template<class NU>
00096           ReferencedVariable 
00097                 (const ST new_value, const ST new_reference, const NU &)
00098             {
00099               V::variable_value = Reverse<typename V::Unit>::VAL
00100                 (Standardize<typename
00101                   CheckAgainstAllUnits<NU, UL>
00102                                ::RET>::VAL (new_value - new_reference));
00103               reference_value 
00104                 = Reverse<typename V::Unit>::VAL (Standardize<NU>::VAL
00105                                                        (new_reference));
00106             }
00107 
00109 
00119        template<template<class, class> class QR, class BTR, class DIMR,
00120                            class ULR, class DUR, class SUR, class STR>
00121          ReferencedVariable (const ST new_value, 
00122            const QR<Quantity<DIMR, BTR, ULR, DUR, STR>, SUR> 
00123                                                         & new_reference)
00124            {
00125              typedef 
00126                QR<Quantity<DIMR, BTR, ULR, DUR, STR>, SUR> Q;
00127              reference_value 
00128                = Reverse<typename V::Unit>::VAL 
00129                  (Standardize<typename CheckAgainstAllUnits<typename 
00130                    CheckSecondDimension<ReferencedVariable, Q>
00131                                                             ::RET::Unit,
00132                      typename 
00133                        Loki::TL::Append<UL, unit::NonPrefixable<BTR, 
00134                          unit::GenericUnit> >::Result>::RET>::VAL
00135                                               (new_reference.value ()));
00136              V::variable_value = new_value - reference_value;
00137            }
00138 
00139 // other constructors?
00140 // e.g., with two units NVU, NRU for variable and reference values
00141 
00143 
00146         ReferencedVariable (const ReferencedVariable &new_variable)
00147           : V (new_variable.variable_value), 
00148                           reference_value (new_variable.reference_value)
00149             {
00150               Q::namestring = new_variable.namestring;
00151               Q::symbolstring = new_variable.symbolstring;
00152             };
00153 
00154 // conversion ?
00155 
00157 
00163         void reference (const ST new_reference)
00164           {V::variable_value 
00165             = V::variable_value + reference_value - new_reference; 
00166                                         reference_value = new_reference;
00167           }
00168 
00170 
00176         template<class NU>
00177           void reference (const ST new_reference, const NU &)
00178             {V::variable_value = V::variable_value + reference_value;
00179              reference_value = Reverse<typename V::Unit>::VAL
00180                (Standardize<typename
00181                  CheckAgainstAllUnits<NU, UL>::RET>::VAL 
00182                                                        (new_reference));
00183              V::variable_value -= reference_value;
00184             }
00185 
00187 
00190         ST reference (void) {return reference_value;}
00191 
00193 
00197         template<class NU>
00198           ST reference (const NU &) 
00199             {return Reverse<typename
00200               CheckAgainstAllUnits<NU, UL>::RET>::VAL 
00201                 (Standardize<typename V::Unit>::VAL (reference_value));}
00202 
00204 /*  assignment is to an already existing referenced variable, thus
00205     the value which is assigned to the existing object is referenced
00206     after the assignment is done to the reference value of the object
00207     assigned to; other explanations, see Variable.h.
00208 */
00209         template<template<class, class> class Q1, class BT1, class DIM1,
00210                              class UL1, class DU1, class SU1, class ST1>
00211             ReferencedVariable & operator=
00212               (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1> 
00213                                                           &new_variable)
00214              {
00215                void *this_pointer = this;
00216                const void *new_pointer = &new_variable;
00217 
00218                if (this_pointer != new_pointer)
00219                {
00220                  typedef Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1> Q;
00221                  V::variable_value = Reverse<typename V::Unit>::VAL
00222                    (Standardize<typename CheckAgainstAllUnits<typename
00223                        CheckSecondDimension<ReferencedVariable, Q>
00224                                                             ::RET::Unit,
00225                          typename Loki::TL::Append<UL,
00226                              unit::NonPrefixable<BT1, 
00227                                unit::GenericUnit> >::Result>::RET>::VAL
00228                                  (new_variable.value ())) 
00229                                                       - reference_value;
00230                }
00231                return *this;
00232              }
00233 
00235 /*  assignment is to an already existing referenced variable, thus
00236     the value which is assigned to the existing object is referenced
00237     after the assignment is done to the reference value of the object
00238     assigned to; other explanations, see Variable.h
00239 */
00240         ReferencedVariable & operator=
00241                                 (const ReferencedVariable &new_variable)
00242         {
00243           if (this != &new_variable)
00244             {V::variable_value = 
00245                             new_variable.value () - reference_value;
00246             }
00247           return *this;
00248         }
00249 
00251 
00254         ST value (void) const 
00255                               {return V::variable_value + reference_value;}
00256 
00258 
00261         ST refvalue (void) const {return V::variable_value;}
00262 
00264 
00269         template<class NU>
00270           ST value (const NU &) const
00271             {return 
00272               Reverse<typename CheckAgainstAllUnits<NU, UL>::RET>::VAL
00273                  (Standardize<typename V::Unit>::VAL (V::variable_value));}
00274 
00276 
00278         const std::string unitsymbol (void) const 
00279                                                  {return SU::Symbol ();}
00280 
00282 
00284         static std::string Unitsymbol (void) {return SU::Symbol ();}
00285 
00287 
00289         const std::string unitname (void) const {return SU::Name ();}
00290 
00292 
00294         static std::string Unitname (void) {return SU::Name ();}
00295 
00296     };
00297 
00298 }
00299 
00300 #endif /* _ReferencedVariable_h */

Generated on Mon Jul 27 15:55:45 2009 for Quantities by  doxygen 1.5.3