Variable.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2002 - 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 _Variable_h
00025 #define _Variable_h
00026 
00027 // Quantity includes
00028 #include "Quantity/Quantity.h"
00029 #include "Quantity/QuantityError.h"
00030 #include "Quantity/Generic.h"
00031 #include "Quantity/Dynamic.h"
00032 
00033 // Loki includes
00034 #include "loki/Typelist.h"
00035 #include "loki/NullType.h"
00036 #include "loki/HierarchyGenerators.h"
00037 
00038 // BOOST includes
00039 #include <boost/serialization/base_object.hpp>
00040 
00041 namespace quantity {
00042 
00044 //  Helper classes and structs for compiling error messages
00046 
00048 
00051 template<bool> 
00052   struct VariableError;
00053 
00055 
00059 template<bool>
00060   struct AssignmentError;
00061 
00063 
00067 template<>
00068   struct AssignmentError<false>
00069     {
00071 
00073        static const bool RET = true;
00074     };
00075 
00077 
00081 template<bool>
00082   struct OperationError;
00083 
00085 
00089 template<>
00090   struct OperationError<false>
00091     {
00093 
00095        static const bool RET = true;
00096     };
00097 
00099 //
00100 //  helper classes and structs for checking features of quantities
00101 //
00103 
00105 
00111 template<template<typename, typename> class Q1, typename QT1,
00112                                       typename DQT1, typename ST1,
00113          template<typename, typename> class Q2, typename QT2, 
00114                                      typename DQT2, typename ST2> 
00115   struct SameDimensioned 
00116         <Q1<Quantity<QT1, ST1>, DQT1>, Q2<Quantity<QT2, ST2>, DQT2> >
00117   {
00118     enum {EQ = SameDimensioned<Quantity<QT1, ST1>, Quantity<QT2, ST2> >::EQ};
00119   };
00120 
00121 
00123 
00128 template<class Q1, class Q2> struct CheckSecondDimension;
00129 
00130 template<template<typename, typename> class Q1, typename QT1, 
00131                                         typename DQT1, typename ST1, 
00132          template<typename, typename> class Q2, class QT2, 
00133                                             typename DQT2, typename ST2>
00134   struct CheckSecondDimension
00135          <Q1<Quantity<QT1, ST1>, DQT1>, Q2<Quantity<QT2, ST2>, DQT2> >
00136   {
00137     public: 
00138       typedef typename 
00139         BSUtilities::IF<SameDimensioned<Quantity<QT1, ST1>, Quantity<QT2, ST2> 
00140           >::EQ, Q2<Quantity<QT2, ST2>, DQT2>, DimensionError<true> >::RET RET;
00141   };
00142 
00144 //
00145 //  construction helpers for Variable 
00146 //
00148 
00150 
00152     template<typename QT, typename DQT>
00153         struct OverwriteNameString
00154         {static std::string exec (void)
00155           {return DerivedQuantityTraits<QT, DQT>::NameString;}
00156         };
00157 
00159 
00162     template<typename QT>
00163         struct UseNameString
00164         {static std::string exec (void)
00165           {return QuantityTraits<QT>::NameString;}
00166         };
00167 
00169 
00173     template<typename QT, typename DQT>
00174         struct Name
00175         {static std::string exec (void)
00176           {return BSUtilities::IF<DerivedQuantityTraits<QT, DQT>::OverwriteName, 
00177              OverwriteNameString<QT, DQT>, UseNameString<QT> >::RET::exec();}
00178         };
00179 
00181 
00183     template<typename QT, typename DQT>
00184         struct OverwriteSymbolString
00185         {static std::string exec (void)
00186           {return DerivedQuantityTraits<QT, DQT>::SymbolString;}
00187         };
00188 
00190 
00193     template<typename QT>
00194         struct UseSymbolString
00195         {static std::string exec (void)
00196             {return QuantityTraits<QT>::SymbolString;}
00197         };
00198 
00200 
00204     template<typename QT, typename DQT>
00205         struct Symbol
00206         {static std::string exec (void)
00207           {return BSUtilities::IF<DerivedQuantityTraits<QT, DQT>::OverwriteSymbol, 
00208               OverwriteSymbolString<QT, DQT>, UseSymbolString<QT> >::RET::exec();}
00209         };
00210 
00212 //
00213 //  forward declarations
00214 //
00216 
00218 
00221 template<typename Q1, typename Q2> struct GenerateVariable;
00222 
00224 //
00225 //  the Variable classes
00226 //
00228 
00230 
00235 template<typename BQ, typename DQ = DerivedQuantity<typename BQ::QuantityType, 
00236             typename BQ::DU, typename BQ::DDQ> > class Variable;
00237 
00239 
00248 template<typename QT, typename ST, typename SU, typename DQT>
00249   class Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > : public Quantity<QT, ST>
00250     {
00251       public:
00253 
00255         typedef typename QuantityTraits<QT>::Dimension DIM;
00256 
00258 
00260         typedef typename QuantityTraits<QT>::UnitType UT;
00261 
00263 
00265         typedef typename QuantityTraits<QT>::UnitList UL;
00266 
00268 
00270         typedef typename QuantityTraits<QT>::DefaultUnit DU;
00271 
00273 
00279         typedef typename unit::CheckUnit<unit::Unit<UT>, SU>::Check StorageUnit;
00280 
00282 
00285         typedef Quantity<QT, ST> BQ;
00286 
00288 
00290         typedef Variable<BQ, DerivedQuantity<QT, SU, DQT> > V;
00291 
00292       private:
00294 
00298         ST _value;
00299 
00301 //  constructors for Variable 
00303 
00304       public:
00306 
00312         Variable (void) : BQ (), _value (ST(0)) 
00313           {name (Name<QT, DQT>::exec ()); symbol (Symbol<QT, DQT>::exec ());}
00314 
00316 
00322         Variable (const ST &value) : BQ (), _value (value)
00323           {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());}
00324 
00326 
00333         Variable (const ST &value, const std::string &namestring, const std::string &symbolstring) 
00334             : BQ (), _value (value)
00335           {BQ::name (namestring); BQ::symbol (symbolstring);}
00336 
00338 
00345         template<typename NU>
00346           Variable (const ST &value, const NU &) 
00347             : BQ (), _value (Reverse<SU, ST>::VAL 
00348               (Standardize<typename CheckAgainstAllUnits<NU, UL>::RET, ST>::VAL (value)))
00349             {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());}
00350 
00352 
00361         template<typename NU>
00362           Variable (const ST &value, const NU &, 
00363                     const std::string &namestring, const std::string &symbolstring) 
00364             : BQ (), _value (Reverse<SU, ST>::VAL 
00365              (Standardize<typename CheckAgainstAllUnits<NU, UL>::RET, ST>::VAL (value)))
00366             {BQ::name (namestring); BQ::symbol (symbolstring);}
00367 
00369 
00381         Variable (const ST value, const std::string &unitsymbol) : BQ ()
00382           {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());
00383              ::unit::Unit<UT> *unitp = BQ::findBySymbol (unitsymbol);
00384                _value = Reverse<StorageUnit, ST>::VAL 
00385                          (dynamic_standardize<UL>::VAL (value, *unitp));
00386 
00387              delete (unitp);
00388           }
00389 
00391 
00401         Variable (const ST value, const char * unitsymbol) : BQ ()
00402           {name (Name<QT, DQT>::exec ()); symbol (Symbol<QT, DQT>::exec ());
00403             ::unit::Unit<UT> *unitp 
00404                               = BQ::findBySymbol (std::string (unitsymbol));
00405              _value = Reverse<StorageUnit, ST>::VAL 
00406                          (dynamic_standardize<UL>::VAL (value, *unitp));
00407 
00408              delete (unitp);
00409             }
00410 
00412 //  end constructors for Variable 
00414 
00416 //  copy constructors for Variable 
00418 
00420 
00425         template<template<typename, typename> class SM, typename SST>
00426           Variable (const SM<Quantity<QT, SST>, DQT> &quantity) 
00427             : BQ (), _value (quantity.value ())
00428               {name (quantity.BQ::name ()); symbol (quantity.BQ::symbol ());}
00429  
00431 
00441         template<template<typename, typename> class SM, 
00442                                            typename SST, typename SSU, typename SDQT>
00443           Variable (const SM<Quantity<QT, SST>, DerivedQuantity<QT, SSU, SDQT> > &quantity)
00444             : BQ (), _value (Reverse<StorageUnit, ST>::VAL 
00445               (Standardize<SSU, SST>::VAL (quantity.value ())))
00446               {name (quantity.Quantity<QT, SST>::name ()); 
00447                   symbol (quantity.Quantity<QT, SST>::symbol ());}
00448 
00450 
00457         template<template<typename, typename> class SM, 
00458                              typename SDIM, typename SST, typename SSU, typename SDQT>
00459           Variable (const SM<Quantity<GenericClass<SDIM>, SST>, 
00460             DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > &quantity)
00461             : BQ (), _value (Reverse<StorageUnit, ST>::VAL
00462               (Standardize<typename
00463                  CheckSecondDimension<V, 
00464                    SM<Quantity<GenericClass<SDIM>, SST>, 
00465                      DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > >
00466                        ::RET::StorageUnit, SST>::VAL (quantity.value ())))
00467               {name (quantity.Quantity<GenericClass<SDIM>, SST>::name ()); 
00468                    symbol (quantity.Quantity<GenericClass<SDIM>, SST>::symbol ());}
00469 
00471 
00483         template<template<typename, typename> class SM, 
00484                              typename SQT, typename SST, typename SSU, typename SDQT>
00485           Variable (const SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > &quantity)
00486             : BQ (), _value (convertValue<V, SM<Quantity<SQT, SST>, 
00487               DerivedQuantity<SQT, SSU, SDQT> > >::exec (quantity))
00488               {name (quantity.Quantity<SQT, SST>::name ()); 
00489                   symbol (quantity.Quantity<SQT, SST>::symbol ());}
00490 
00491 
00493 
00497         template<typename SST>
00498           Variable (const Dynamic<SST> &dynamic)
00499             {if (dynamic.isCommensurable (*this))
00500                _value = Reverse<StorageUnit, ST>::VAL (dynamic.value ());
00501              else
00502                {throw DimensionMismatch ();}
00503 
00504             }
00505 
00507 //  end copy constructors for Variable 
00509 
00511 //  assignment operators for Variable 
00513 
00515 
00522         Variable & operator= (const Variable &variable)
00523           {if (this != &variable)
00524              {_value = variable.value ();}
00525            return *this;
00526           }
00527 
00529 
00552         template<template<typename, typename> class SM, typename SST, typename SSU, typename SDQT>
00553           Variable & operator= (const SM<Quantity<QT, SST>, DerivedQuantity<QT, SSU, SDQT> > &quantity)
00554           {_value = Reverse<StorageUnit, ST>::VAL (Standardize<SSU, SST>::VAL (quantity.value ()));
00555            return *this;
00556           }
00557 
00559 
00586         template<typename SDIM, typename SST, typename SSU, typename SDQT>
00587           Variable & operator= 
00588             (const Variable<Quantity<GenericClass<SDIM>, SST>, 
00589                               DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > &quantity)
00590             {_value = Reverse<StorageUnit, ST>::VAL
00591                (Standardize<typename
00592                  CheckSecondDimension<V, Variable<Quantity<GenericClass<SDIM>, SST>, 
00593                    DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > >::RET::StorageUnit, SST>::VAL 
00594                                                                             (quantity.value ()));
00595              return *this;
00596             }
00597 
00599 
00614         template<template<typename, typename> class SM, 
00615                           typename SQT, typename SST, typename SSU, typename SDQT>
00616           Variable & operator= 
00617             (const SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > &quantity)
00618           {*this = V(quantity);
00619            return *this;
00620           }
00621 
00623 
00631       template<typename SST>
00632         Variable & operator= (const Dynamic<SST> &dynamic)
00633           {if (dynamic.isCommensurable (*this))
00634              _value = Reverse<StorageUnit, ST>::VAL (dynamic.value ());
00635            else
00636              {throw DimensionMismatch ();}
00637            return *this;
00638           }
00639 
00641 
00645       Variable & operator= (const std::string &str) {this->read_value (str); return *this;}
00646 
00648 
00652       Variable & operator= (const char * str) {this->read_value (str); return *this;}
00653 
00655 
00665     template <typename T>
00666       Variable & operator= (const T &);
00667 
00669 //  end assignment operators for Variable 
00671 
00673 //  state reporting member functions for Variable 
00675 
00676     public:
00678 
00680         ST value (void) const {return _value;}
00681 
00683 
00686         ST standard_value (void) const 
00687                      {return Standardize<StorageUnit, ST>::VAL (_value);}
00688 
00690 
00696           template<typename NU>
00697             Variable<Quantity<QT, ST>, DerivedQuantity<QT, NU, DQT> > value (const NU &) const 
00698              {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, NU, DQT> > 
00699                 (Reverse<typename CheckAgainstAllUnits<NU, UL>::RET, ST>::VAL
00700                            (Standardize<StorageUnit, ST>::VAL (_value)));}
00701 
00703 
00712         ST value (const std::string &symbol)
00713           {ST value;
00714            ::unit::Unit<UT> *unitp = BQ::findBySymbol (symbol);
00715 
00716            value = dynamic_reverse<UL>::VAL
00717                     (Standardize<StorageUnit, ST>::VAL (_value), *unitp);
00718 
00719            delete (unitp);
00720 
00721            return value;
00722           }
00723 
00725 
00727         std::string unitsymbol (void) const {return StorageUnit::Symbol ();}
00728 
00730 
00732         static std::string Unitsymbol (void) {return StorageUnit::Symbol ();}
00733 
00735 
00737         std::string unitname (void) const {return StorageUnit::Name ();}
00738 
00740 
00742         static std::string Unitname (void) {return StorageUnit::Name ();}
00743 
00745 //  end state reporting operators for Variable 
00747 
00749 //  arithmetic operators for Variable 
00751 
00753 
00767         Variable & operator+= (const Variable &variable)
00768           {if(BSUtilities::IF<BSUtilities::SameType<UL, 
00769             Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit>, 
00770               Loki::NullType> >::sameType, AssignmentError<true>, 
00771                                      AssignmentError<false> >::RET::RET)
00772            _value += variable.value (); 
00773            return *this;
00774           }
00775 
00777 
00792         template <template<typename, typename> class M1, typename ST1, 
00793                                                 typename SU1, typename DQT1>
00794           Variable & operator+= (const M1<Quantity<QT, ST1>, 
00795                                     DerivedQuantity<QT, SU1, DQT1> > &quantity)
00796             {_value = Reverse<StorageUnit, ST>::VAL 
00797               (Standardize<StorageUnit, ST>::VAL (_value) + 
00798                  Standardize<SU1, ST1>::VAL (quantity.value ()));
00799               return *this;
00800             }
00801 
00803 
00819         template <template<typename, typename> class M1, 
00820                                     typename DIM1, typename ST1, typename SU1, typename DQT1>
00821           Variable & operator+= (const M1<Quantity<GenericClass<DIM1>, ST1>,
00822                                DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > &quantity)
00823             {_value = Reverse<StorageUnit, ST>::VAL 
00824               (Standardize<StorageUnit, ST>::VAL (_value) + 
00825                 Standardize<typename CheckSecondDimension<V, 
00826                   M1<Quantity<GenericClass<DIM1>, ST1>, 
00827                     DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > >
00828                           ::RET::StorageUnit, ST1>::VAL (quantity.value ()));
00829               return *this;
00830             }
00831 
00833 
00850         template<template<typename, typename> class M1, 
00851                                  typename QT1, typename ST1, typename SU1, typename DQT1>
00852           Variable & operator+= (const M1<Variable<QT1, ST1>, 
00853                                     DerivedQuantity<QT1, SU1, DQT1> > &quantity)
00854           {
00855             static const bool RET = 
00856               BSUtilities::IF<BSUtilities::SameType<QT, QT1>::sameType, 
00857                 DimensionError<false>, DimensionError<true> >::RET::RET;
00858             return *this;
00859           }
00860 
00862 
00866       template<template<typename, typename> class M1, 
00867                               typename QT1, typename ST1, typename SU1, typename DQT1>
00868       struct PlusGenerated
00869         {static V exec 
00870           (const V &variable, 
00871              const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity)
00872             {return V (Reverse<StorageUnit, ST>::VAL 
00873               (Standardize<StorageUnit, ST>::VAL (variable.value ()) 
00874                 + Standardize<typename CheckSecondDimension<
00875                   V, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
00876                            ::RET::StorageUnit, ST1>::VAL (quantity.value ())));
00877             }
00878         };
00879         
00881 
00884         template<class Q>
00885           struct Plus
00886             {static V exec (const V &variable, const Q &quantity)
00887               {V new_object (variable);
00888                 return new_object += quantity;
00889               }
00890             };
00891 
00893 
00899         template <template<typename, typename> class M1, 
00900                                  typename QT1, typename ST1, typename SU1, typename DQT1>
00901           Variable operator+ (const M1<Quantity<QT1, ST1>, 
00902                                       DerivedQuantity<QT1, SU1, DQT1> > &quantity) const
00903             {return BSUtilities::IF<BSUtilities::SameType<UL, 
00904               Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00905                 unit::GenericUnit>, Loki::NullType> >::sameType, 
00906                   typename PlusGenerated<M1, QT1, ST1, SU1, DQT1>::PlusGenerated, 
00907                     typename Plus<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
00908                                       ::Plus>::RET::exec (*this, quantity);
00909             }
00910 
00912 
00919         template <typename SST>
00920           Variable operator+ (const Dynamic<SST> &quantity) const
00921             {Variable new_variable (quantity);
00922              return *this + new_variable;
00923             }
00924 
00926 
00933         template<template<typename, typename> class M1, typename ST1>
00934           friend Variable operator+ 
00935             (const Dynamic<ST1> &quantity1, 
00936                       const M1<BQ, DerivedQuantity<QT, SU, DQT> > &quantity2)
00937           {Variable new_variable (quantity1);
00938            return new_variable + quantity2;
00939           }
00940 
00942 
00956         Variable & operator-= (const Variable &variable)
00957           {if(BSUtilities::IF<BSUtilities::SameType<UL, 
00958             Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00959               unit::GenericUnit>, Loki::NullType> >::sameType, 
00960                 AssignmentError<true>, AssignmentError<false> >::RET::RET)
00961            _value -= variable.value (); 
00962            return *this;
00963           }
00964 
00966 
00981         template <template<typename, typename> class M1, typename ST1, 
00982                                              typename SU1, typename DQT1>
00983           Variable & operator-= (const M1<Quantity<QT, ST1>, 
00984                                      DerivedQuantity<QT, SU1, DQT1> > &quantity)
00985             {_value = Reverse<StorageUnit, ST>::VAL 
00986               (Standardize<StorageUnit, ST>::VAL (_value) - 
00987                 Standardize<SU1, ST1>::VAL (quantity.value ()));
00988               return *this;
00989             }
00990 
00992 
01008         template <template<typename, typename> class M1, 
01009                             typename DIM1, typename ST1, typename SU1, typename DQT1>
01010           Variable & operator-= 
01011                (const M1<Quantity<GenericClass<DIM1>, ST1>, 
01012                              DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > &quantity)
01013             {_value = Reverse<StorageUnit, ST>::VAL 
01014               (Standardize<StorageUnit, ST>::VAL (_value) - 
01015                 Standardize<typename CheckSecondDimension<
01016                   V, M1<Quantity<GenericClass<DIM1>, ST1>,
01017                     DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > >
01018                         ::RET::StorageUnit, ST1>::VAL (quantity.value ()));
01019               return *this;
01020             }
01021 
01023 
01040         template<template<typename, typename> class M1, 
01041                          typename QT1, typename ST1, typename SU1, typename DQT1>
01042           Variable & operator-= (const M1<Quantity<QT1, ST1>, 
01043                                  DerivedQuantity<QT1, SU1, DQT1> > &quantity)
01044           {
01045             static const bool RET = 
01046               BSUtilities::IF<BSUtilities::SameType<QT, QT1>::sameType, 
01047                 DimensionError<false>, DimensionError<true> >::RET::RET;
01048             return *this;
01049           }
01050 
01052 
01056       template<template<typename, typename> class M1, 
01057                               typename QT1, typename ST1, typename SU1, typename DQT1>
01058       struct MinusGenerated
01059         {static V exec (const V &variable, 
01060              const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity)
01061             {return V (Reverse<StorageUnit, ST>::VAL 
01062               (Standardize<StorageUnit, ST>::VAL (variable.value ()) 
01063                 - Standardize<typename CheckSecondDimension<
01064                  V, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
01065                             ::RET::StorageUnit, ST1>::VAL (quantity.value ())));
01066             }
01067         };
01068         
01070 
01073         template<typename Q>
01074           struct Minus
01075             {static V exec (const V &variable, const Q &quantity)
01076               {V new_object (variable);
01077                 return new_object -= quantity;
01078               }
01079             };
01080 
01082 
01088         template <template<typename, typename> class M1, 
01089                               typename QT1, typename ST1, typename SU1, typename DQT1>
01090           Variable operator- (const M1<Quantity<QT1, ST1>, 
01091                                     DerivedQuantity<QT1, SU1, DQT1> > &quantity) const
01092             {return BSUtilities::IF<BSUtilities::SameType<UL, 
01093               Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
01094                 unit::GenericUnit>, Loki::NullType> >::sameType, 
01095                   typename MinusGenerated<M1, QT1, ST1, SU1, DQT1>::MinusGenerated, 
01096                   typename Minus<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
01097                                         ::Minus>::RET::exec (*this, quantity);
01098             }
01099 
01101 
01108         Variable operator- (const Dynamic<ST> &quantity) const
01109           {Variable new_variable (quantity);
01110            return *this - new_variable;
01111           }
01112 
01114 
01121         template<template<typename, typename> class M1, typename ST1>
01122           friend Variable operator- 
01123             (const Dynamic<ST1> &quantity1, 
01124                      const M1<BQ, DerivedQuantity<QT, SU, DQT> > &quantity2)
01125           {Variable new_variable (quantity1);
01126            return new_variable - quantity2;
01127           }
01128 
01130 
01133         Variable & operator*= (const ST factor)
01134            {_value *= factor;
01135              return *this;
01136            }
01137 
01139 
01141         Variable operator* (const ST factor) const
01142           {V new_object (*this);
01143             return new_object *= factor;
01144           }
01145 
01147 
01150       template<typename RHSST>
01151         Dynamic<RHSST> operator * (const Dynamic<RHSST> &rhs) const
01152         {return rhs * (*this);}
01153 
01155 
01167         template <template<typename, typename> class Q>
01168           friend V operator* 
01169             (const ST factor, const Q<Quantity<QT, ST>, 
01170                DerivedQuantity<QT, SU, DQT> > &variable)
01171                          {return V (variable) *= factor;}
01172 
01174 
01177         template<template<typename, typename> class FM, typename FQT, typename FST, typename FSU,
01178                                                                            typename FDQT>
01179           typename GenerateVariable<V, 
01180             FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > >::Add 
01181             operator* (const FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > &factor) const
01182             {
01183               return typename 
01184                 GenerateVariable<V, FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > >::Add 
01185                                             (standard_value () * factor.standard_value ());
01186             }
01187 
01189 
01193         Variable & operator/= (const ST divisor)
01194            {_value /= divisor;
01195              return *this;
01196            }
01197   
01199 
01201         Variable operator/ (const ST divisor) const
01202           {V new_object (*this);
01203             return new_object /= divisor;
01204           }
01205 
01207 
01212         template<class Q>
01213           typename GenerateVariable<Variable, Q>::Sub operator/ 
01214                                                 (const Q &factor) const
01215             {
01216               return typename GenerateVariable<Variable, Q>::Sub 
01217                          (standard_value () / factor.standard_value ());
01218             }
01219 
01221 
01224         friend
01225           typename GenerateVariable<Variable, Loki::NullType>::Inv 
01226             operator/ (const ST numerator, const Variable &factor)
01227           {
01228             return typename 
01229               GenerateVariable<Variable, Loki::NullType>::Inv 
01230                                  (numerator / factor.standard_value ());
01231           }
01232 
01234 
01237         const Variable operator+ (void) const
01238           {return Variable (*this);}
01239 
01241 
01244         const Variable operator- (void) const
01245           {return Variable (*this) *= ST(-1.0);}
01246 
01248 
01251         Variable & operator++ ()
01252           {++_value;
01253            return *this;
01254           }
01255 
01257 
01260         Variable & operator-- ()
01261           {--_value;
01262            return *this;
01263           }
01264 
01266 
01270         const Variable operator++ (int)
01271           {Variable temp (*this);
01272            ++*this;
01273            return temp;
01274           }
01275 
01277 
01281         const Variable operator-- (int)
01282           {Variable temp (*this);
01283            --*this;
01284            return temp;
01285           }
01286 
01288 //  end arithmetic operators for Variable 
01290 
01292 //  comparison operators for Variable 
01294 
01296 
01310 #define QUANTITY_COMPARISON_OPERATORS(mode, opName, opType) \
01311   bool opName (const mode &rhs) const \
01312     {return _value opType rhs.value ();} \
01313   template <template<typename, typename> class RM, typename RST, typename RSU, typename RDQT> \
01314     bool opName (const RM<Quantity<QT, RST>, DerivedQuantity<QT, RSU, RDQT> > &rhs) const \
01315       {return standard_value () opType rhs.standard_value ();} \
01316   template <template<typename, typename> class RM, \
01317                                  typename RQT, typename RST, typename RSU, typename RDQT> \
01318     bool opName (const RM<Quantity<RQT, RST>, DerivedQuantity<RQT, RSU, RDQT> > &rhs) const \
01319       {return (*this opType V(rhs));} \
01320   bool opName (const Dynamic<ST> &dynamic) const \
01321     {if (dynamic.isCommensurable (*this)) \
01322        return standard_value () opType dynamic.value (); \
01323      else \
01324        {throw DimensionMismatch ();} }
01325 
01326 QUANTITY_COMPARISON_OPERATORS(Variable, operator==, ==)
01327 QUANTITY_COMPARISON_OPERATORS(Variable, operator!=, !=)
01328 QUANTITY_COMPARISON_OPERATORS(Variable, operator>, >)
01329 QUANTITY_COMPARISON_OPERATORS(Variable, operator<, <)
01330 QUANTITY_COMPARISON_OPERATORS(Variable, operator>=, >=)
01331 QUANTITY_COMPARISON_OPERATORS(Variable, operator<=, <=)
01332 
01334 //  end comparison operators for Variable 
01336 
01338 //  mathematical functions for Variable 
01340 
01342 
01348         template<long N, long D>
01349           typename GenerateVariable<Variable, 
01350                                      BSUtilities::Rational<N, D> >::Mult
01351                          pow (const BSUtilities::Rational<N, D> &) const
01352           {return std::pow (standard_value (), 
01353                         static_cast<double>(N)/static_cast<double>(D));}
01354 
01356 
01362         template<int I>
01363           typename GenerateVariable<Variable, 
01364               BSUtilities::Rational<I, long(1)> >::Mult 
01365                               pow (const typename Loki::Int2Type<I>) const
01366           {return std::pow (standard_value (), I);}
01367 
01369 
01375     template<class T>
01376       Dynamic<ST> pow (const T &exp) const
01377                                 {return Dynamic<ST>::pow (*this, exp);}
01378 
01380 
01387         typename 
01388           GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01389                                                >::Mult sqrt (void) const
01390           {
01391             return typename 
01392               GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01393                                  >::Mult (std::sqrt(standard_value ()));
01394           }
01395 
01397 //  end mathematical functions for Variable 
01399 
01401 //  io functions for Variable 
01403 
01405 
01408       std::ostream & print_value (std::ostream &os) const
01409         {return os << _value << " " << StorageUnit::Symbol ();}
01410 
01412 
01414       void operator>> (std::string &str) const
01415           {str = BSUtilities::Conversion<Variable>::to_string (*this);}
01416 
01418 
01422       std::ostream & operator>> (std::ostream &os) const
01423                    {return this->print (os);}
01424 
01426 
01428       void read_value (const std::string &str);
01429 
01431 
01433       friend void operator>> 
01434         (const std::string &str, Variable &variable) 
01435                                             {variable.read_value (str);}
01436 
01438       void operator<< (const std::string &str) {read_value (str);}
01439 
01441 
01445       std::istream & operator<< (std::istream &is) 
01446         {std::string string; getline (is, string); 
01447                                   this->read_value (string); return is;}
01448 
01450 
01453       friend std::istream & operator>> 
01454         (std::istream &is, Variable &variable) {return variable << is;}
01455 
01457 //  end io functions for Variable 
01459 
01461 //  serialization of Variable 
01463 
01464   private:
01466       friend class boost::serialization::access;
01467 
01469 
01471       template<typename Archive>
01472         void serialize (Archive &ar, const unsigned int )
01473         {
01474           ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BQ);
01475           ar & BOOST_SERIALIZATION_NVP(_value);
01476         }
01477 
01479 //  end serialization of Variable 
01481 
01482     };
01483 
01485 //  end Variable 
01487 
01492 template<typename QT, typename ST, typename SU, typename DQT>
01493   void Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >::read_value 
01494                                                           (const std::string &str)
01495     {
01496       std::string value;
01497       std::string unit;
01498 
01499       std::string::size_type start;
01500       std::string::size_type end;
01501 
01502       start = str.find_first_not_of (" \0");
01503       end = start;
01504 
01505       if (RS.name ())
01506       {
01507         if (start == std::string::npos)
01508           throw InputError ();
01509 
01510         else
01511         {
01512           end = str.find_first_of (" \0", start);
01513 
01514           if (end == std::string::npos)
01515             BQ::namestring = str.substr (start);
01516 
01517           else
01518             BQ::namestring = (str.substr (start, end - start));
01519         }
01520       }
01521 
01522       start = str.find_first_not_of (" \0", end);
01523       end = start;
01524  
01525       if (RS.symbol ())
01526       {
01527         if (start == std::string::npos)
01528           throw InputError ();
01529 
01530         else
01531         {
01532           end = str.find_first_of (" \0", start);
01533 
01534           if (end == std::string::npos)
01535             BQ::symbolstring = str.substr (start);
01536 
01537           else
01538             BQ::symbolstring = (str.substr (start, end - start));
01539         }
01540       }
01541 
01542       start = str.find_first_not_of (" \0", end);
01543       end = start;
01544 
01545       if (RS.equal () && (RS.name () || RS.symbol ()))
01546       {
01547         if (start == std::string::npos)
01548           throw InputError ();
01549 
01550         else
01551         {
01552           end = str.find_first_of (" \0", start);
01553 
01554           if (end == std::string::npos)
01555             throw InputError ();
01556 
01557           else if (str.substr (start, end - start) != "=")
01558             throw InputError ();
01559         }
01560       }
01561 
01562       start = str.find_first_not_of (" \0", end);
01563       end = start;
01564  
01565       if (start == std::string::npos)
01566         throw InputError ();
01567 
01568       else
01569       {
01570         end = str.find_first_of (" \0", start);
01571 
01572         if (end == std::string::npos)
01573           value = str.substr (start);
01574 
01575         else
01576           value = str.substr (start, end - start);
01577 
01578         start = str.find_first_not_of (" \0", end);
01579 
01580         if (start == std::string::npos)
01581           unit = "";
01582 
01583         else
01584         {
01585           end = str.find_first_of (" \0\n", start);
01586 
01587           if ((end = std::string::npos))
01588             unit = str.substr (start);
01589 
01590           else
01591             unit = str.substr (start, end - start);
01592         }
01593       }
01594    
01595       ST intermediate;
01596 
01597       try {
01598         intermediate = BSUtilities::Conversion<ST>::string_to (value);
01599           }
01600 
01601       catch (BSUtilities::ConversionFailure) {throw InputError ();}
01602 
01603       start = unit.find_first_not_of (" \0");
01604       end = start;
01605 
01606 /* if no unit symbol string is present in input, assume one or use
01607    storage unit
01608 */
01609       if (start == std::string::npos)
01610       {
01611         std::string assume_unit;
01612 
01613 /* if a unit has been set, use this for conversion of intermediate
01614    (value); else do nothing, since we assume that the value is in 
01615    the storage unit and can be stored directly. 
01616 */
01617         if ((assume_unit = RS.unit ()) != "")
01618         {
01619           try {
01620             ::unit::Unit<UT> *unitp = BQ::findBySymbol (assume_unit);
01621             intermediate 
01622               = Reverse<SU, ST>::VAL (dynamic_standardize<UL>::VAL (intermediate, *unitp));
01623 
01624             delete (unitp);
01625               }
01626 
01627           catch (UnitMismatch) {throw InputError ();}
01628 
01629         }
01630       }
01631 
01632 /* if unit symbol string is present in input, use it for conversion
01633    of intermediate (value); assume that the rest of the input is unit symbol string.
01634 */
01635       else
01636       {
01637         end = unit.find_first_of (" \0", start);
01638         try {
01639           ::unit::Unit<UT> *unitp = BQ::findBySymbol (unit.substr (start));
01640 
01641           intermediate 
01642             = Reverse<SU, ST>::VAL (dynamic_standardize<UL>::VAL (intermediate, *unitp));
01643 
01644           delete (unitp);
01645             }
01646         catch (UnitMismatch) {throw InputError ();}
01647       }
01648 
01649       _value = intermediate;
01650 
01651     }
01652 
01654 
01658 template<template<typename, typename> class Q1, typename QT1, typename DQT1, 
01659          template<typename, typename> class Q2, typename QT2, typename DQT2,
01660                                                                typename ST>
01661   struct GenerateVariable
01662                <Q1<Quantity<QT1, ST>, DQT1>, Q2<Quantity<QT2, ST>, DQT2> >
01663   {
01664      private:
01665        typedef typename QuantityTraits<QT1>::Dimension Dim1;
01666        typedef typename QuantityTraits<QT2>::Dimension Dim2;
01667 
01669        typedef typename Dim1::template Add<Dim2> AddT;
01670        typedef Quantity<GenericClass<typename AddT::Res>, ST> AddNewQ;
01671 
01673        typedef typename Dim1::template Sub<Dim2> SubT;
01674        typedef Quantity<GenericClass<typename SubT::Res>, ST> SubNewQ;
01675 
01676      public:
01678 
01680        typedef Variable<AddNewQ> Add;
01681 
01683 
01685        typedef Variable<SubNewQ> Sub;
01686   };
01687 
01689 
01692 template<template<typename, typename> class Q, 
01693                                typename QT, typename ST, typename DQT>
01694   struct GenerateVariable <Q<Quantity<QT, ST>, DQT>, Loki::NullType>
01695   {
01696      private:
01698        typedef typename QuantityTraits<QT>::Dimension::Inv InvT;
01699        typedef Quantity<GenericClass<typename InvT::Res>, ST> InvNewQ;
01700 
01701      public:
01703 
01705        typedef Variable<InvNewQ> Inv;
01706   };
01707 
01709 
01712 template<template<typename, typename> class Q, typename QT, 
01713                                    class ST, class DQT, long N, long D>
01714   struct GenerateVariable
01715     <Q<Quantity<QT, ST>, DQT>, BSUtilities::Rational<N, D> >
01716   {
01717      private:
01719        typedef typename QuantityTraits<QT>::Dimension::template
01720                                                        Mult<N, D> MultT;
01721 
01722        typedef Quantity<GenericClass<typename MultT::Res>, ST> MultNewQ;
01723 
01724      public:
01726 
01728        typedef Variable<MultNewQ> Mult;
01729   };
01730 
01732 
01739 template<template<typename, typename> class Q, typename QT, 
01740            typename ST, typename SU, typename DQT>
01741   inline typename GenerateVariable
01742     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<1, 2> >::Mult 
01743       sqrt (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity)
01744           {
01745             return typename 
01746               GenerateVariable<Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01747                 BSUtilities::Rational<1, 2> >::Mult (quantity.sqrt());
01748           }
01749 
01751 
01758 template<template<typename, typename> class Q, typename QT, 
01759                                       typename ST, typename SU, typename DQT, int I>
01760   inline typename GenerateVariable
01761     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<I, long(1)> >::Mult 
01762       pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, 
01763                                             typename Loki::Int2Type<I>)
01764           {
01765             return typename 
01766               GenerateVariable<Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01767                 BSUtilities::Rational<long(I), long(1)> >::Mult
01768                               (quantity.pow(Loki::Int2Type<I> ()));
01769           }
01770 
01772 
01780 template<template<typename, typename> class Q, typename QT, 
01781                          typename ST, typename SU, typename DQT, long N, long D>
01782   inline typename GenerateVariable
01783     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<N, D> >::Mult 
01784       pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, 
01785                                    const BSUtilities::Rational<N, D> &)
01786       { return typename 
01787           GenerateVariable <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01788                                      BSUtilities::Rational<N, D> >::Mult
01789             (quantity.pow(BSUtilities::Rational<N, D> ()));
01790           }
01791 
01793 
01798 template<template<typename, typename> class Q, typename QT, 
01799                              typename ST, typename SU, typename DQT, typename T>
01800   inline Dynamic<ST> 
01801     pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, const T &exp) 
01802           {return Dynamic<ST> (quantity.pow(exp));}
01803 
01805 
01807 template<template<typename, typename> class Q, typename QT, 
01808                                           typename ST, typename SU, typename DQT>
01809   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01810     abs (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01811     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01812                               (std::abs (variable.value ()));}
01813 
01815 
01817 template<template<typename, typename> class Q, typename QT, 
01818                                          typename ST, typename SU, typename DQT>
01819   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01820     ceil (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01821     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01822                                (std::ceil (variable.value ()));}
01823 
01825 
01827 template<template<typename, typename> class Q, typename QT, 
01828                                           typename ST, typename SU, typename DQT>
01829   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01830     floor (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01831     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01832                                 (std::floor (variable.value ()));}
01833 
01835 
01837 template<template<typename, typename> class Q, typename QT, 
01838                                            typename ST, typename SU, typename DQT>
01839   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01840     frexp (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable, int *exponent)
01841     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01842                         (std::frexp (variable.value (), exponent));}
01843 
01845 
01847 template<template<typename, typename> class Q, typename QT, 
01848                                           typename ST, typename SU, typename DQT>
01849   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01850     ldexp (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable, int exponent)
01851     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01852                     (std::ldexp (variable.value (), exponent));}
01853 
01855 
01862 template<template<typename, typename> class Q1, 
01863   template<typename, typename> class Q2, typename QT, 
01864                                         typename ST, typename SU, typename DQT>
01865   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01866     fmod (const Q1<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity1,
01867                       const Q2<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity2)
01868     {return 
01869       Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01870             (std::fmod (quantity1.value (), quantity2.value ()));
01871     }
01872 
01874 
01880 template<template<typename, typename> class Q1, 
01881   template<typename, typename> class Q2, typename QT, 
01882             typename ST, typename SU, typename DQT1, class DQT2> 
01883   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> >
01884     fmod (const Q1<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> > &quantity1,
01885                       const Q2<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT2> > &quantity2)
01886   {return 
01887     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> >
01888       (Reverse<SU, ST>::VAL 
01889         (std::fmod (quantity1.standard_value (), quantity2.standard_value ())));
01890   }
01891 
01893 
01899 template <template<typename, typename> class Q1, typename QT1, 
01900         typename ST, typename SU1, typename DQT1, 
01901   template<typename, typename> class Q2, typename QT2, typename SU2, typename DQT2> 
01902   inline Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01903     fmod (const Q1<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > &quantity1,
01904                         const Q2<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> > &quantity2)
01905   {return Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01906     (Reverse<SU1, ST>::VAL 
01907       (std::fmod (quantity1.standard_value (), Standardize<typename CheckSecondDimension<
01908         Q1<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >, 
01909           Q2<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >
01910                      >::RET::StorageUnit, ST>::VAL (quantity2.value ()))));
01911   }
01912 
01914 
01917 template<template<typename, typename> class Q, typename QT, 
01918                                        typename ST, typename SU, typename DQT> 
01919   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01920     modf (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity,
01921                        Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > *integral)
01922   {ST i_ptr; 
01923     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01924                    new_variable (std::modf (quantity.value (), &i_ptr));
01925     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > int_quantity (i_ptr);
01926                           *integral = int_quantity; return new_variable;
01927         }
01928 
01930 
01934 template<template<typename, typename> class Q, typename QT, 
01935           typename ST, typename SU1, typename DQT1, typename SU2, typename DQT2>
01936   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >
01937     modf (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> > &quantity,
01938                        Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU2, DQT2> > *integral)
01939   {ST i_ptr; 
01940     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >
01941                    new_variable (std::modf (quantity.value (), &i_ptr));
01942     *integral = Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU2, DQT2> >
01943                    (Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >(i_ptr)); 
01944     return new_variable;
01945   }
01946 
01948 
01952 template<template<typename, typename> class Q, typename QT1, 
01953                typename SU1, typename DQT1, typename QT2, typename SU2, typename DQT2, typename ST>
01954   inline Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01955   modf (const Q<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > &quantity,
01956                             Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> > *integral)
01957   {ST i_ptr; 
01958     typename CheckSecondDimension<Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >,
01959       Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > >::RET
01960         new_variable (Reverse<SU1, ST>::VAL 
01961                       (std::modf (quantity.standard_value (), &i_ptr)));
01962     *integral = Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >
01963             (Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >(i_ptr)); 
01964   return new_variable;
01965   }
01966 
01968 //  mathematical functions producing a dimensionless result
01969 //  exp,log, and trigonometric function
01971 
01973 
01975       struct Dummy;
01976 
01978 
01993 #define QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(function, helper) \
01994 template<typename QT, typename ST> struct helper {static ST exec (const Quantity<QT, ST> &quantity) \
01995 {return ST(std::function (quantity.value ()));}}; \
01996 template<template<typename, typename> class M, typename QT, typename ST, typename SU, typename DQT> \
01997 inline typename GenerateVariable<M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, \
01998 BSUtilities::Rational<0> >::Mult \
01999 function (const M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity) \
02000 {return typename GenerateVariable<M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, \
02001 BSUtilities::Rational<0> >::Mult (BSUtilities::IF<CheckDimensionality<Quantity<QT, ST> >::RET, \
02002 typename helper<QT, ST>::helper, Dummy>::RET::exec (quantity));}
02003 
02004 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(exp, expHelper)
02005 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(log, logHelper)
02006 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(log10, log10Helper)
02007 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(sin, sinHelper)
02008 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(cos, cosHelper)
02009 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(tan, tanHelper)
02010 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(sinh, sinhHelper)
02011 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(cosh, coshHelper)
02012 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(tanh, tanhHelper)
02013 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(asin, asinHelper)
02014 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(acos, acosHelper)
02015 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(atan, atanHelper)
02016 
02018 
02025 template<template<typename, typename> class M1, typename QT1, typename ST1, typename SU1, typename DQT1,
02026      template<typename, typename> class M2, typename QT2, typename ST2, typename SU2, typename DQT2>
02027   inline typename GenerateVariable<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> >, 
02028     M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > >::Sub 
02029     atan2 (const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity,
02030                            const M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > &quantity2)
02031       {return typename GenerateVariable<typename BSUtilities::IF<SameDimensioned<Quantity<QT1, ST1>,
02032          Quantity<QT2, ST2> >::EQ, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> >, 
02033            DimensionError<true> >::RET, M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > >::Sub
02034           (std::atan2 (quantity.standard_value (), quantity2.standard_value ()));}
02035 
02037 //  end mathematical functions producing a dimensionless result
02039 
02040 } // end namespace quantity
02041 
02042 #endif /* _Variable_h */

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