00001 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef _Variable_h
00025 #define _Variable_h
00026 
00027 
00028 #include "Quantities/Quantity/Quantity.h"
00029 #include "Quantities/Quantity/QuantityError.h"
00030 #include "Quantities/Quantity/Generic.h"
00031 #include "Quantities/Quantity/Dynamic.h"
00032 
00033 
00034 #include "loki/Typelist.h"
00035 #include "loki/NullType.h"
00036 #include "loki/HierarchyGenerators.h"
00037 
00038 
00039 #include <boost/serialization/base_object.hpp>
00040 
00041 namespace quantity {
00042 
00044 
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 
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 
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 
00214 
00216 
00218 
00221 template<typename Q1, typename Q2> struct GenerateVariable;
00222 
00224 
00225 
00226 
00228 
00230 
00235 template<typename BQ, typename DQ = DerivedQuantity<typename BQ::QT, 
00236             typename BQ::DU, typename BQ::DDQ> > class Variable;
00237 
00239 
00248 template<typename QT, typename ST, typename DQSU, typename DQT>
00249   class Variable<Quantity<QT, ST>, DerivedQuantity<QT, DQSU, DQT> > 
00250                                              : public Quantity<QT, ST>
00251     {
00252       public:
00254 
00256         typedef typename QuantityTraits<QT>::Dimension DIM;
00257 
00259 
00261         typedef typename QuantityTraits<QT>::UnitType UT;
00262 
00264 
00266         typedef typename QuantityTraits<QT>::UnitList UL;
00267 
00269 
00272         typedef Quantity<QT, ST> BQ;
00273 
00275 
00278         typedef typename BQ::DU DU;
00279 
00281 
00283         typedef typename unit::ValidUnit<DQSU, UL>::RET SU;
00284 
00286 
00288         typedef Variable<BQ, DerivedQuantity<QT, SU, DQT> > V;
00289 
00290       private:
00292 
00296         ST _value;
00297 
00299 
00301 
00302       public:
00304 
00310         Variable (void) : BQ (), _value (ST(0)) 
00311           {name (Name<QT, DQT>::exec ()); symbol (Symbol<QT, DQT>::exec ());}
00312 
00314 
00320         Variable (const ST &value) : BQ (), _value (value)
00321           {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());}
00322 
00324 
00331         Variable (const ST &value, const std::string &namestring, 
00332           const std::string &symbolstring) : BQ (), _value (value)
00333           {BQ::name (namestring); BQ::symbol (symbolstring);}
00334 
00336 
00343         template<typename NU>
00344           Variable (const ST &value, const NU &) 
00345             : BQ (), _value (unit::Reverse<SU>::VAL 
00346               (unit::Standard<typename unit::ValidUnit<NU, UL>::RET>::VAL
00347                                                                        (value)))
00348             {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());}
00349 
00351 
00361         template<typename NU>
00362           Variable (const ST &value, const NU &, 
00363                  const std::string &namestring, const std::string &symbolstring)
00364             : BQ (), _value (unit::Reverse<SU>::VAL 
00365              (unit::Standard<typename unit::ValidUnit<NU, UL>::RET>::VAL 
00366                                                                        (value)))
00367             {BQ::name (namestring); BQ::symbol (symbolstring);}
00368 
00370 
00382         Variable (const ST value, const std::string &unitsymbol) : BQ ()
00383           {name (Name<QT, DQT>::exec ()); symbol(Symbol<QT, DQT>::exec ());
00384             _value = unit::Reverse<SU>::VAL
00385                (unit::standard<UL>::VAL (value, unitsymbol));
00386           }
00387 
00389 
00399         Variable (const ST value, const char * unitsymbol) : BQ ()
00400           {name (Name<QT, DQT>::exec ()); symbol (Symbol<QT, DQT>::exec ());
00401             _value = unit::Reverse<SU>::VAL
00402                (unit::standard<UL>::VAL (value, std::string (unitsymbol)));
00403             }
00404 
00406 
00408 
00410 
00412 
00414 
00419         template<template<typename, typename> class SM, typename SST>
00420           Variable (const SM<Quantity<QT, SST>, DQT> &quantity) 
00421             : BQ (), _value (quantity.value ())
00422               {name (quantity.BQ::name ()); symbol (quantity.BQ::symbol ());}
00423  
00425 
00435         template<template<typename, typename> class SM, 
00436                                     typename SST, typename SSU, typename SDQT>
00437           Variable (const SM<Quantity<QT, SST>, 
00438                                   DerivedQuantity<QT, SSU, SDQT> > &quantity)
00439             : BQ (), _value (unit::Reverse<SU>::VAL 
00440               (unit::Standard<SSU>::VAL (quantity.value ())))
00441               {name (quantity.Quantity<QT, SST>::name ()); 
00442                   symbol (quantity.Quantity<QT, SST>::symbol ());}
00443 
00445 
00452         template<template<typename, typename> class SM, 
00453                  typename SDIM, typename SST, typename SSU, typename SDQT>
00454           Variable (const SM<Quantity<GenericClass<SDIM>, SST>, 
00455             DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > &quantity)
00456             : BQ (), _value (unit::Reverse<SU>::VAL
00457               (unit::Standard<typename
00458                  CheckSecondDimension<V, 
00459                    SM<Quantity<GenericClass<SDIM>, SST>, 
00460                      DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > >
00461                        ::RET::SU>::VAL (quantity.value ())))
00462               {name (quantity.Quantity<GenericClass<SDIM>, SST>::name ()); 
00463                    symbol (quantity.Quantity<GenericClass<SDIM>, SST>::symbol ());}
00464 
00466 
00479         template<template<typename, typename> class SM, 
00480                       typename SQT, typename SST, typename SSU, typename SDQT>
00481           Variable (const SM<Quantity<SQT, SST>, 
00482                                    DerivedQuantity<SQT, SSU, SDQT> > &quantity)
00483             : BQ (), _value (convertValue<V, SM<Quantity<SQT, SST>, 
00484               DerivedQuantity<SQT, SSU, SDQT> > >::exec (quantity))
00485               {name (quantity.Quantity<SQT, SST>::name ()); 
00486                   symbol (quantity.Quantity<SQT, SST>::symbol ());}
00487 
00488 
00490 
00494         template<typename SST>
00495           Variable (const Dynamic<SST> &dynamic)
00496             {if (dynamic.isCommensurable (*this))
00497                _value = unit::Reverse<SU>::VAL (dynamic.value ());
00498              else
00499                {throw DimensionMismatch ();}
00500 
00501             }
00502 
00504 
00506 
00508 
00510 
00512 
00519         Variable & operator= (const Variable &variable)
00520           {if (this != &variable)
00521              {_value = variable.value ();}
00522            return *this;
00523           }
00524 
00526 
00549         template<template<typename, typename> class SM, typename SST, 
00550           typename SSU, typename SDQT>
00551           Variable & operator= (const SM<Quantity<QT, SST>, 
00552                                      DerivedQuantity<QT, SSU, SDQT> > &quantity)
00553           {_value = unit::Reverse<SU>::VAL (unit::Standard<SSU>::VAL 
00554                                                            (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 = unit::Reverse<SU>::VAL
00591                (unit::Standard<typename
00592                  CheckSecondDimension<V, 
00593                               Variable<Quantity<GenericClass<SDIM>, SST>, 
00594                    DerivedQuantity<GenericClass<SDIM>, SSU, SDQT> > >
00595                       ::RET::SU>::VAL (quantity.value ()));
00596              return *this;
00597             }
00598 
00600 
00615         template<template<typename, typename> class SM, 
00616                           typename SQT, typename SST, typename SSU, typename SDQT>
00617           Variable & operator= 
00618             (const SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > &quantity)
00619           {*this = V(quantity);
00620            return *this;
00621           }
00622 
00624 
00632       template<typename SST>
00633         Variable & operator= (const Dynamic<SST> &dynamic)
00634           {if (dynamic.isCommensurable (*this))
00635              _value = unit::Reverse<SU>::VAL (dynamic.value ());
00636            else
00637              {throw DimensionMismatch ();}
00638            return *this;
00639           }
00640 
00642 
00648       Variable & operator= (const std::string &str) 
00649         {this->read_value (str); return *this;}
00650 
00652 
00658       Variable & operator= (const char * str) {this->read_value (str); return *this;}
00659 
00661 
00671     template <typename T>
00672       Variable & operator= (const T &);
00673 
00675 
00677 
00679 
00681 
00682     public:
00684 
00686         ST value (void) const {return _value;}
00687 
00689 
00692         ST standard_value (void) const 
00693                      {return unit::Standard<SU>::VAL (_value);}
00694 
00696 
00702         template<typename NU>
00703           Variable<Quantity<QT, ST>, 
00704                      DerivedQuantity<QT, NU, DQT> > value (const NU &) const
00705             {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, NU, DQT> > 
00706                 (unit::Reverse<typename unit::ValidUnit<NU, UL>::RET>::VAL
00707                                  (unit::Standard<SU>::VAL (_value)));}
00708 
00710 
00720         ST value (const std::string &unitsymbol)
00721           {ST value;
00722            value = unit::reverse<UL>::VAL
00723                           (unit::Standard<SU>::VAL (_value), unitsymbol);
00724            return value;
00725           }
00726 
00728         static std::string QuantityName (void) 
00729           {return Name<QT, DQT>::exec ();}
00730 
00732 
00734         ST value (const char * unitsymbol)
00735           {return value (std::string (unitsymbol));}
00736 
00738 
00740         std::string unitsymbol (void) const {return SU::Symbol ();}
00741 
00743 
00745         static std::string Unitsymbol (void) {return SU::Symbol ();}
00746 
00748 
00750         std::string unitname (void) const {return SU::Name ();}
00751 
00753 
00755         static std::string Unitname (void) {return SU::Name ();}
00756 
00758 
00760 
00762 
00764 
00766 
00780         Variable & operator+= (const Variable &variable)
00781           {if(BSUtilities::IF<BSUtilities::SameType<UL, 
00782             Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit>, 
00783               Loki::NullType> >::sameType, AssignmentError<true>, 
00784                                      AssignmentError<false> >::RET::RET)
00785            _value += variable.value (); 
00786            return *this;
00787           }
00788 
00790 
00805         template <template<typename, typename> class M1, typename ST1, 
00806                                                 typename SU1, typename DQT1>
00807           Variable & operator+= (const M1<Quantity<QT, ST1>, 
00808                                     DerivedQuantity<QT, SU1, DQT1> > &quantity)
00809             {_value = unit::Reverse<SU>::VAL 
00810               (unit::Standard<SU>::VAL (_value) + 
00811                  unit::Standard<SU1>::VAL (quantity.value ()));
00812               return *this;
00813             }
00814 
00816 
00832         template <template<typename, typename> class M1, 
00833                                     typename DIM1, typename ST1, typename SU1, typename DQT1>
00834           Variable & operator+= (const M1<Quantity<GenericClass<DIM1>, ST1>,
00835                                DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > &quantity)
00836             {_value = unit::Reverse<SU>::VAL 
00837               (unit::Standard<SU>::VAL (_value) + 
00838                 unit::Standard<typename CheckSecondDimension<V, 
00839                   M1<Quantity<GenericClass<DIM1>, ST1>, 
00840                     DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > >
00841                           ::RET::SU>::VAL (quantity.value ()));
00842               return *this;
00843             }
00844 
00846 
00863         template<template<typename, typename> class M1, 
00864                                  typename QT1, typename ST1, typename SU1, typename DQT1>
00865           Variable & operator+= (const M1<Variable<QT1, ST1>, 
00866                                     DerivedQuantity<QT1, SU1, DQT1> > &quantity)
00867           {
00868             static const bool RET = 
00869               BSUtilities::IF<BSUtilities::SameType<QT, QT1>::sameType, 
00870                 DimensionError<false>, DimensionError<true> >::RET::RET;
00871             return *this;
00872           }
00873 
00875 
00879       template<template<typename, typename> class M1, 
00880                      typename QT1, typename ST1, typename SU1, typename DQT1>
00881       struct PlusGenerated
00882         {static V exec 
00883           (const V &variable, 
00884              const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity)
00885             {return V (unit::Reverse<SU>::VAL 
00886               (unit::Standard<SU>::VAL (variable.value ()) 
00887                 + unit::Standard<typename CheckSecondDimension<
00888                   V, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
00889                            ::RET::SU>::VAL (quantity.value ())));
00890             }
00891         };
00892         
00894 
00897         template<class Q>
00898           struct Plus
00899             {static V exec (const V &variable, const Q &quantity)
00900               {V new_object (variable);
00901                 return new_object += quantity;
00902               }
00903             };
00904 
00906 
00912         template <template<typename, typename> class M1, 
00913                  typename QT1, typename ST1, typename SU1, typename DQT1>
00914           Variable operator+ (const M1<Quantity<QT1, ST1>, 
00915                          DerivedQuantity<QT1, SU1, DQT1> > &quantity) const
00916             {return BSUtilities::IF<BSUtilities::SameType<UL, 
00917               Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00918                 unit::GenericUnit>, Loki::NullType> >::sameType, 
00919                   typename PlusGenerated<M1, QT1, ST1, SU1, DQT1>::PlusGenerated, 
00920                     typename Plus<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
00921                                       ::Plus>::RET::exec (*this, quantity);
00922             }
00923 
00925 
00932         template <typename SST>
00933           Variable operator+ (const Dynamic<SST> &quantity) const
00934             {Variable new_variable (quantity);
00935              return *this + new_variable;
00936             }
00937 
00939 
00946         template<template<typename, typename> class M1, typename ST1>
00947           friend Variable operator+ 
00948             (const Dynamic<ST1> &quantity1, 
00949                       const M1<BQ, DerivedQuantity<QT, SU, DQT> > &quantity2)
00950           {Variable new_variable (quantity1);
00951            return new_variable + quantity2;
00952           }
00953 
00955 
00969         Variable & operator-= (const Variable &variable)
00970           {if(BSUtilities::IF<BSUtilities::SameType<UL, 
00971             Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00972               unit::GenericUnit>, Loki::NullType> >::sameType, 
00973                 AssignmentError<true>, AssignmentError<false> >::RET::RET)
00974            _value -= variable.value (); 
00975            return *this;
00976           }
00977 
00979 
00994         template <template<typename, typename> class M1, typename ST1, 
00995                                              typename SU1, typename DQT1>
00996           Variable & operator-= (const M1<Quantity<QT, ST1>, 
00997                                      DerivedQuantity<QT, SU1, DQT1> > &quantity)
00998             {_value = unit::Reverse<SU>::VAL 
00999               (unit::Standard<SU>::VAL (_value) - 
01000                 unit::Standard<SU1>::VAL (quantity.value ()));
01001               return *this;
01002             }
01003 
01005 
01021         template <template<typename, typename> class M1, 
01022                             typename DIM1, typename ST1, typename SU1, typename DQT1>
01023           Variable & operator-= 
01024                (const M1<Quantity<GenericClass<DIM1>, ST1>, 
01025                              DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > &quantity)
01026             {_value = unit::Reverse<SU>::VAL 
01027               (unit::Standard<SU>::VAL (_value) - 
01028                 unit::Standard<typename CheckSecondDimension<
01029                   V, M1<Quantity<GenericClass<DIM1>, ST1>,
01030                     DerivedQuantity<GenericClass<DIM1>, SU1, DQT1> > >
01031                         ::RET::SU>::VAL (quantity.value ()));
01032               return *this;
01033             }
01034 
01036 
01053         template<template<typename, typename> class M1, 
01054                          typename QT1, typename ST1, typename SU1, typename DQT1>
01055           Variable & operator-= (const M1<Quantity<QT1, ST1>, 
01056                                  DerivedQuantity<QT1, SU1, DQT1> > &quantity)
01057           {
01058             static const bool RET = 
01059               BSUtilities::IF<BSUtilities::SameType<QT, QT1>::sameType, 
01060                 DimensionError<false>, DimensionError<true> >::RET::RET;
01061             return *this;
01062           }
01063 
01065 
01069       template<template<typename, typename> class M1, 
01070                               typename QT1, typename ST1, typename SU1, typename DQT1>
01071       struct MinusGenerated
01072         {static V exec (const V &variable, 
01073              const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity)
01074             {return V (unit::Reverse<SU>::VAL 
01075               (unit::Standard<SU>::VAL (variable.value ()) 
01076                 - unit::Standard<typename CheckSecondDimension<
01077                  V, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
01078                             ::RET::SU>::VAL (quantity.value ())));
01079             }
01080         };
01081         
01083 
01086         template<typename Q>
01087           struct Minus
01088             {static V exec (const V &variable, const Q &quantity)
01089               {V new_object (variable);
01090                 return new_object -= quantity;
01091               }
01092             };
01093 
01095 
01101         template <template<typename, typename> class M1, 
01102                               typename QT1, typename ST1, typename SU1, typename DQT1>
01103           Variable operator- (const M1<Quantity<QT1, ST1>, 
01104                                     DerivedQuantity<QT1, SU1, DQT1> > &quantity) const
01105             {return BSUtilities::IF<BSUtilities::SameType<UL, 
01106               Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
01107                 unit::GenericUnit>, Loki::NullType> >::sameType, 
01108                   typename MinusGenerated<M1, QT1, ST1, SU1, DQT1>::MinusGenerated, 
01109                   typename Minus<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > >
01110                                         ::Minus>::RET::exec (*this, quantity);
01111             }
01112 
01114 
01121         Variable operator- (const Dynamic<ST> &quantity) const
01122           {Variable new_variable (quantity);
01123            return *this - new_variable;
01124           }
01125 
01127 
01134         template<template<typename, typename> class M1, typename ST1>
01135           friend Variable operator- 
01136             (const Dynamic<ST1> &quantity1, 
01137                      const M1<BQ, DerivedQuantity<QT, SU, DQT> > &quantity2)
01138           {Variable new_variable (quantity1);
01139            return new_variable - quantity2;
01140           }
01141 
01143 
01146         Variable & operator*= (const ST factor)
01147            {_value *= factor;
01148              return *this;
01149            }
01150 
01152 
01154         Variable operator* (const ST factor) const
01155           {V new_object (*this);
01156             return new_object *= factor;
01157           }
01158 
01160 
01163       template<typename RHSST>
01164         Dynamic<RHSST> operator * (const Dynamic<RHSST> &rhs) const
01165         {return rhs * (*this);}
01166 
01168 
01180         template <template<typename, typename> class Q>
01181           friend V operator* 
01182             (const ST factor, const Q<Quantity<QT, ST>, 
01183                DerivedQuantity<QT, SU, DQT> > &variable)
01184                          {return V (variable) *= factor;}
01185 
01187 
01190         template<template<typename, typename> class FM, typename FQT, typename FST, typename FSU,
01191                                                                            typename FDQT>
01192           typename GenerateVariable<V, 
01193             FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > >::Add 
01194             operator* (const FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > &factor) const
01195             {
01196               return typename 
01197                 GenerateVariable<V, FM<Quantity<FQT, FST>, DerivedQuantity<FQT, FSU, FDQT> > >::Add 
01198                                             (standard_value () * factor.standard_value ());
01199             }
01200 
01202 
01206         Variable & operator/= (const ST divisor)
01207            {_value /= divisor;
01208              return *this;
01209            }
01210   
01212 
01214         Variable operator/ (const ST divisor) const
01215           {V new_object (*this);
01216             return new_object /= divisor;
01217           }
01218 
01220 
01225         template<class Q>
01226           typename GenerateVariable<Variable, Q>::Sub operator/ 
01227                                                 (const Q &factor) const
01228             {
01229               return typename GenerateVariable<Variable, Q>::Sub 
01230                          (standard_value () / factor.standard_value ());
01231             }
01232 
01234 
01237         friend
01238           typename GenerateVariable<Variable, Loki::NullType>::Inv 
01239             operator/ (const ST numerator, const Variable &factor)
01240           {
01241             return typename 
01242               GenerateVariable<Variable, Loki::NullType>::Inv 
01243                                  (numerator / factor.standard_value ());
01244           }
01245 
01247 
01250         const Variable operator+ (void) const
01251           {return Variable (*this);}
01252 
01254 
01257         const Variable operator- (void) const
01258           {return Variable (*this) *= ST(-1.0);}
01259 
01261 
01264         Variable & operator++ ()
01265           {++_value;
01266            return *this;
01267           }
01268 
01270 
01273         Variable & operator-- ()
01274           {--_value;
01275            return *this;
01276           }
01277 
01279 
01284         const Variable operator++ (int)
01285           {Variable temp (*this);
01286            ++*this;
01287            return temp;
01288           }
01289 
01291 
01296         const Variable operator-- (int)
01297           {Variable temp (*this);
01298            --*this;
01299            return temp;
01300           }
01301 
01303 
01305 
01307 
01309 
01311 
01325 #define QUANTITY_COMPARISON_OPERATORS(mode, opName, opType) \
01326   bool opName (const mode &rhs) const \
01327     {return _value opType rhs.value ();} \
01328   template <template<typename, typename> class RM, typename RST, typename RSU, typename RDQT> \
01329     bool opName (const RM<Quantity<QT, RST>, DerivedQuantity<QT, RSU, RDQT> > &rhs) const \
01330       {return standard_value () opType rhs.standard_value ();} \
01331   template <template<typename, typename> class RM, \
01332                                  typename RQT, typename RST, typename RSU, typename RDQT> \
01333     bool opName (const RM<Quantity<RQT, RST>, DerivedQuantity<RQT, RSU, RDQT> > &rhs) const \
01334       {return (*this opType V(rhs));} \
01335   bool opName (const Dynamic<ST> &dynamic) const \
01336     {if (dynamic.isCommensurable (*this)) \
01337        return standard_value () opType dynamic.value (); \
01338      else \
01339        {throw DimensionMismatch ();} }
01340 
01341 QUANTITY_COMPARISON_OPERATORS(Variable, operator==, ==)
01342 QUANTITY_COMPARISON_OPERATORS(Variable, operator!=, !=)
01343 QUANTITY_COMPARISON_OPERATORS(Variable, operator>, >)
01344 QUANTITY_COMPARISON_OPERATORS(Variable, operator<, <)
01345 QUANTITY_COMPARISON_OPERATORS(Variable, operator>=, >=)
01346 QUANTITY_COMPARISON_OPERATORS(Variable, operator<=, <=)
01347 
01349 
01351 
01353 
01355 
01357 
01363         template<long N, long D>
01364           typename GenerateVariable<Variable, 
01365                                      BSUtilities::Rational<N, D> >::Mult
01366                          pow (const BSUtilities::Rational<N, D> &) const
01367           {return std::pow (standard_value (), 
01368                         static_cast<double>(N)/static_cast<double>(D));}
01369 
01371 
01377         template<int I>
01378           typename GenerateVariable<Variable, 
01379               BSUtilities::Rational<I, long(1)> >::Mult 
01380                               pow (const typename Loki::Int2Type<I>) const
01381           {return std::pow (standard_value (), I);}
01382 
01384 
01390     template<class T>
01391       Dynamic<ST> pow (const T &exp) const
01392                                 {return Dynamic<ST>::pow (*this, exp);}
01393 
01395 
01402         typename 
01403           GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01404                                                >::Mult sqrt (void) const
01405           {
01406             return typename 
01407               GenerateVariable<Variable, BSUtilities::Rational<1, 2> 
01408                                  >::Mult (std::sqrt(standard_value ()));
01409           }
01410 
01412 
01414 
01416 
01418 
01420 
01423       std::ostream & print_value (std::ostream &os) const
01424         {return os << _value << " " << SU::Symbol ();}
01425 
01427 
01429       void operator>> (std::string &str) const
01430           {str = BSUtilities::Conversion<Variable>::to_string (*this);}
01431 
01433 
01437       std::ostream & operator>> (std::ostream &os) const
01438                    {return this->print (os);}
01439 
01441 
01443       void read_value (const std::string &str);
01444 
01446 
01448       friend void operator>> 
01449         (const std::string &str, Variable &variable) 
01450                                             {variable.read_value (str);}
01451 
01453       void operator<< (const std::string &str) {read_value (str);}
01454 
01456 
01460       std::istream & operator<< (std::istream &is) 
01461         {std::string string; getline (is, string); 
01462                                   this->read_value (string); return is;}
01463 
01465 
01468       friend std::istream & operator>> 
01469         (std::istream &is, Variable &variable) {return variable << is;}
01470 
01472 
01474 
01476 
01478 
01479   private:
01481       friend class boost::serialization::access;
01482 
01484 
01486       template<typename Archive>
01487         void serialize (Archive &ar, const unsigned int )
01488         {
01489           ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BQ);
01490           ar & BOOST_SERIALIZATION_NVP(_value);
01491         }
01492 
01494 
01496 
01497     };
01498 
01500 
01502 
01507 template<typename QT, typename ST, typename SU, typename DQT>
01508   void Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >::read_value 
01509                                                     (const std::string &str)
01510     {
01511       std::string value;
01512       std::string unit;
01513 
01514       std::string::size_type start;
01515       std::string::size_type end;
01516 
01517       start = str.find_first_not_of (" \0");
01518       end = start;
01519 
01520       if (RS.name ())
01521       {
01522         if (start == std::string::npos)
01523           throw InputError ();
01524 
01525         else
01526         {
01527           end = str.find_first_of (" \0", start);
01528 
01529           if (end == std::string::npos)
01530             BQ::namestring = str.substr (start);
01531 
01532           else
01533             BQ::namestring = (str.substr (start, end - start));
01534         }
01535       }
01536 
01537       start = str.find_first_not_of (" \0", end);
01538       end = start;
01539  
01540       if (RS.symbol ())
01541       {
01542         if (start == std::string::npos)
01543           throw InputError ();
01544 
01545         else
01546         {
01547           end = str.find_first_of (" \0", start);
01548 
01549           if (end == std::string::npos)
01550             BQ::symbolstring = str.substr (start);
01551 
01552           else
01553             BQ::symbolstring = (str.substr (start, end - start));
01554         }
01555       }
01556 
01557       start = str.find_first_not_of (" \0", end);
01558       end = start;
01559 
01560       if (RS.equal () && (RS.name () || RS.symbol ()))
01561       {
01562         if (start == std::string::npos)
01563           throw InputError ();
01564 
01565         else
01566         {
01567           end = str.find_first_of (" \0", start);
01568 
01569           if (end == std::string::npos)
01570             throw InputError ();
01571 
01572           else if (str.substr (start, end - start) != "=")
01573             throw InputError ();
01574         }
01575       }
01576 
01577       start = str.find_first_not_of (" \0", end);
01578       end = start;
01579  
01580       if (start == std::string::npos)
01581         throw InputError ();
01582 
01583       else
01584       {
01585         end = str.find_first_of (" \0", start);
01586 
01587         if (end == std::string::npos)
01588           value = str.substr (start);
01589 
01590         else
01591           value = str.substr (start, end - start);
01592 
01593         start = str.find_first_not_of (" \0", end);
01594 
01595         if (start == std::string::npos)
01596           unit = "";
01597 
01598         else
01599         {
01600           end = str.find_first_of (" \0\n", start);
01601 
01602           if ((end = std::string::npos))
01603             unit = str.substr (start);
01604 
01605           else
01606             unit = str.substr (start, end - start);
01607         }
01608       }
01609    
01610       ST intermediate;
01611 
01612       try {
01613         intermediate = BSUtilities::Conversion<ST>::string_to (value);
01614           }
01615 
01616       catch (BSUtilities::ConversionFailure) {throw InputError ();}
01617 
01618       start = unit.find_first_not_of (" \0");
01619       end = start;
01620 
01621 
01622 
01623 
01624       if (start == std::string::npos)
01625       {
01626         std::string assume_unit;
01627 
01628 
01629 
01630 
01631 
01632         if ((assume_unit = RS.unit ()) != "")
01633         {
01634           try {
01635             intermediate = unit::Reverse<SU>::VAL
01636                (unit::standard<UL>::VAL (intermediate, assume_unit));
01637               }
01638 
01639           catch (unit::UnitMismatch) {throw InputError ();}
01640           catch (unit::UnitSyntaxError) {throw InputError ();}
01641 
01642         }
01643       }
01644 
01645 
01646 
01647 
01648 
01649       else
01650       {
01651         end = unit.find_first_of (" \0", start);
01652         try {
01653             intermediate = unit::Reverse<SU>::VAL
01654                (unit::standard<UL>::VAL (intermediate, unit.substr (start)));
01655             }
01656         catch (unit::UnitMismatch) {throw InputError ();}
01657         catch (unit::UnitSyntaxError) {throw InputError ();}
01658       }
01659 
01660       _value = intermediate;
01661 
01662     }
01663 
01665 
01669 template<template<typename, typename> class Q1, typename QT1, typename DQT1, 
01670          template<typename, typename> class Q2, typename QT2, typename DQT2,
01671                                                                typename ST>
01672   struct GenerateVariable
01673                <Q1<Quantity<QT1, ST>, DQT1>, Q2<Quantity<QT2, ST>, DQT2> >
01674   {
01675      private:
01676        typedef typename QuantityTraits<QT1>::Dimension Dim1;
01677        typedef typename QuantityTraits<QT2>::Dimension Dim2;
01678 
01680        typedef typename Dim1::template Add<Dim2> AddT;
01681        typedef Quantity<GenericClass<typename AddT::Res>, ST> AddNewQ;
01682 
01684        typedef typename Dim1::template Sub<Dim2> SubT;
01685        typedef Quantity<GenericClass<typename SubT::Res>, ST> SubNewQ;
01686 
01687      public:
01689 
01691        typedef Variable<AddNewQ> Add;
01692 
01694 
01696        typedef Variable<SubNewQ> Sub;
01697   };
01698 
01700 
01703 template<template<typename, typename> class Q, 
01704                                typename QT, typename ST, typename DQT>
01705   struct GenerateVariable <Q<Quantity<QT, ST>, DQT>, Loki::NullType>
01706   {
01707      private:
01709        typedef typename QuantityTraits<QT>::Dimension::Inv InvT;
01710        typedef Quantity<GenericClass<typename InvT::Res>, ST> InvNewQ;
01711 
01712      public:
01714 
01716        typedef Variable<InvNewQ> Inv;
01717   };
01718 
01720 
01723 template<template<typename, typename> class Q, typename QT, 
01724                                    class ST, class DQT, long N, long D>
01725   struct GenerateVariable
01726     <Q<Quantity<QT, ST>, DQT>, BSUtilities::Rational<N, D> >
01727   {
01728      private:
01730        typedef typename QuantityTraits<QT>::Dimension::template
01731                                                        Mult<N, D> MultT;
01732 
01733        typedef Quantity<GenericClass<typename MultT::Res>, ST> MultNewQ;
01734 
01735      public:
01737 
01739        typedef Variable<MultNewQ> Mult;
01740   };
01741 
01743 
01750 template<template<typename, typename> class Q, typename QT, 
01751            typename ST, typename SU, typename DQT>
01752   inline typename GenerateVariable
01753     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<1, 2> >::Mult 
01754       sqrt (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity)
01755           {
01756             return typename 
01757               GenerateVariable<Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01758                 BSUtilities::Rational<1, 2> >::Mult (quantity.sqrt());
01759           }
01760 
01762 
01769 template<template<typename, typename> class Q, typename QT, 
01770                                       typename ST, typename SU, typename DQT, int I>
01771   inline typename GenerateVariable
01772     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<I, long(1)> >::Mult 
01773       pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, 
01774                                             typename Loki::Int2Type<I>)
01775           {
01776             return typename 
01777               GenerateVariable<Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01778                 BSUtilities::Rational<long(I), long(1)> >::Mult
01779                               (quantity.pow(Loki::Int2Type<I> ()));
01780           }
01781 
01783 
01791 template<template<typename, typename> class Q, typename QT, 
01792                          typename ST, typename SU, typename DQT, long N, long D>
01793   inline typename GenerateVariable
01794     <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, BSUtilities::Rational<N, D> >::Mult 
01795       pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, 
01796                                    const BSUtilities::Rational<N, D> &)
01797       { return typename 
01798           GenerateVariable <Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >,
01799                                      BSUtilities::Rational<N, D> >::Mult
01800             (quantity.pow(BSUtilities::Rational<N, D> ()));
01801           }
01802 
01804 
01809 template<template<typename, typename> class Q, typename QT, 
01810                              typename ST, typename SU, typename DQT, typename T>
01811   inline Dynamic<ST> 
01812     pow (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity, const T &exp) 
01813           {return Dynamic<ST> (quantity.pow(exp));}
01814 
01816 
01818 template<template<typename, typename> class Q, typename QT, 
01819                                           typename ST, typename SU, typename DQT>
01820   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01821     abs (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01822     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01823                               (std::abs (variable.value ()));}
01824 
01826 
01828 template<template<typename, typename> class Q, typename QT, 
01829                                          typename ST, typename SU, typename DQT>
01830   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01831     ceil (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01832     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01833                                (std::ceil (variable.value ()));}
01834 
01836 
01838 template<template<typename, typename> class Q, typename QT, 
01839                                           typename ST, typename SU, typename DQT>
01840   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01841     floor (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable)
01842     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01843                                 (std::floor (variable.value ()));}
01844 
01846 
01848 template<template<typename, typename> class Q, typename QT, 
01849                                            typename ST, typename SU, typename DQT>
01850   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01851     frexp (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable, int *exponent)
01852     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01853                         (std::frexp (variable.value (), exponent));}
01854 
01856 
01858 template<template<typename, typename> class Q, typename QT, 
01859                                           typename ST, typename SU, typename DQT>
01860   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01861     ldexp (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &variable, int exponent)
01862     {return Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01863                     (std::ldexp (variable.value (), exponent));}
01864 
01866 
01873 template<template<typename, typename> class Q1, 
01874   template<typename, typename> class Q2, typename QT, 
01875                                         typename ST, typename SU, typename DQT>
01876   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01877     fmod (const Q1<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity1,
01878                       const Q2<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity2)
01879     {return 
01880       Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01881             (std::fmod (quantity1.value (), quantity2.value ()));
01882     }
01883 
01885 
01891 template<template<typename, typename> class Q1, 
01892   template<typename, typename> class Q2, typename QT, 
01893             typename ST, typename SU, typename DQT1, class DQT2> 
01894   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> >
01895     fmod (const Q1<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> > &quantity1,
01896                       const Q2<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT2> > &quantity2)
01897   {return 
01898     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT1> >
01899       (unit::Reverse<SU>::VAL 
01900         (std::fmod (quantity1.standard_value (), quantity2.standard_value ())));
01901   }
01902 
01904 
01910 template <template<typename, typename> class Q1, typename QT1, 
01911         typename ST, typename SU1, typename DQT1, 
01912   template<typename, typename> class Q2, typename QT2, typename SU2, typename DQT2> 
01913   inline Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01914     fmod (const Q1<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > &quantity1,
01915                         const Q2<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> > &quantity2)
01916   {return Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01917     (unit::Reverse<SU1>::VAL 
01918       (std::fmod (quantity1.standard_value (), unit::Standard<typename CheckSecondDimension<
01919         Q1<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >, 
01920           Q2<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >
01921                      >::RET::SU>::VAL (quantity2.value ()))));
01922   }
01923 
01925 
01928 template<template<typename, typename> class Q, typename QT, 
01929                                        typename ST, typename SU, typename DQT> 
01930   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01931     modf (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity,
01932                        Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > *integral)
01933   {ST i_ptr; 
01934     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
01935                    new_variable (std::modf (quantity.value (), &i_ptr));
01936     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > int_quantity (i_ptr);
01937                           *integral = int_quantity; return new_variable;
01938         }
01939 
01941 
01945 template<template<typename, typename> class Q, typename QT, 
01946           typename ST, typename SU1, typename DQT1, typename SU2, typename DQT2>
01947   inline Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >
01948     modf (const Q<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> > &quantity,
01949                        Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU2, DQT2> > *integral)
01950   {ST i_ptr; 
01951     Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >
01952                    new_variable (std::modf (quantity.value (), &i_ptr));
01953     *integral = Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU2, DQT2> >
01954                    (Variable<Quantity<QT, ST>, DerivedQuantity<QT, SU1, DQT1> >(i_ptr)); 
01955     return new_variable;
01956   }
01957 
01959 
01963 template<template<typename, typename> class Q, typename QT1, 
01964                typename SU1, typename DQT1, typename QT2, typename SU2, typename DQT2, typename ST>
01965   inline Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >
01966   modf (const Q<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > &quantity,
01967                             Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> > *integral)
01968   {ST i_ptr; 
01969     typename CheckSecondDimension<Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >,
01970       Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> > >::RET
01971         new_variable (unit::Reverse<SU1>::VAL 
01972                       (std::modf (quantity.standard_value (), &i_ptr)));
01973     *integral = Variable<Quantity<QT2, ST>, DerivedQuantity<QT2, SU2, DQT2> >
01974             (Variable<Quantity<QT1, ST>, DerivedQuantity<QT1, SU1, DQT1> >(i_ptr)); 
01975   return new_variable;
01976   }
01977 
01979 
01980 
01982 
01984 
01986       struct Dummy;
01987 
01989 
02004 #define QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(function, helper) \
02005 template<typename QT, typename ST> struct helper {static ST exec (const Quantity<QT, ST> &quantity) \
02006 {return ST(std::function (quantity.value ()));}}; \
02007 template<template<typename, typename> class M, typename QT, typename ST, typename SU, typename DQT> \
02008 inline typename GenerateVariable<M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, \
02009 BSUtilities::Rational<0> >::Mult \
02010 function (const M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> > &quantity) \
02011 {return typename GenerateVariable<M<Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >, \
02012 BSUtilities::Rational<0> >::Mult (BSUtilities::IF<CheckDimensionality<Quantity<QT, ST> >::RET, \
02013 typename helper<QT, ST>::helper, Dummy>::RET::exec (quantity));}
02014 
02015 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(exp, expHelper)
02016 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(log, logHelper)
02017 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(log10, log10Helper)
02018 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(sin, sinHelper)
02019 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(cos, cosHelper)
02020 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(tan, tanHelper)
02021 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(sinh, sinhHelper)
02022 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(cosh, coshHelper)
02023 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(tanh, tanhHelper)
02024 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(asin, asinHelper)
02025 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(acos, acosHelper)
02026 QUANTITY_VARIABLE_DIMENSIONLESS_MATHFCT(atan, atanHelper)
02027 
02029 
02036 template<template<typename, typename> class M1, typename QT1, typename ST1, typename SU1, typename DQT1,
02037      template<typename, typename> class M2, typename QT2, typename ST2, typename SU2, typename DQT2>
02038   inline typename GenerateVariable<M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> >, 
02039     M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > >::Sub 
02040     atan2 (const M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> > &quantity,
02041                            const M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > &quantity2)
02042       {return typename GenerateVariable<typename BSUtilities::IF<SameDimensioned<Quantity<QT1, ST1>,
02043          Quantity<QT2, ST2> >::EQ, M1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SU1, DQT1> >, 
02044            DimensionError<true> >::RET, M2<Quantity<QT2, ST2>, DerivedQuantity<QT1, SU2, DQT2> > >::Sub
02045           (std::atan2 (quantity.standard_value (), quantity2.standard_value ()));}
02046 
02048 
02050 
02051 } 
02052 
02053 #endif