00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _Generic_h
00025 #define _Generic_h
00026
00027
00028 #include "Quantity/Unit.h"
00029 #include "Quantity/Quantity.h"
00030
00031
00032 #include "loki/Typelist.h"
00033
00034
00035 #include <string>
00036
00037 namespace quantity {
00038
00039
00040
00042
00047 template<typename DIM> struct GenericClass;
00048
00050 template<typename DIM> struct DerivedGenericClass;
00051
00052 }
00053
00054 namespace unit {
00055
00057
00060 template<typename DIM> struct GenericUnitBase;
00061
00063 class GenericUnit;
00064
00066
00067
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 }
00117
00118 namespace quantity {
00119
00121
00122
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 }
00313
00314 #endif