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 virtual ~Unit () {}
00183
00184 };
00185
00187
00188
00189
00191
00193
00197 template<class BT, class U>
00198 class NonPrefixable : public Unit<BT>
00199 {
00200 private:
00202 static const bool SI;
00203
00205
00207 static const std::string Namestring;
00208
00210
00212 static const std::string Symbolstring;
00213
00214 public:
00216
00220 static const bool IsSI (void) {return SI;}
00221
00223
00225 const bool isSI (void) const {return IsSI ();}
00226
00228
00229
00230
00231
00232
00233
00234 static const std::string Name (void) {return Namestring;}
00235
00237
00240 const std::string name (void) const {return Name ();}
00241
00243
00244
00245
00246
00247
00248
00249 static const std::string Symbol (void) {return Symbolstring;}
00250
00252
00255 const std::string symbol (void) const {return Symbol ();}
00256
00257 };
00258
00260
00261
00262
00264
00265
00266 template<class BT, class U> class Prefixable;
00267
00269
00272 template<class BP, class UP = No> class Prefixed;
00273
00275
00280 template<class BT, class U, class UP>
00281 class Prefixed<Prefixable<BT, U>, UP> : public Prefixable<BT, U>
00282 {
00283 public:
00285
00286
00287
00288
00289
00290
00291
00292
00293 static const std::string Name (void)
00294 {return UP::Name + Prefixable<BT, U>::Basename;}
00295
00297
00300 const std::string name (void) const {return Name ();}
00301
00303
00304
00305
00306
00307
00308
00309
00310
00311 static const std::string Symbol (void)
00312 {return UP::Symbol + Prefixable<BT, U>::Basesymbol;}
00313
00315
00318 const std::string symbol (void) const {return Symbol ();}
00319
00320 };
00321
00323
00330 template<class BT, class U> class Prefixable : public Unit<BT>
00331 {
00332 private:
00334
00336 static const bool SI;
00337
00338 public:
00340 typedef Loki::Typelist<Prefixed<Prefixable<BT, U>, Yotta>,
00341 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zetta>,
00342 Loki::Typelist<Prefixed<Prefixable<BT, U>, Exa>,
00343 Loki::Typelist<Prefixed<Prefixable<BT, U>, Peta>,
00344 Loki::Typelist<Prefixed<Prefixable<BT, U>, Tera>,
00345 Loki::Typelist<Prefixed<Prefixable<BT, U>, Giga>,
00346 Loki::Typelist<Prefixed<Prefixable<BT, U>, Mega>,
00347 Loki::Typelist<Prefixed<Prefixable<BT, U>, Kilo>,
00348 Loki::Typelist<Prefixed<Prefixable<BT, U>, Hecto>,
00349 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deca>,
00350 Loki::Typelist<Prefixed<Prefixable<BT, U>, No>,
00351 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deci>,
00352 Loki::Typelist<Prefixed<Prefixable<BT, U>, Centi>,
00353 Loki::Typelist<Prefixed<Prefixable<BT, U>, Milli>,
00354 Loki::Typelist<Prefixed<Prefixable<BT, U>, Micro>,
00355 Loki::Typelist<Prefixed<Prefixable<BT, U>, Nano>,
00356 Loki::Typelist<Prefixed<Prefixable<BT, U>, Pico>,
00357 Loki::Typelist<Prefixed<Prefixable<BT, U>, Femto>,
00358 Loki::Typelist<Prefixed<Prefixable<BT, U>, Atto>,
00359 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zepto>,
00360 Loki::Typelist<Prefixed<Prefixable<BT, U>, Yocto>,
00361 Loki::NullType> > > > > > > > > > > > > > > > > > > > >
00362 Units;
00363
00365
00369 static const bool IsSI (void) {return SI;}
00370
00372
00374 const bool isSI (void) const {return IsSI ();}
00375
00376 protected:
00378
00379
00380
00381 static const std::string Basename;
00382
00384
00385
00386
00387 static const std::string Basesymbol;
00388
00389 };
00390
00392
00393
00394
00395
00397
00399 template<class BT, class CEL> class ComposeBase;
00400
00402
00405 template<class BC, class CUL> class Composed;
00406
00408
00413 template<class BT, class UL, class R> struct ComposeElement;
00414
00416
00422 template<class BT, class BT1, class U, class UTail, long N, long D>
00423 struct
00424 ComposeElement<BT, Loki::Typelist<NonPrefixable<BT1, U>, UTail>,
00425 BSUtilities::Rational<N, D> >
00426 {
00427 private:
00428 typedef typename CheckUnits<Unit<BT1>,
00429 Loki::Typelist<NonPrefixable<BT1, U>, UTail> >::Check Check;
00430
00431 public:
00432 typedef Loki::Typelist<NonPrefixable<BT1, U>, UTail> Units;
00433 typedef BSUtilities::Rational<N, D> Power;
00434 };
00435
00437
00443 template<class BT, class BT1, class U, class UP, class UTail,
00444 long N, long D>
00445 struct ComposeElement<BT,
00446 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>,
00447 BSUtilities::Rational<N, D> >
00448 {
00449 private:
00450 typedef typename CheckUnits<Unit<BT1>,
00451 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail> >
00452 ::Check Check;
00453
00454 public:
00455 typedef Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>
00456 Units;
00457 typedef BSUtilities::Rational<N, D> Power;
00458 };
00459
00461
00467 template<class BT, class BT1, class CEL, class CUL,
00468 class UTail, long N, long D>
00469 struct ComposeElement<BT,
00470 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail>,
00471 BSUtilities::Rational<N, D> >
00472 {
00473 private:
00474 typedef typename CheckUnits<Unit<BT1>,
00475 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail> >
00476 ::Check Check;
00477
00478 public:
00479 typedef Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>,
00480 UTail> Units;
00481 typedef BSUtilities::Rational<N, D> Power;
00482 };
00483
00485
00487 template<class UL> struct ComposedSI;
00488
00490
00494 template<class U, class UTail>
00495 struct ComposedSI<Loki::Typelist<U, UTail> >
00496 {
00501 static const bool isSI (void)
00502 {return ((U::IsSI () && ComposedSI<UTail>::isSI ()) ? 1 : 0);}
00503
00504 };
00505
00509 template<>
00510 struct ComposedSI<Loki::NullType>
00511 {
00512 static const bool isSI (void) {return true;}
00513 };
00514
00516
00519 template<class UL, class RL> struct ComposedStrings;
00520
00522
00524 template<class U, class UTail, long N, long D, class RTail>
00525 struct ComposedStrings<Loki::Typelist<U, UTail>,
00526 Loki::Typelist<BSUtilities::Rational<N, D>, RTail> >
00527 {
00528 static const std::string Name (void)
00529 {return U::Name ()
00530 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00531 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00532 + ComposedStrings<UTail, RTail>::Name ();}
00533
00534 static const std::string Symbol (void)
00535 {return U::Symbol ()
00536 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00537 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00538 + ComposedStrings<UTail, RTail>::Symbol ();}
00539 };
00540
00542
00544 template<class U, class UTail, long N, class RTail>
00545 struct ComposedStrings<Loki::Typelist<U, UTail>,
00546 Loki::Typelist<BSUtilities::Rational<N, 1L>, RTail> >
00547 {
00548 static const std::string Name (void)
00549 {return U::Name ()
00550 + "^" + BSUtilities::Conversion<long>::to_string(N)
00551 + ComposedStrings<UTail, RTail>::Name ();}
00552
00553 static const std::string Symbol (void)
00554 {return U::Symbol ()
00555 + "^" + BSUtilities::Conversion<long>::to_string(N) + " "
00556 + ComposedStrings<UTail, RTail>::Symbol ();}
00557 };
00558
00560
00562 template<class U, class UTail, class RTail>
00563 struct ComposedStrings<Loki::Typelist<U, UTail>,
00564 Loki::Typelist<BSUtilities::Rational<1L, 1L>, RTail> >
00565 {
00566 static const std::string Name (void)
00567 {return U::Name () + ComposedStrings<UTail, RTail>::Name ();}
00568
00569 static const std::string Symbol (void)
00570 {return U::Symbol () + " "
00571 + ComposedStrings<UTail, RTail>::Symbol ();}
00572 };
00573
00575
00577 template<class U, long N, long D>
00578 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00579 Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType> >
00580 {
00581 static const std::string Name (void)
00582 {return U::Name ()
00583 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00584 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00585
00586 static const std::string Symbol (void)
00587 {return U::Symbol ()
00588 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00589 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00590 };
00591
00593
00596 template<class U, long N>
00597 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00598 Loki::Typelist<BSUtilities::Rational<N>, Loki::NullType> >
00599 {
00600 static const std::string Name (void)
00601 {return U::Name ()
00602 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00603
00604 static const std::string Symbol (void)
00605 {return U::Symbol ()
00606 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00607 };
00608
00610
00619 template<class BT, class CEL, class UL>
00620 class Composed<ComposeBase<BT, CEL>, UL> : public ComposeBase<BT, CEL>
00621 {
00622 private:
00623 typedef Composed<ComposeBase<BT, CEL>, UL> Unit;
00624 typedef typename ComposeBase<BT, CEL>::Powers::Powers Powers;
00625
00626 public:
00628
00629
00630 static const bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00631
00633
00635 bool const isSI (void) const {return IsSI ();}
00636
00638
00639
00640
00641
00642
00643
00644 static const std::string Name (void)
00645 {return ComposedStrings<UL, Powers>::Name ();}
00646
00648
00651 const std::string name (void) const {return Name ();}
00652
00654
00655
00656
00657
00658
00659
00660 static const std::string Symbol (void)
00661 {return ComposedStrings<UL, Powers>::Symbol ();}
00662
00664
00667 const std::string symbol (void) const {return Symbol ();}
00668
00669 };
00670
00672
00681 template<class UL, class CUL> struct GenComposedList;
00682
00684
00690 template<class U, class UTail>
00691 struct GenComposedList<Loki::Typelist<U, UTail>, Loki::NullType>
00692 {
00693 typedef
00694 Loki::Typelist<Loki::Typelist<U, Loki::NullType>,
00695 typename GenComposedList<UTail, Loki::NullType>::List> List;
00696 };
00697
00699
00703 template<>
00704 struct GenComposedList<Loki::NullType, Loki::NullType>
00705 {
00706 typedef Loki::NullType List;
00707 };
00708
00710
00718 template<class U1, class U, class UTail, class CULTail>
00719 struct GenComposedList<U1,
00720 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00721 {
00722 typedef Loki::Typelist<Loki::Typelist<U1,
00723 Loki::Typelist<U, UTail> >,
00724 typename GenComposedList<U1, CULTail>::List> List;
00725 };
00726
00728
00730 template<class U>
00731 struct GenComposedList<U, Loki::NullType>
00732 {
00733 typedef Loki::NullType List;
00734 };
00735
00737
00743 template<class U1, class U, class UTail, class U1Tail, class CULTail>
00744 struct GenComposedList<Loki::Typelist<U1, U1Tail>,
00745 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00746 {
00747 typedef typename BSUtilities::Concatenate<typename
00748 GenComposedList<U1,
00749 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >::List,
00750 typename GenComposedList<U1Tail,
00751 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail>
00752 >::List>::Result List;
00753 };
00754
00756
00759 template<class U, class UTail, class CULTail>
00760 struct GenComposedList<Loki::NullType,
00761 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00762 {
00763 typedef Loki::NullType List;
00764 };
00765
00767
00770 template<class CEL> struct ExpandComposeElementList;
00771
00773
00778 template<class CELHead, class CELTail>
00779 struct ExpandComposeElementList<Loki::Typelist<CELHead, CELTail> >
00780 {
00781 typedef typename GenComposedList<typename CELHead::Units,
00782 typename ExpandComposeElementList<CELTail>::List>::List List;
00783 };
00784
00786
00788 template<>
00789 struct ExpandComposeElementList<Loki::NullType>
00790 {
00791 typedef Loki::NullType List;
00792 };
00793
00795
00798 template<class BC, class CUL> struct GenComposedUnits;
00799
00801
00804 template<class BT, class CEL, class CULHead, class CULTail>
00805 struct GenComposedUnits<ComposeBase<BT, CEL>,
00806 Loki::Typelist<CULHead, CULTail> >
00807 {
00808 typedef Loki::Typelist<Composed<ComposeBase<BT, CEL>, CULHead>,
00809 typename GenComposedUnits<ComposeBase<BT, CEL>,
00810 CULTail>::List> List;
00811 };
00812
00814
00817 template<class BT, class CEL>
00818 struct GenComposedUnits<ComposeBase<BT, CEL>, Loki::NullType>
00819 {
00820 typedef Loki::NullType List;
00821 };
00822
00824
00826 template<class CEL> struct GenPowers;
00827
00829
00832 template<class CELHead, class CELTail>
00833 struct GenPowers<Loki::Typelist<CELHead, CELTail> >
00834 {
00835 typedef Loki::Typelist<typename CELHead::Power,
00836 typename GenPowers<CELTail>::Powers> Powers;
00837 };
00838
00840
00844 template<class CE>
00845 struct GenPowers<Loki::Typelist<CE, Loki::NullType> >
00846 {
00847 typedef Loki::Typelist<typename CE::Power, Loki::NullType> Powers;
00848 };
00849
00850
00852
00853
00854
00855
00857
00859
00863 template<class BT, class UHead, class UTail,
00864 long N, long D, class ELTail>
00865 class ComposeBase<BT, Loki::Typelist<ComposeElement<BT,
00866 Loki::Typelist<UHead, UTail>, BSUtilities::Rational<N, D> >,
00867 ELTail> > : public Unit<BT>
00868 {
00869 private:
00870 typedef
00871 Loki::Typelist<ComposeElement<BT, Loki::Typelist<UHead, UTail>,
00872 BSUtilities::Rational<N, D> >, ELTail> ElementList;
00873
00874 public:
00875 typedef GenPowers<ElementList> Powers;
00876
00877 typedef typename
00878 GenComposedUnits<ComposeBase<BT, ElementList>, typename
00879 ExpandComposeElementList<ElementList>::List>::List Units;
00880 };
00881
00882 }
00883
00884 #endif