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 "Quantities/Quantity/Unit.h"
00029 #include "Quantities/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 static const bool Exact;
00086
00087 static const double StandardFactor;
00088
00089 public:
00090 static bool IsSI (void) {return SI;}
00091
00092 bool isSI (void) const {return IsSI ();}
00093
00094 static bool IsExact (void) {return Exact;}
00095
00096 bool isExact (void) const {return IsExact ();}
00097
00098 static double Factor (void) {return StandardFactor;}
00099
00100 static const std::string Namestring;
00101
00102 static std::string Name (void) {return Namestring;}
00103
00104 std::string name (void) const {return Name ();}
00105
00106 static const std::string Symbolstring;
00107
00108 static std::string Symbol (void) {return Symbolstring;}
00109
00110 std::string symbol (void) const {return Symbol ();}
00111
00112 };
00113
00114 template<typename DIM> const bool
00115 NonPrefixable<GenericUnitBase<DIM>, GenericUnit>::SI = false;
00116
00117 template<typename DIM> const bool
00118 NonPrefixable<GenericUnitBase<DIM>, GenericUnit>::Exact = true;
00119
00120 template<typename DIM> const double
00121 NonPrefixable<GenericUnitBase<DIM>, GenericUnit>::StandardFactor = 1.0;
00122
00123 template<typename DIM> const
00124 std::string
00125 NonPrefixable<GenericUnitBase<DIM>, GenericUnit> ::Namestring = "";
00126
00127 template<typename DIM> const
00128 std::string
00129 NonPrefixable<GenericUnitBase<DIM>, GenericUnit>
00130 ::Symbolstring = "(unknown unit)";
00131
00132 }
00133
00134 namespace quantity {
00135
00137
00138
00139
00141
00143
00144
00145
00146
00147
00148
00149
00150
00152
00153
00154
00155
00156
00158
00159
00160
00161
00162
00164 template<typename DIM>
00165 struct DerivedQuantityTraits<GenericClass<DIM>, DerivedGenericClass<DIM> >
00166 {
00167 static const bool OverwriteName = false;
00168 static const bool OverwriteSymbol = false;
00169
00170 static const std::string NameString ();
00171 static const std::string SymbolString ();
00172
00173 };
00174
00176
00178 template<typename DIM> struct QuantityTraits<GenericClass<DIM> >
00179 {
00180 typedef DIM Dimension;
00181 typedef unit::GenericUnitBase<DIM> UnitType;
00182 typedef Loki::Typelist<unit::NonPrefixable<unit::GenericUnitBase<DIM>,
00183 unit::GenericUnit>, Loki::NullType> UnitList;
00184 typedef unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit> DefaultUnit;
00185
00186 typedef DerivedGenericClass<DIM> DefaultDerivedQuantityType;
00187
00189
00191 static const std::string NameString (void) {return "";}
00192
00194
00196 static const std::string SymbolString (void) {return "";}
00197
00198 };
00199
00201
00203 template<typename DIM, typename ST> class Quantity<GenericClass<DIM>, ST>
00204 {
00205 public:
00206 typedef GenericClass<DIM> QT;
00207
00208 typedef typename QuantityTraits<GenericClass<DIM> >::Dimension Dim;
00209 typedef typename QuantityTraits<GenericClass<DIM> >::UnitType UT;
00210 typedef typename QuantityTraits<GenericClass<DIM> >::UnitList UL;
00211
00213
00215 typedef typename unit::ValidUnit<typename
00216 QuantityTraits<GenericClass<DIM> >::DefaultUnit, UL>::RET DU;
00217
00218 typedef
00219 typename
00220 QuantityTraits<GenericClass<DIM> >::DefaultDerivedQuantityType DDQ;
00221
00222 private:
00223 static const bool Dimensionless = Dim::IsDimensionless;
00224
00225 typedef Quantity<GenericClass<DIM>, ST> Q;
00226
00227 protected:
00228 std::string namestring;
00229 std::string symbolstring;
00230
00231 public:
00232 Quantity (void)
00233 : namestring (QuantityTraits<GenericClass<Dim> >::NameString ()),
00234 symbolstring (QuantityTraits<GenericClass<Dim>
00235 >::SymbolString ()) {}
00236
00237 virtual ~Quantity (void) {}
00238
00239 std::string name (void) const {return namestring;}
00240 std::string symbol (void) const {return symbolstring;}
00241
00242 void name (const std::string &name) {namestring = name;}
00243 void symbol (const std::string &symbol) {symbolstring = symbol;}
00244
00245 virtual ST standard_value (void) const = 0;
00246
00247 virtual ST value (void) const = 0;
00248
00249 static bool IsDimensionless (void) {return Dimensionless;}
00250
00251 bool isDimensionless (void) const {return IsDimensionless ();}
00252
00253 friend std::ostream & operator<<
00254 (std::ostream &os, const Quantity &quantity)
00255 {return quantity.print (os);}
00256
00257 std::ostream & print (std::ostream &os) const
00258 {
00259 std::string name ("");
00260 std::string symbol ("");
00261 std::string equal ("");
00262
00263 if (PS.name ())
00264 name = namestring + " ";
00265
00266 if (PS.symbol ())
00267 symbol = symbolstring + " ";
00268
00269 if (PS.name () || PS.symbol ())
00270 equal = "= ";
00271
00272 os << name << symbol << equal;
00273
00274 return print_value (os);
00275 }
00276
00277 virtual std::ostream & print_value (std::ostream &os) const = 0;
00278
00279 friend void operator<<
00280 (std::string &str, const Quantity &quantity) {quantity >> str;}
00281
00282 virtual void operator>> (std::string &str) const = 0;
00283
00284 operator std::string () const
00285 {std::string string; *this >> string; return string;}
00286
00287 virtual std::ostream & operator>> (std::ostream &os) const = 0;
00288
00290
00293 friend class boost::serialization::access;
00294
00295 private:
00296 template<typename Archive>
00297 void serialize (Archive &ar, const unsigned int )
00298 {
00299 ar & BOOST_SERIALIZATION_NVP(namestring);
00300 ar & BOOST_SERIALIZATION_NVP(symbolstring);
00301 }
00302
00303 };
00304
00306
00311 template<template<typename, typename> class M, typename DIM, typename ST, typename SU, typename DQT,
00312 template<typename, typename> class SM, typename SQT, typename SST, typename SSU, typename SDQT>
00313 struct convertValue<M<Quantity<GenericClass<DIM>, ST>, DerivedQuantity<GenericClass<DIM>, SU, DQT> >,
00314 SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > >
00315 {
00316 static ST exec (const typename BSUtilities::IF<SameDimensioned<M<Quantity<GenericClass<DIM>, ST>,
00317 DerivedQuantity<GenericClass<DIM>, SU, DQT> >,
00318 SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> > >::EQ,
00319 SM<Quantity<SQT, SST>, DerivedQuantity<SQT, SSU, SDQT> >, DimensionError<true> >::RET
00320 & quantity)
00321 {return unit::Reverse<SU>::VAL
00322 (unit::Standard<SSU>::VAL (quantity.value ()));}
00323 };
00324
00325 }
00326
00327 #endif