Generic.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 _Generic_h
00025 #define _Generic_h
00026 
00027 // Quantity includes
00028 #include "Quantity/Unit.h"
00029 #include "Quantity/Quantity.h"
00030 
00031 // Loki includes
00032 #include "loki/Typelist.h"
00033 
00034 // STL includes
00035 #include <string>
00036 
00037 namespace quantity {
00038 
00039 /* the Generic quantity */
00040 
00042 
00047 template<typename DIM> struct GenericClass;
00048 
00050 template<typename DIM> struct DerivedGenericClass;
00051 
00052 } // end namespace quantity
00053 
00054 namespace unit {
00055 
00057 
00060 template<typename DIM> struct GenericUnitBase;
00061 
00063 class GenericUnit;
00064 
00066 //
00067 //  the Generic Unit
00068 //
00070 
00072 
00078 template<typename DIM> 
00079   class NonPrefixable<GenericUnitBase<DIM>, GenericUnit> 
00080                            : public Unit<GenericUnitBase<DIM> >
00081   {
00082     private:
00083       static const bool SI;
00084 
00085    public:
00086       static bool IsSI (void) {return SI;}
00087 
00088       bool isSI (void) const {return IsSI ();}
00089 
00090       static const std::string Namestring;
00091 
00092       static std::string Name (void) {return Namestring;}
00093 
00094       std::string name (void) const {return Name ();}
00095 
00096       static const std::string Symbolstring;
00097 
00098       static std::string Symbol (void) {return Symbolstring;}
00099 
00100       std::string symbol (void) const {return Symbol ();}
00101 
00102   };
00103 
00104 template<typename DIM> const bool 
00105   NonPrefixable<GenericUnitBase<DIM>, GenericUnit>::SI = false;
00106 
00107 template<typename DIM> const 
00108   std::string 
00109     NonPrefixable<GenericUnitBase<DIM>, GenericUnit> ::Namestring = "";
00110 
00111 template<typename DIM> const 
00112   std::string 
00113     NonPrefixable<GenericUnitBase<DIM>, GenericUnit>
00114                                       ::Symbolstring = "(unknown unit)";
00115 
00116 } // end namespace unit
00117 
00118 namespace quantity {
00119 
00121 //
00122 //  the Generic Quantity
00123 // 
00125 
00127 template<typename DIM, typename ST>
00128   struct Standard<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00129                                                  unit::GenericUnit>, ST>
00130   {
00131     static const ST ratio;
00132     static const bool exact;
00133   };
00134 
00136 template<typename DIM, typename ST>
00137   const ST
00138     Standard<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00139                                unit::GenericUnit>, ST>::ratio = ST(1.0);
00140 
00142 template<typename DIM, typename ST>
00143   const bool
00144     Standard<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00145                                   unit::GenericUnit>, ST>::exact = true;
00146 
00148 template<typename DIM>
00149   struct DerivedQuantityTraits<GenericClass<DIM>, DerivedGenericClass<DIM> >
00150   {
00151     typedef unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit> StorageUnit;
00152 
00153     static const bool OverwriteName = false;
00154     static const bool OverwriteSymbol = false;
00155 
00156     static const std::string NameString;
00157     static const std::string SymbolString;
00158 
00159   };
00160 
00162 
00164 template<typename DIM> struct QuantityTraits<GenericClass<DIM> > 
00165   {
00166     typedef DIM Dimension;
00167     typedef unit::GenericUnitBase<DIM> UnitType;
00168     typedef Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>, 
00169                                    unit::GenericUnit>, Loki::NullType> UnitList;
00170     typedef unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit> DefaultUnit;
00171 
00172     typedef DerivedGenericClass<DIM> DefaultDerivedQuantityType;
00173 
00174     static const std::string NameString;
00175     static const std::string SymbolString;
00176   };
00177 
00178 template<typename DIM> const std::string QuantityTraits<GenericClass<DIM> >::NameString = "";
00179 template<typename DIM> const std::string QuantityTraits<GenericClass<DIM> >::SymbolString = "";
00180 
00182 
00184 template<typename DIM, typename ST>
00185   class Quantity<GenericClass<DIM>, ST> : public Quantities
00186   {
00187     public:
00188       typedef GenericClass<DIM> QuantityType;
00189 
00190       typedef typename QuantityTraits<GenericClass<DIM> >::Dimension Dim;
00191       typedef typename QuantityTraits<GenericClass<DIM> >::UnitType UT;
00192       typedef typename QuantityTraits<GenericClass<DIM> >::UnitList UL;
00193       typedef typename QuantityTraits<GenericClass<DIM> >::DefaultUnit DU;
00194       typedef typename QuantityTraits<GenericClass<DIM> >::DefaultDerivedQuantityType DDQ;
00195 
00196     private:
00197       static const bool Dimensionless = Dim::IsDimensionless;
00198 
00199       typedef Quantity<GenericClass<DIM>, ST> Q;
00200 
00201     protected:
00202       std::string namestring;
00203       std::string symbolstring;
00204 
00205       unit::Unit<GenericClass<Dim> > * findBySymbol (const std::string &unitsymbol)
00206          {return UnitPointerBySymbol<UT, UL>::result (unitsymbol);}
00207 
00208      template<typename U>
00209        static ST standard (const ST value, const U&)
00210          {return Standardize<typename CheckAgainstAllUnits<U, UL>::RET, ST> (value);}
00211 
00212      template<typename U>
00213        static ST reverse (const ST value, const U& unit)
00214          {return Reverse<typename CheckAgainstAllUnits<U, UL>::RET, ST> (value);}
00215 
00216     public:
00217       Quantity (void) 
00218         : namestring (QuantityTraits<GenericClass<Dim> >::NameString), 
00219           symbolstring (QuantityTraits<GenericClass<Dim> >::SymbolString) 
00220                                                                               {}
00221 
00222       virtual ~Quantity (void) {}
00223 
00224       typedef AllUnitsTemplate<GenericClass<Dim>, UL> AllUnits;
00225 
00226       typedef DefaultUnitTemplate<GenericClass<Dim>, DU> DefaultUnit;
00227 
00228       std::string name (void) const {return namestring;}
00229       std::string symbol (void) const {return symbolstring;}
00230 
00231       void name (const std::string &name) {namestring = name;}
00232       void symbol (const std::string &symbol) {symbolstring = symbol;}
00233 
00234       virtual ST standard_value (void) const = 0;
00235 
00236       virtual ST value (void) const = 0;
00237 
00238       static bool IsDimensionless (void) {return Dimensionless;}
00239 
00240       bool isDimensionless (void) const {return IsDimensionless ();}
00241 
00242       friend std::ostream & operator<< 
00243                             (std::ostream &os, const Quantity &quantity)
00244              {return quantity.print (os);}
00245 
00246       std::ostream & print (std::ostream &os) const
00247         {
00248           std::string name (""); 
00249           std::string symbol ("");
00250           std::string equal ("");
00251 
00252           if (PS.name ())
00253             name = namestring + " ";
00254 
00255           if (PS.symbol ())
00256             symbol = symbolstring + " ";
00257 
00258           if (PS.name () || PS.symbol ())
00259             equal = "= ";
00260 
00261           os << name << symbol << equal;
00262 
00263           return print_value (os);
00264         }
00265 
00266       virtual std::ostream & print_value (std::ostream &os) const = 0;
00267 
00268       friend void operator<< 
00269         (std::string &str, const Quantity &quantity) {quantity >> str;}
00270 
00271       virtual void operator>> (std::string &str) const = 0;
00272 
00273       operator std::string () const 
00274         {std::string string; *this >> string; return string;}
00275 
00276       virtual std::ostream & operator>> (std::ostream &os) const = 0;
00277 
00279 
00282       friend class boost::serialization::access;
00283 
00284   private:
00285       template<typename Archive>
00286         void serialize (Archive &ar, const unsigned int )
00287         {
00288           ar & BOOST_SERIALIZATION_NVP(namestring);
00289           ar & BOOST_SERIALIZATION_NVP(symbolstring);
00290         }
00291 
00292   };
00293 
00295 
00299 template<template<typename, typename> class M, typename DIM, typename ST, typename SU, typename DQT,
00300      template<typename, typename> class SM, typename SQT, typename SST, typename SSU, typename SDQT>
00301   struct convertValue<M<Quantity<GenericClass<DIM>, ST>, DerivedQuantity<GenericClass<DIM>, SU, DQT> >, 
00302                      SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > >
00303   {
00304     static ST exec (const typename BSUtilities::IF<SameDimensioned<M<Quantity<GenericClass<DIM>, ST>, 
00305       DerivedQuantity<GenericClass<DIM>, SU, DQT> >,
00306         SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > >::EQ, 
00307           SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> >, DimensionError<true> >::RET 
00308                                                                                     & quantity)
00309       {return Reverse<SU, ST>::VAL (Standardize<SSU, SST>::VAL (quantity.value ()));}
00310   };
00311 
00312 } // end namespace quantity
00313 
00314 #endif /* _Generic_h */

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