00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _Quantity_h
00025 #define _Quantity_h
00026
00027
00028 #include "Quantities/version.h"
00029 #include "Quantities/Quantity/Unit.h"
00030 #include "Quantities/Quantity/Dimension.h"
00031 #include "Quantities/Quantity/QuantityError.h"
00032
00033
00034 #include "BSUtilities/BSUtilities.h"
00035 #include "BSUtilities/TypeToName.h"
00036 #include "BSUtilities/Conversion.h"
00037
00038
00039 #include "loki/Singleton.h"
00040
00041
00042 #include <iostream>
00043 #include <string>
00044 #include <cmath>
00045 #include <typeinfo>
00046
00047
00048 #include <boost/serialization/serialization.hpp>
00049 #include <boost/serialization/nvp.hpp>
00050 #include <boost/serialization/is_abstract.hpp>
00051
00053 namespace quantity {
00054
00056
00057
00058
00060
00062
00064 template<bool>
00065 struct DimensionError;
00066
00068
00072 template<>
00073 struct DimensionError<false>
00074 {
00076
00078 static const bool RET = true;
00079 };
00080
00082
00086 template<typename Q>
00087 struct CheckDimensionality
00088 {
00089 public:
00091
00093 static const bool RET =
00094 BSUtilities::IF<Q::Dim::IsDimensionless, DimensionError<false>,
00095 DimensionError<true> >::RET::RET;
00096 };
00097
00099
00100
00101
00103
00105
00107 template<bool P> class PrintName;
00109
00111 template<bool P> class PrintSymbol;
00112
00114 class PrintStatus
00115 {
00116 private:
00118 static bool _name;
00120 static bool _symbol;
00121
00122 public:
00124
00126 bool name (void) const {return _name;}
00128
00130 bool symbol (void) const {return _symbol;}
00131
00133 template<bool P> friend class PrintName;
00134
00136 template<bool P> friend class PrintSymbol;
00137 };
00138
00140 typedef Loki::SingletonHolder<PrintStatus> PrintStatusHolder;
00141
00142 #define PS PrintStatusHolder::Instance()
00143
00145
00148 template<bool P>
00149 class PrintName
00150 {
00152
00155 void set (bool name) const {PrintStatus::_name = name;}
00156
00158
00164 friend std::ostream & operator<<
00165 (std::ostream &os, const PrintName &print)
00166 {print.set (P); return os;}
00167 };
00168
00170
00173 template<bool P>
00174 class PrintSymbol
00175 {
00177
00180 void set (bool symbol) const {PrintStatus::_symbol = symbol;}
00181
00183
00189 friend std::ostream & operator<<
00190 (std::ostream &os, const PrintSymbol &print)
00191 {print.set (P); return os;}
00192
00193 };
00194
00196
00198 template<bool P> class ReadName;
00199
00201
00203 template<bool P> class ReadSymbol;
00204
00206
00208 template<bool P> class ReadEqual;
00209
00211 class ReadStatus
00212 {
00213 private:
00215 static bool _name;
00216
00218 static bool _symbol;
00219
00221 static bool _equal;
00222
00224
00227 static std::string _unit;
00228
00229 public:
00231
00233 bool name (void) const {return _name;}
00234
00236
00238 bool symbol (void) const {return _symbol;}
00239
00241
00243 bool equal (void) const {return _equal;}
00244
00246
00248 std::string unit (void) const {return _unit;}
00249
00251 template<bool P> friend class ReadName;
00252
00254 template<bool P> friend class ReadSymbol;
00255
00257 template<bool P> friend class ReadEqual;
00258
00260 template<class U> friend class ReadUnit;
00261 };
00262
00264 typedef Loki::SingletonHolder<ReadStatus> ReadStatusHolder;
00265
00266 #define RS ReadStatusHolder::Instance()
00267
00269
00272 template<bool P>
00273 class ReadName
00274 {
00276
00279 void set (bool name) const {ReadStatus::_name = name;}
00280
00282
00288 friend std::istream & operator>>
00289 (std::istream &is, const ReadName &read)
00290 {read.set (P); return is;}
00291 };
00292
00294
00297 template<bool P>
00298 class ReadSymbol
00299 {
00301
00304 void set (bool symbol) const {ReadStatus::_symbol = symbol;}
00305
00307
00313 friend std::istream & operator>>
00314 (std::istream &is, const ReadSymbol &read)
00315 {read.set (P); return is;}
00316
00317 };
00318
00320
00323 template<bool P>
00324 class ReadEqual
00325 {
00327
00330 void set (bool equal) const {ReadStatus::_equal = equal;}
00331
00333
00339 friend std::istream & operator>>
00340 (std::istream &is, const ReadEqual &read)
00341 {read.set (P); return is;}
00342
00343 };
00344
00346
00348 template<typename U>
00349 class ReadUnit
00350 {
00352
00355 void set (std::string unit) const {ReadStatus::_unit = unit;}
00356
00358
00365 friend std::istream & operator>>
00366 (std::istream &is, const ReadUnit<U> &unit)
00367 {unit.set (U::Symbol ()); return is;}
00368
00369 };
00370
00371 typedef Loki::NullType NoUnit;
00372
00374
00376 template<>
00377 class ReadUnit<NoUnit>
00378 {
00380
00383 void set (std::string unit) const {ReadStatus::_unit = unit;}
00384
00386
00392 friend std::istream & operator>>
00393 (std::istream &is, const ReadUnit<NoUnit> &unit)
00394 {unit.set (""); return is;}
00395
00396 };
00397
00399
00400
00401
00403
00405
00427 template<typename T> struct QuantityTraits;
00428
00430
00431
00432
00434
00436
00449 template<typename T, typename ST = double> class Quantity
00450 {
00451 public:
00453 typedef T QT;
00454
00456 typedef typename QuantityTraits<QT>::Dimension Dim;
00457
00459 typedef typename QuantityTraits<QT>::UnitType UT;
00460
00462 typedef typename QuantityTraits<QT>::UnitList UL;
00463
00465
00467 typedef typename unit::ValidUnit<typename
00468 QuantityTraits<QT>::DefaultUnit, UL>::RET DU;
00469
00471 typedef typename QuantityTraits<QT>::DefaultDerivedQuantityType DDQ;
00472
00473 private:
00475 static const bool Dimensionless = Dim::IsDimensionless;
00476
00478 typedef Quantity<T, ST> Q;
00479
00480 protected:
00482
00485 std::string namestring;
00487
00490 std::string symbolstring;
00491
00492 public:
00494 Quantity (void) {}
00495
00497
00500 virtual ~Quantity (void) {}
00501
00503
00505 virtual void name (const std::string &name) {namestring = name;}
00506
00508
00510 virtual void symbol (const std::string &symbol)
00511 {symbolstring = symbol;}
00512
00514
00516 virtual std::string name (void) const {return namestring;}
00517
00519
00521 virtual std::string symbol (void) const {return symbolstring;}
00522
00524
00526 virtual ST standard_value (void) const = 0;
00527
00529
00531 virtual ST value (void) const = 0;
00532
00534
00536 static bool IsDimensionless (void) {return Dimensionless;}
00537
00539
00541 bool isDimensionless (void) const {return IsDimensionless ();}
00542
00544
00546 virtual std::string unitsymbol (void) const = 0;
00547
00549
00551 virtual std::string unitname (void) const = 0;
00552
00554
00559 friend std::ostream & operator<<
00560 (std::ostream &os, const Quantity &quantity)
00561 {return quantity.print (os);}
00562
00564
00578 std::ostream & print (std::ostream &os) const
00579 {
00580 std::string nameFragment ("");
00581 std::string symbolFragment ("");
00582 std::string equal ("");
00583
00584 if (PS.name ())
00585 nameFragment = name () + " ";
00586
00587 if (PS.symbol ())
00588 symbolFragment = symbol () + " ";
00589
00590 if (PS.name () || PS.symbol ())
00591 equal = "= ";
00592
00593 os << nameFragment << symbolFragment << equal;
00594
00595 return print_value (os);
00596 }
00597
00599
00602 virtual std::ostream & print_value (std::ostream &os) const = 0;
00603
00605 friend void operator<<
00606 (std::string &str, const Quantity &quantity) {quantity >> str;}
00607
00609 virtual void operator>> (std::string &str) const = 0;
00610
00612
00615 operator std::string () const
00616 {std::string string; *this >> string; return string;}
00617
00619
00622 virtual std::ostream & operator>> (std::ostream &os) const = 0;
00623
00625
00627
00629 friend class boost::serialization::access;
00630
00632
00634 private:
00635 template<typename Archive>
00636 void serialize (Archive &ar, const unsigned int )
00637 {
00638 ar & BOOST_SERIALIZATION_NVP(namestring);
00639 ar & BOOST_SERIALIZATION_NVP(symbolstring);
00640 }
00641
00642 };
00643
00645
00646
00648
00650
00652 template<typename Q1, typename Q2> struct SameDimensioned;
00653
00655
00657 template<typename QT1, typename ST1, typename QT2, typename ST2>
00658 struct SameDimensioned<Quantity<QT1, ST1>, Quantity<QT2, ST2> >
00659 {
00660 enum {EQ = QuantityTraits<QT1>::Dimension::template Equal<
00661 typename QuantityTraits<QT2>::Dimension>::EQ};
00662 };
00663
00665
00666
00668
00670
00672
00674
00700 template<typename Q, typename DQ> struct DerivedQuantityTraits;
00701
00703
00705
00706 template<typename QT, typename SU
00707 = typename QuantityTraits<QT>::DefaultUnit, typename DQT
00708 = typename QuantityTraits<QT>::DefaultDerivedQuantityType>
00709 struct DerivedQuantity
00710 {
00711 static const bool OverwriteName
00712 = DerivedQuantityTraits<QT, DQT>::OverwriteName;
00713 static const bool OverwriteSymbol
00714 = DerivedQuantityTraits<QT, DQT>::OverwriteSymbol;
00715 };
00716
00718
00719
00720
00722
00724
00728 template<typename Q1, typename Q2> struct convertValue;
00729
00730 }
00731
00732 #endif