00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _Unit_h
00027 #define _Unit_h
00028
00029 #include <vector>
00030 #include <string>
00031
00032 #include "Quantity/Prefix.h"
00033
00034 #include "NullType.h"
00035 #include "EmptyType.h"
00036 #include "TypeManip.h"
00037 #include "Typelist.h"
00038
00039 #include "BSUtilities.h"
00040 #include "TemplateTools.h"
00041 #include "Conversion.h"
00042
00043 #include "xmlwriter.h"
00044
00045 #include <tinyxml/tinyxml.h>
00046
00048
00056 namespace unit {
00057
00059
00060
00061
00062
00064
00066
00069 template<bool>
00070 struct UnitError;
00071
00073
00075 template<class BU, class TU>
00076 struct CheckUnit
00077 {
00079
00089 typedef typename
00090 BSUtilities::IF<Loki::SuperSubclass<BU, TU>::value,
00091 TU, UnitError<true> >::RET Check;
00092 };
00093
00095
00101 template<class BU, class TUL>
00102 struct CheckUnits
00103 {
00104 private:
00105 typedef
00106 typename CheckUnit<BU, typename TUL::Head>::Check UnitCheck;
00107
00108 public:
00109 typedef typename CheckUnits<BU, typename TUL::Tail>::Check Check;
00110 };
00111
00113
00116 template<class BU>
00117 struct CheckUnits<BU, Loki::NullType>
00118 {
00120 typedef Loki::EmptyType Check;
00121 };
00122
00124
00125
00126
00128
00130 class Units
00131 {
00132 public:
00134
00137 static const std::string Version (void)
00138 {static const std::string v_string ("Units version 1.2");
00139 return v_string;}
00140
00142
00145 static const std::string version (void) {return Version ();}
00146
00148
00150 static const std::string TAG;
00151
00153
00155 static const std::string TYPETAG;
00156
00157 };
00158
00160
00164 template<class BT> class Unit : public Units
00165 {
00166 public:
00168
00170 virtual const std::string name (void) const = 0;
00171
00173
00175 virtual const std::string symbol (void) const = 0;
00176
00178
00180 virtual const bool isSI (void) const = 0;
00181
00182 };
00183
00185
00186
00187
00189
00191
00195 template<class BT, class U>
00196 class NonPrefixable : public Unit<BT>
00197 {
00198 private:
00200 static const bool SI;
00201
00203
00205 static const std::string Namestring;
00206
00208
00210 static const std::string Symbolstring;
00211
00212 public:
00214
00218 static const bool IsSI (void) {return SI;}
00219
00221
00223 const bool isSI (void) const {return IsSI ();}
00224
00226
00227
00228
00229
00230
00231
00232 static const std::string Name (void) {return Namestring;}
00233
00235
00238 const std::string name (void) const {return Name ();}
00239
00241
00242
00243
00244
00245
00246
00247 static const std::string Symbol (void) {return Symbolstring;}
00248
00250
00253 const std::string symbol (void) const {return Symbol ();}
00254
00255 };
00256
00258
00259
00260
00262
00263
00264 template<class BT, class U> class Prefixable;
00265
00267
00270 template<class BP, class UP = No> class Prefixed;
00271
00273
00278 template<class BT, class U, class UP>
00279 class Prefixed<Prefixable<BT, U>, UP> : public Prefixable<BT, U>
00280 {
00281 public:
00283
00284
00285
00286
00287
00288
00289
00290
00291 static const std::string Name (void) {return UP::Name + Basename;}
00292
00294
00297 const std::string name (void) const {return Name ();}
00298
00300
00301
00302
00303
00304
00305
00306
00307
00308 static const std::string Symbol (void)
00309 {return UP::Symbol + Basesymbol;}
00310
00312
00315 const std::string symbol (void) const {return Symbol ();}
00316
00317 };
00318
00320
00327 template<class BT, class U> class Prefixable : public Unit<BT>
00328 {
00329 private:
00331
00333 static const bool SI;
00334
00335 public:
00337 typedef Loki::Typelist<Prefixed<Prefixable<BT, U>, Yotta>,
00338 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zetta>,
00339 Loki::Typelist<Prefixed<Prefixable<BT, U>, Exa>,
00340 Loki::Typelist<Prefixed<Prefixable<BT, U>, Peta>,
00341 Loki::Typelist<Prefixed<Prefixable<BT, U>, Tera>,
00342 Loki::Typelist<Prefixed<Prefixable<BT, U>, Giga>,
00343 Loki::Typelist<Prefixed<Prefixable<BT, U>, Mega>,
00344 Loki::Typelist<Prefixed<Prefixable<BT, U>, Kilo>,
00345 Loki::Typelist<Prefixed<Prefixable<BT, U>, Hecto>,
00346 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deca>,
00347 Loki::Typelist<Prefixed<Prefixable<BT, U>, No>,
00348 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deci>,
00349 Loki::Typelist<Prefixed<Prefixable<BT, U>, Centi>,
00350 Loki::Typelist<Prefixed<Prefixable<BT, U>, Milli>,
00351 Loki::Typelist<Prefixed<Prefixable<BT, U>, Micro>,
00352 Loki::Typelist<Prefixed<Prefixable<BT, U>, Nano>,
00353 Loki::Typelist<Prefixed<Prefixable<BT, U>, Pico>,
00354 Loki::Typelist<Prefixed<Prefixable<BT, U>, Femto>,
00355 Loki::Typelist<Prefixed<Prefixable<BT, U>, Atto>,
00356 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zepto>,
00357 Loki::Typelist<Prefixed<Prefixable<BT, U>, Yocto>,
00358 Loki::NullType> > > > > > > > > > > > > > > > > > > > >
00359 Units;
00360
00362
00366 static const bool IsSI (void) {return SI;}
00367
00369
00371 const bool isSI (void) const {return IsSI ();}
00372
00373 protected:
00375
00376
00377
00378 static const std::string Basename;
00379
00381
00382
00383
00384 static const std::string Basesymbol;
00385
00386 };
00387
00389
00390
00391
00392
00394
00396 template<class BT, class CEL> class ComposeBase;
00397
00399
00402 template<class BC, class CUL> class Composed;
00403
00405
00410 template<class BT, class UL, class R> struct ComposeElement;
00411
00413
00419 template<class BT, class BT1, class U, class UTail, long N, long D>
00420 struct
00421 ComposeElement<BT, Loki::Typelist<NonPrefixable<BT1, U>, UTail>,
00422 BSUtilities::Rational<N, D> >
00423 {
00424 private:
00425 typedef typename CheckUnits<Unit<BT1>,
00426 Loki::Typelist<NonPrefixable<BT1, U>, UTail> >::Check Check;
00427
00428 public:
00429 typedef Loki::Typelist<NonPrefixable<BT1, U>, UTail> Units;
00430 typedef BSUtilities::Rational<N, D> Power;
00431 };
00432
00434
00440 template<class BT, class BT1, class U, class UP, class UTail,
00441 long N, long D>
00442 struct ComposeElement<BT,
00443 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>,
00444 BSUtilities::Rational<N, D> >
00445 {
00446 private:
00447 typedef typename CheckUnits<Unit<BT1>,
00448 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail> >
00449 ::Check Check;
00450
00451 public:
00452 typedef Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>
00453 Units;
00454 typedef BSUtilities::Rational<N, D> Power;
00455 };
00456
00458
00464 template<class BT, class BT1, class CEL, class CUL,
00465 class UTail, long N, long D>
00466 struct ComposeElement<BT,
00467 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail>,
00468 BSUtilities::Rational<N, D> >
00469 {
00470 private:
00471 typedef typename CheckUnits<Unit<BT1>,
00472 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail> >
00473 ::Check Check;
00474
00475 public:
00476 typedef Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>,
00477 UTail> Units;
00478 typedef BSUtilities::Rational<N, D> Power;
00479 };
00480
00482
00484 template<class UL> struct ComposedSI;
00485
00487
00491 template<class U, class UTail>
00492 struct ComposedSI<Loki::Typelist<U, UTail> >
00493 {
00498 static const bool isSI (void)
00499 {return ((U::IsSI () && ComposedSI<UTail>::isSI ()) ? 1 : 0);}
00500
00501 };
00502
00506 template<>
00507 struct ComposedSI<Loki::NullType>
00508 {
00509 static const bool isSI (void) {return true;}
00510 };
00511
00513
00516 template<class UL, class RL> struct ComposedStrings;
00517
00519
00521 template<class U, class UTail, long N, long D, class RTail>
00522 struct ComposedStrings<Loki::Typelist<U, UTail>,
00523 Loki::Typelist<BSUtilities::Rational<N, D>, RTail> >
00524 {
00525 static const std::string Name (void)
00526 {return U::Name ()
00527 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00528 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00529 + ComposedStrings<UTail, RTail>::Name ();}
00530
00531 static const std::string Symbol (void)
00532 {return U::Symbol ()
00533 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00534 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00535 + ComposedStrings<UTail, RTail>::Symbol ();}
00536 };
00537
00539
00541 template<class U, class UTail, long N, class RTail>
00542 struct ComposedStrings<Loki::Typelist<U, UTail>,
00543 Loki::Typelist<BSUtilities::Rational<N, 1L>, RTail> >
00544 {
00545 static const std::string Name (void)
00546 {return U::Name ()
00547 + "^" + BSUtilities::Conversion<long>::to_string(N)
00548 + ComposedStrings<UTail, RTail>::Name ();}
00549
00550 static const std::string Symbol (void)
00551 {return U::Symbol ()
00552 + "^" + BSUtilities::Conversion<long>::to_string(N) + " "
00553 + ComposedStrings<UTail, RTail>::Symbol ();}
00554 };
00555
00557
00559 template<class U, class UTail, class RTail>
00560 struct ComposedStrings<Loki::Typelist<U, UTail>,
00561 Loki::Typelist<BSUtilities::Rational<1L, 1L>, RTail> >
00562 {
00563 static const std::string Name (void)
00564 {return U::Name () + ComposedStrings<UTail, RTail>::Name ();}
00565
00566 static const std::string Symbol (void)
00567 {return U::Symbol () + " "
00568 + ComposedStrings<UTail, RTail>::Symbol ();}
00569 };
00570
00572
00574 template<class U, long N, long D>
00575 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00576 Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType> >
00577 {
00578 static const std::string Name (void)
00579 {return U::Name ()
00580 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00581 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00582
00583 static const std::string Symbol (void)
00584 {return U::Symbol ()
00585 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00586 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00587 };
00588
00590
00593 template<class U, long N>
00594 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00595 Loki::Typelist<BSUtilities::Rational<N>, Loki::NullType> >
00596 {
00597 static const std::string Name (void)
00598 {return U::Name ()
00599 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00600
00601 static const std::string Symbol (void)
00602 {return U::Symbol ()
00603 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00604 };
00605
00607
00616 template<class BT, class CEL, class UL>
00617 class Composed<ComposeBase<BT, CEL>, UL> : public ComposeBase<BT, CEL>
00618 {
00619 private:
00620 typedef Composed<ComposeBase<BT, CEL>, UL> Unit;
00621 typedef typename ComposeBase<BT, CEL>::Powers::Powers Powers;
00622
00623 public:
00625
00626
00627 static const bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00628
00630
00632 bool const isSI (void) const {return IsSI ();}
00633
00635
00636
00637
00638
00639
00640
00641 static const std::string Name (void)
00642 {return ComposedStrings<UL, Powers>::Name ();}
00643
00645
00648 const std::string name (void) const {return Name ();}
00649
00651
00652
00653
00654
00655
00656
00657 static const std::string Symbol (void)
00658 {return ComposedStrings<UL, Powers>::Symbol ();}
00659
00661
00664 const std::string symbol (void) const {return Symbol ();}
00665
00666 };
00667
00669
00678 template<class UL, class CUL> struct GenComposedList;
00679
00681
00687 template<class U, class UTail>
00688 struct GenComposedList<Loki::Typelist<U, UTail>, Loki::NullType>
00689 {
00690 typedef
00691 Loki::Typelist<Loki::Typelist<U, Loki::NullType>,
00692 typename GenComposedList<UTail, Loki::NullType>::List> List;
00693 };
00694
00696
00700 template<>
00701 struct GenComposedList<Loki::NullType, Loki::NullType>
00702 {
00703 typedef Loki::NullType List;
00704 };
00705
00707
00715 template<class U1, class U, class UTail, class CULTail>
00716 struct GenComposedList<U1,
00717 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00718 {
00719 typedef Loki::Typelist<Loki::Typelist<U1,
00720 Loki::Typelist<U, UTail> >,
00721 typename GenComposedList<U1, CULTail>::List> List;
00722 };
00723
00725
00727 template<class U>
00728 struct GenComposedList<U, Loki::NullType>
00729 {
00730 typedef Loki::NullType List;
00731 };
00732
00734
00740 template<class U1, class U, class UTail, class U1Tail, class CULTail>
00741 struct GenComposedList<Loki::Typelist<U1, U1Tail>,
00742 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00743 {
00744 typedef typename BSUtilities::Concatenate<typename
00745 GenComposedList<U1,
00746 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >::List,
00747 typename GenComposedList<U1Tail,
00748 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail>
00749 >::List>::Result List;
00750 };
00751
00753
00756 template<class U, class UTail, class CULTail>
00757 struct GenComposedList<Loki::NullType,
00758 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00759 {
00760 typedef Loki::NullType List;
00761 };
00762
00764
00767 template<class CEL> struct ExpandComposeElementList;
00768
00770
00775 template<class CELHead, class CELTail>
00776 struct ExpandComposeElementList<Loki::Typelist<CELHead, CELTail> >
00777 {
00778 typedef typename GenComposedList<typename CELHead::Units,
00779 typename ExpandComposeElementList<CELTail>::List>::List List;
00780 };
00781
00783
00785 template<>
00786 struct ExpandComposeElementList<Loki::NullType>
00787 {
00788 typedef Loki::NullType List;
00789 };
00790
00792
00795 template<class BC, class CUL> struct GenComposedUnits;
00796
00798
00801 template<class BT, class CEL, class CULHead, class CULTail>
00802 struct GenComposedUnits<ComposeBase<BT, CEL>,
00803 Loki::Typelist<CULHead, CULTail> >
00804 {
00805 typedef Loki::Typelist<Composed<ComposeBase<BT, CEL>, CULHead>,
00806 typename GenComposedUnits<ComposeBase<BT, CEL>,
00807 CULTail>::List> List;
00808 };
00809
00811
00814 template<class BT, class CEL>
00815 struct GenComposedUnits<ComposeBase<BT, CEL>, Loki::NullType>
00816 {
00817 typedef Loki::NullType List;
00818 };
00819
00821
00823 template<class CEL> struct GenPowers;
00824
00826
00829 template<class CELHead, class CELTail>
00830 struct GenPowers<Loki::Typelist<CELHead, CELTail> >
00831 {
00832 typedef Loki::Typelist<typename CELHead::Power,
00833 typename GenPowers<CELTail>::Powers> Powers;
00834 };
00835
00837
00841 template<class CE>
00842 struct GenPowers<Loki::Typelist<CE, Loki::NullType> >
00843 {
00844 typedef Loki::Typelist<typename CE::Power, Loki::NullType> Powers;
00845 };
00846
00847
00849
00850
00851
00852
00854
00856
00860 template<class BT, class UHead, class UTail,
00861 long N, long D, class ELTail>
00862 class ComposeBase<BT, Loki::Typelist<ComposeElement<BT,
00863 Loki::Typelist<UHead, UTail>, BSUtilities::Rational<N, D> >,
00864 ELTail> > : public Unit<BT>
00865 {
00866 private:
00867 typedef
00868 Loki::Typelist<ComposeElement<BT, Loki::Typelist<UHead, UTail>,
00869 BSUtilities::Rational<N, D> >, ELTail> ElementList;
00870
00871 public:
00872 typedef GenPowers<ElementList> Powers;
00873
00874 typedef typename
00875 GenComposedUnits<ComposeBase<BT, ElementList>, typename
00876 ExpandComposeElementList<ElementList>::List>::List Units;
00877 };
00878
00879 }
00880
00881 #endif