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 "TemplateTools.h"
00040 #include "Conversion.h"
00041
00043
00051 namespace unit {
00052
00054
00055
00056
00057
00059
00061
00064 template<bool>
00065 struct UnitError;
00066
00068
00070 template<class BU, class TU>
00071 struct CheckUnit
00072 {
00074
00084 typedef typename
00085 BSUtilities::IF<Loki::SuperSubclass<BU, TU>::value,
00086 TU, UnitError<true> >::RET Check;
00087 };
00088
00090
00096 template<class BU, class TUL>
00097 struct CheckUnits
00098 {
00099 private:
00100 typedef
00101 typename CheckUnit<BU, typename TUL::Head>::Check UnitCheck;
00102
00103 public:
00104 typedef typename CheckUnits<BU, typename TUL::Tail>::Check Check;
00105 };
00106
00108
00111 template<class BU>
00112 struct CheckUnits<BU, Loki::NullType>
00113 {
00115 typedef Loki::EmptyType Check;
00116 };
00117
00119
00120
00121
00123
00125 class Units
00126 {
00127 public:
00129
00132 static const std::string Version (void)
00133 {static const std::string v_string ("Units version 1.1");
00134 return v_string;}
00135
00137
00140 static const std::string version (void) {return Version ();}
00141
00142 };
00143
00145
00149 template<class BT> class Unit : public Units
00150 {
00151 public:
00153
00155 virtual const std::string name (void) const = 0;
00156
00158
00160 virtual const std::string symbol (void) const = 0;
00161
00163
00165 virtual const bool isSI (void) const = 0;
00166
00167 };
00168
00170
00171
00172
00174
00176
00180 template<class BT, class U>
00181 class NonPrefixable : public Unit<BT>
00182 {
00183 private:
00185 static const bool SI;
00186
00188
00190 static const std::string Namestring;
00191
00193
00195 static const std::string Symbolstring;
00196
00197 public:
00199
00203 static const bool IsSI (void) {return SI;}
00204
00206
00208 const bool isSI (void) const {return IsSI ();}
00209
00211
00212
00213
00214
00215
00216
00217 static const std::string Name (void) {return Namestring;}
00218
00220
00223 const std::string name (void) const {return Name ();}
00224
00226
00227
00228
00229
00230
00231
00232 static const std::string Symbol (void) {return Symbolstring;}
00233
00235
00238 const std::string symbol (void) const {return Symbol ();}
00239
00240 };
00241
00243
00244
00245
00247
00248
00249 template<class BT, class U> class Prefixable;
00250
00252
00255 template<class BP, class UP = No> class Prefixed;
00256
00258
00263 template<class BT, class U, class UP>
00264 class Prefixed<Prefixable<BT, U>, UP> : public Prefixable<BT, U>
00265 {
00266 public:
00268
00269
00270
00271
00272
00273
00274
00275
00276 static const std::string Name (void) {return UP::Name + Basename;}
00277
00279
00282 const std::string name (void) const {return Name ();}
00283
00285
00286
00287
00288
00289
00290
00291
00292
00293 static const std::string Symbol (void)
00294 {return UP::Symbol + Basesymbol;}
00295
00297
00300 const std::string symbol (void) const {return Symbol ();}
00301
00302 };
00303
00305
00312 template<class BT, class U> class Prefixable : public Unit<BT>
00313 {
00314 private:
00316
00318 static const bool SI;
00319
00320 public:
00322 typedef Loki::Typelist<Prefixed<Prefixable<BT, U>, Yotta>,
00323 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zetta>,
00324 Loki::Typelist<Prefixed<Prefixable<BT, U>, Exa>,
00325 Loki::Typelist<Prefixed<Prefixable<BT, U>, Peta>,
00326 Loki::Typelist<Prefixed<Prefixable<BT, U>, Tera>,
00327 Loki::Typelist<Prefixed<Prefixable<BT, U>, Giga>,
00328 Loki::Typelist<Prefixed<Prefixable<BT, U>, Mega>,
00329 Loki::Typelist<Prefixed<Prefixable<BT, U>, Kilo>,
00330 Loki::Typelist<Prefixed<Prefixable<BT, U>, Hecto>,
00331 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deca>,
00332 Loki::Typelist<Prefixed<Prefixable<BT, U>, No>,
00333 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deci>,
00334 Loki::Typelist<Prefixed<Prefixable<BT, U>, Centi>,
00335 Loki::Typelist<Prefixed<Prefixable<BT, U>, Milli>,
00336 Loki::Typelist<Prefixed<Prefixable<BT, U>, Micro>,
00337 Loki::Typelist<Prefixed<Prefixable<BT, U>, Nano>,
00338 Loki::Typelist<Prefixed<Prefixable<BT, U>, Pico>,
00339 Loki::Typelist<Prefixed<Prefixable<BT, U>, Femto>,
00340 Loki::Typelist<Prefixed<Prefixable<BT, U>, Atto>,
00341 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zepto>,
00342 Loki::Typelist<Prefixed<Prefixable<BT, U>, Yocto>,
00343 Loki::NullType> > > > > > > > > > > > > > > > > > > > >
00344 Units;
00345
00347
00351 static const bool IsSI (void) {return SI;}
00352
00354
00356 const bool isSI (void) const {return IsSI ();}
00357
00358 protected:
00360
00361
00362
00363 static const std::string Basename;
00364
00366
00367
00368
00369 static const std::string Basesymbol;
00370
00371 };
00372
00374
00375
00376
00377
00379
00381 template<class BT, class CEL> class ComposeBase;
00382
00384
00387 template<class BC, class CUL> class Composed;
00388
00390
00395 template<class BT, class UL, class R> struct ComposeElement;
00396
00398
00404 template<class BT, class BT1, class U, class UTail, long N, long D>
00405 struct
00406 ComposeElement<BT, Loki::Typelist<NonPrefixable<BT1, U>, UTail>,
00407 BSUtilities::Rational<N, D> >
00408 {
00409 private:
00410 typedef typename CheckUnits<Unit<BT1>,
00411 Loki::Typelist<NonPrefixable<BT1, U>, UTail> >::Check Check;
00412
00413 public:
00414 typedef Loki::Typelist<NonPrefixable<BT1, U>, UTail> Units;
00415 typedef BSUtilities::Rational<N, D> Power;
00416 };
00417
00419
00425 template<class BT, class BT1, class U, class UP, class UTail,
00426 long N, long D>
00427 struct ComposeElement<BT,
00428 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>,
00429 BSUtilities::Rational<N, D> >
00430 {
00431 private:
00432 typedef typename CheckUnits<Unit<BT1>,
00433 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail> >
00434 ::Check Check;
00435
00436 public:
00437 typedef Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>
00438 Units;
00439 typedef BSUtilities::Rational<N, D> Power;
00440 };
00441
00443
00449 template<class BT, class BT1, class CEL, class CUL,
00450 class UTail, long N, long D>
00451 struct ComposeElement<BT,
00452 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail>,
00453 BSUtilities::Rational<N, D> >
00454 {
00455 private:
00456 typedef typename CheckUnits<Unit<BT1>,
00457 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail> >
00458 ::Check Check;
00459
00460 public:
00461 typedef Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>,
00462 UTail> Units;
00463 typedef BSUtilities::Rational<N, D> Power;
00464 };
00465
00467
00469 template<class UL> struct ComposedSI;
00470
00472
00476 template<class U, class UTail>
00477 struct ComposedSI<Loki::Typelist<U, UTail> >
00478 {
00483 static const bool isSI (void)
00484 {return ((U::IsSI () && ComposedSI<UTail>::isSI ()) ? 1 : 0);}
00485
00486 };
00487
00491 template<>
00492 struct ComposedSI<Loki::NullType>
00493 {
00494 static const bool isSI (void) {return true;}
00495 };
00496
00498
00501 template<class UL, class RL> struct ComposedStrings;
00502
00504
00506 template<class U, class UTail, long N, long D, class RTail>
00507 struct ComposedStrings<Loki::Typelist<U, UTail>,
00508 Loki::Typelist<BSUtilities::Rational<N, D>, RTail> >
00509 {
00510 static const std::string Name (void)
00511 {return U::Name ()
00512 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00513 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00514 + ComposedStrings<UTail, RTail>::Name ();}
00515
00516 static const std::string Symbol (void)
00517 {return U::Symbol ()
00518 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00519 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00520 + ComposedStrings<UTail, RTail>::Symbol ();}
00521 };
00522
00524
00526 template<class U, class UTail, long N, class RTail>
00527 struct ComposedStrings<Loki::Typelist<U, UTail>,
00528 Loki::Typelist<BSUtilities::Rational<N, 1L>, RTail> >
00529 {
00530 static const std::string Name (void)
00531 {return U::Name ()
00532 + "^" + BSUtilities::Conversion<long>::to_string(N)
00533 + ComposedStrings<UTail, RTail>::Name ();}
00534
00535 static const std::string Symbol (void)
00536 {return U::Symbol ()
00537 + "^" + BSUtilities::Conversion<long>::to_string(N) + " "
00538 + ComposedStrings<UTail, RTail>::Symbol ();}
00539 };
00540
00542
00544 template<class U, class UTail, class RTail>
00545 struct ComposedStrings<Loki::Typelist<U, UTail>,
00546 Loki::Typelist<BSUtilities::Rational<1L, 1L>, RTail> >
00547 {
00548 static const std::string Name (void)
00549 {return U::Name () + ComposedStrings<UTail, RTail>::Name ();}
00550
00551 static const std::string Symbol (void)
00552 {return U::Symbol () + " "
00553 + ComposedStrings<UTail, RTail>::Symbol ();}
00554 };
00555
00557
00559 template<class U, long N, long D>
00560 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00561 Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType> >
00562 {
00563 static const std::string Name (void)
00564 {return U::Name ()
00565 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00566 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00567
00568 static const std::string Symbol (void)
00569 {return U::Symbol ()
00570 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00571 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00572 };
00573
00575
00578 template<class U, long N>
00579 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00580 Loki::Typelist<BSUtilities::Rational<N>, Loki::NullType> >
00581 {
00582 static const std::string Name (void)
00583 {return U::Name ()
00584 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00585
00586 static const std::string Symbol (void)
00587 {return U::Symbol ()
00588 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00589 };
00590
00592
00601 template<class BT, class CEL, class UL>
00602 class Composed<ComposeBase<BT, CEL>, UL> : public ComposeBase<BT, CEL>
00603 {
00604 private:
00605 typedef Composed<ComposeBase<BT, CEL>, UL> Unit;
00606 typedef typename ComposeBase<BT, CEL>::Powers::Powers Powers;
00607
00608 public:
00610
00611
00612 static const bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00613
00615
00617 bool const isSI (void) const {return IsSI ();}
00618
00620
00621
00622
00623
00624
00625
00626 static const std::string Name (void)
00627 {return ComposedStrings<UL, Powers>::Name ();}
00628
00630
00633 const std::string name (void) const {return Name ();}
00634
00636
00637
00638
00639
00640
00641
00642 static const std::string Symbol (void)
00643 {return ComposedStrings<UL, Powers>::Symbol ();}
00644
00646
00649 const std::string symbol (void) const {return Symbol ();}
00650
00651 };
00652
00654
00663 template<class UL, class CUL> struct GenComposedList;
00664
00666
00672 template<class U, class UTail>
00673 struct GenComposedList<Loki::Typelist<U, UTail>, Loki::NullType>
00674 {
00675 typedef
00676 Loki::Typelist<Loki::Typelist<U, Loki::NullType>,
00677 typename GenComposedList<UTail, Loki::NullType>::List> List;
00678 };
00679
00681
00685 template<>
00686 struct GenComposedList<Loki::NullType, Loki::NullType>
00687 {
00688 typedef Loki::NullType List;
00689 };
00690
00692
00700 template<class U1, class U, class UTail, class CULTail>
00701 struct GenComposedList<U1,
00702 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00703 {
00704 typedef Loki::Typelist<Loki::Typelist<U1,
00705 Loki::Typelist<U, UTail> >,
00706 typename GenComposedList<U1, CULTail>::List> List;
00707 };
00708
00710
00712 template<class U>
00713 struct GenComposedList<U, Loki::NullType>
00714 {
00715 typedef Loki::NullType List;
00716 };
00717
00719
00725 template<class U1, class U, class UTail, class U1Tail, class CULTail>
00726 struct GenComposedList<Loki::Typelist<U1, U1Tail>,
00727 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00728 {
00729 typedef typename BSUtilities::Concatenate<typename
00730 GenComposedList<U1,
00731 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >::List,
00732 typename GenComposedList<U1Tail,
00733 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail>
00734 >::List>::Result List;
00735 };
00736
00738
00741 template<class U, class UTail, class CULTail>
00742 struct GenComposedList<Loki::NullType,
00743 Loki::Typelist<Loki::Typelist<U, UTail>, CULTail> >
00744 {
00745 typedef Loki::NullType List;
00746 };
00747
00749
00752 template<class CEL> struct ExpandComposeElementList;
00753
00755
00760 template<class CELHead, class CELTail>
00761 struct ExpandComposeElementList<Loki::Typelist<CELHead, CELTail> >
00762 {
00763 typedef typename GenComposedList<typename CELHead::Units,
00764 typename ExpandComposeElementList<CELTail>::List>::List List;
00765 };
00766
00768
00770 template<>
00771 struct ExpandComposeElementList<Loki::NullType>
00772 {
00773 typedef Loki::NullType List;
00774 };
00775
00777
00780 template<class BC, class CUL> struct GenComposedUnits;
00781
00783
00786 template<class BT, class CEL, class CULHead, class CULTail>
00787 struct GenComposedUnits<ComposeBase<BT, CEL>,
00788 Loki::Typelist<CULHead, CULTail> >
00789 {
00790 typedef Loki::Typelist<Composed<ComposeBase<BT, CEL>, CULHead>,
00791 typename GenComposedUnits<ComposeBase<BT, CEL>,
00792 CULTail>::List> List;
00793 };
00794
00796
00799 template<class BT, class CEL>
00800 struct GenComposedUnits<ComposeBase<BT, CEL>, Loki::NullType>
00801 {
00802 typedef Loki::NullType List;
00803 };
00804
00806
00808 template<class CEL> struct GenPowers;
00809
00811
00814 template<class CELHead, class CELTail>
00815 struct GenPowers<Loki::Typelist<CELHead, CELTail> >
00816 {
00817 typedef Loki::Typelist<typename CELHead::Power,
00818 typename GenPowers<CELTail>::Powers> Powers;
00819 };
00820
00822
00826 template<class CE>
00827 struct GenPowers<Loki::Typelist<CE, Loki::NullType> >
00828 {
00829 typedef Loki::Typelist<typename CE::Power, Loki::NullType> Powers;
00830 };
00831
00832
00834
00835
00836
00837
00839
00841
00845 template<class BT, class UHead, class UTail,
00846 long N, long D, class ELTail>
00847 class ComposeBase<BT, Loki::Typelist<ComposeElement<BT,
00848 Loki::Typelist<UHead, UTail>, BSUtilities::Rational<N, D> >,
00849 ELTail> > : public Unit<BT>
00850 {
00851 private:
00852 typedef
00853 Loki::Typelist<ComposeElement<BT, Loki::Typelist<UHead, UTail>,
00854 BSUtilities::Rational<N, D> >, ELTail> ElementList;
00855
00856 public:
00857 typedef GenPowers<ElementList> Powers;
00858
00859 typedef typename
00860 GenComposedUnits<ComposeBase<BT, ElementList>, typename
00861 ExpandComposeElementList<ElementList>::List>::List Units;
00862 };
00863
00864 }
00865
00866 #endif