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
00030 #include "Quantity/Prefix.h"
00031
00032
00033 #include "BSUtilities/BSUtilities.h"
00034 #include "BSUtilities/TemplateTools.h"
00035 #include "BSUtilities/Conversion.h"
00036
00037
00038 #include "loki/NullType.h"
00039 #include "loki/EmptyType.h"
00040 #include "loki/TypeManip.h"
00041 #include "loki/Typelist.h"
00042
00043
00044 #include <vector>
00045 #include <string>
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
00147 };
00148
00150
00154 template<class BT> class Unit : public Units
00155 {
00156 public:
00158
00160 virtual std::string name (void) const = 0;
00161
00163
00165 virtual std::string symbol (void) const = 0;
00166
00168
00170 virtual bool isSI (void) const = 0;
00171
00172 virtual ~Unit () {}
00173
00174 };
00175
00177
00178
00179
00181
00183
00187 template<class BT, class U>
00188 class NonPrefixable : public Unit<BT>
00189 {
00190 private:
00192 static const bool SI;
00193
00195
00197 static const std::string Namestring;
00198
00200
00202 static const std::string Symbolstring;
00203
00204 public:
00206
00210 static bool IsSI (void) {return SI;}
00211
00213
00215 bool isSI (void) const {return IsSI ();}
00216
00218
00219
00220
00221
00222
00223
00224 static std::string Name (void) {return Namestring;}
00225
00227
00230 std::string name (void) const {return Name ();}
00231
00233
00234
00235
00236
00237
00238
00239 static std::string Symbol (void) {return Symbolstring;}
00240
00242
00245 std::string symbol (void) const {return Symbol ();}
00246
00247 };
00248
00250
00251
00252
00254
00255
00256 template<class BT, class U> class Prefixable;
00257
00259
00262 template<class BP, class UP = No> class Prefixed;
00263
00265
00270 template<class BT, class U, class UP>
00271 class Prefixed<Prefixable<BT, U>, UP> : public Prefixable<BT, U>
00272 {
00273 public:
00275
00276
00277
00278
00279
00280
00281
00282
00283 static std::string Name (void)
00284 {return UP::Name + Prefixable<BT, U>::Basename;}
00285
00287
00290 std::string name (void) const {return Name ();}
00291
00293
00294
00295
00296
00297
00298
00299
00300
00301 static std::string Symbol (void)
00302 {return UP::Symbol + Prefixable<BT, U>::Basesymbol;}
00303
00305
00308 std::string symbol (void) const {return Symbol ();}
00309
00310 };
00311
00313
00320 template<class BT, class U> class Prefixable : public Unit<BT>
00321 {
00322 private:
00324
00326 static const bool SI;
00327
00328 public:
00330 typedef Loki::Typelist<Prefixed<Prefixable<BT, U>, Yotta>,
00331 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zetta>,
00332 Loki::Typelist<Prefixed<Prefixable<BT, U>, Exa>,
00333 Loki::Typelist<Prefixed<Prefixable<BT, U>, Peta>,
00334 Loki::Typelist<Prefixed<Prefixable<BT, U>, Tera>,
00335 Loki::Typelist<Prefixed<Prefixable<BT, U>, Giga>,
00336 Loki::Typelist<Prefixed<Prefixable<BT, U>, Mega>,
00337 Loki::Typelist<Prefixed<Prefixable<BT, U>, Kilo>,
00338 Loki::Typelist<Prefixed<Prefixable<BT, U>, Hecto>,
00339 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deca>,
00340 Loki::Typelist<Prefixed<Prefixable<BT, U>, No>,
00341 Loki::Typelist<Prefixed<Prefixable<BT, U>, Deci>,
00342 Loki::Typelist<Prefixed<Prefixable<BT, U>, Centi>,
00343 Loki::Typelist<Prefixed<Prefixable<BT, U>, Milli>,
00344 Loki::Typelist<Prefixed<Prefixable<BT, U>, Micro>,
00345 Loki::Typelist<Prefixed<Prefixable<BT, U>, Nano>,
00346 Loki::Typelist<Prefixed<Prefixable<BT, U>, Pico>,
00347 Loki::Typelist<Prefixed<Prefixable<BT, U>, Femto>,
00348 Loki::Typelist<Prefixed<Prefixable<BT, U>, Atto>,
00349 Loki::Typelist<Prefixed<Prefixable<BT, U>, Zepto>,
00350 Loki::Typelist<Prefixed<Prefixable<BT, U>, Yocto>,
00351 Loki::NullType> > > > > > > > > > > > > > > > > > > > >
00352 Units;
00353
00355
00359 static bool IsSI (void) {return SI;}
00360
00362
00364 bool isSI (void) const {return IsSI ();}
00365
00366 protected:
00368
00369
00370
00371 static const std::string Basename;
00372
00374
00375
00376
00377 static const std::string Basesymbol;
00378
00379 };
00380
00382
00383
00384
00385
00387
00389 template<class BT, class CEL> class ComposeBase;
00390
00392
00395 template<class BC, class CUL> class Composed;
00396
00398
00403 template<class BT, class UL, class R> struct ComposeElement;
00404
00406
00412 template<class BT, class BT1, class U, class UTail, long N, long D>
00413 struct
00414 ComposeElement<BT, Loki::Typelist<NonPrefixable<BT1, U>, UTail>,
00415 BSUtilities::Rational<N, D> >
00416 {
00417 private:
00418 typedef typename CheckUnits<Unit<BT1>,
00419 Loki::Typelist<NonPrefixable<BT1, U>, UTail> >::Check Check;
00420
00421 public:
00422 typedef Loki::Typelist<NonPrefixable<BT1, U>, UTail> Units;
00423 typedef BSUtilities::Rational<N, D> Power;
00424 };
00425
00427
00433 template<class BT, class BT1, class U, class UP, class UTail,
00434 long N, long D>
00435 struct ComposeElement<BT,
00436 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>,
00437 BSUtilities::Rational<N, D> >
00438 {
00439 private:
00440 typedef typename CheckUnits<Unit<BT1>,
00441 Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail> >
00442 ::Check Check;
00443
00444 public:
00445 typedef Loki::Typelist<Prefixed<Prefixable<BT1, U>, UP>, UTail>
00446 Units;
00447 typedef BSUtilities::Rational<N, D> Power;
00448 };
00449
00451
00457 template<class BT, class BT1, class CEL, class CUL,
00458 class UTail, long N, long D>
00459 struct ComposeElement<BT,
00460 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail>,
00461 BSUtilities::Rational<N, D> >
00462 {
00463 private:
00464 typedef typename CheckUnits<Unit<BT1>,
00465 Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>, UTail> >
00466 ::Check Check;
00467
00468 public:
00469 typedef Loki::Typelist<Composed<ComposeBase<BT1, CEL>, CUL>,
00470 UTail> Units;
00471 typedef BSUtilities::Rational<N, D> Power;
00472 };
00473
00475
00477 template<class UL> struct ComposedSI;
00478
00480
00484 template<class U, class UTail>
00485 struct ComposedSI<Loki::Typelist<U, UTail> >
00486 {
00491 static bool isSI (void)
00492 {return ((U::IsSI () && ComposedSI<UTail>::isSI ()) ? 1 : 0);}
00493
00494 };
00495
00499 template<>
00500 struct ComposedSI<Loki::NullType>
00501 {
00502 static bool isSI (void) {return true;}
00503 };
00504
00506
00509 template<class UL, class RL> struct ComposedStrings;
00510
00512
00516 template<class U, class UTail, long N, long D, class RTail>
00517 struct ComposedStrings<Loki::Typelist<U, UTail>,
00518 Loki::Typelist<BSUtilities::Rational<N, D>, RTail> >
00519 {
00520 static const std::string Name (void)
00521 {return U::Name ()
00522 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00523 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00524 + ComposedStrings<UTail, RTail>::Name ();}
00525
00526 static const std::string Symbol (void)
00527 {return U::Symbol ()
00528 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00529 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00530 + ComposedStrings<UTail, RTail>::Symbol ();}
00531
00532 };
00533
00535
00537 template<class U, class UTail, long N, class RTail>
00538 struct ComposedStrings<Loki::Typelist<U, UTail>,
00539 Loki::Typelist<BSUtilities::Rational<N, 1L>, RTail> >
00540 {
00541 static const std::string Name (void)
00542 {return U::Name ()
00543 + "^" + BSUtilities::Conversion<long>::to_string(N)
00544 + ComposedStrings<UTail, RTail>::Name ();}
00545
00546 static const std::string Symbol (void)
00547 {return U::Symbol ()
00548 + "^" + BSUtilities::Conversion<long>::to_string(N) + " "
00549 + ComposedStrings<UTail, RTail>::Symbol ();}
00550
00551 };
00552
00554
00556 template<class U, class UTail, class RTail>
00557 struct ComposedStrings<Loki::Typelist<U, UTail>,
00558 Loki::Typelist<BSUtilities::Rational<1L, 1L>, RTail> >
00559 {
00560 static const std::string Name (void)
00561 {return U::Name () + ComposedStrings<UTail, RTail>::Name ();}
00562
00563 static const std::string Symbol (void)
00564 {return U::Symbol () + " "
00565 + ComposedStrings<UTail, RTail>::Symbol ();}
00566
00567 };
00568
00570
00572 template<class U, long N, long D>
00573 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00574 Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType> >
00575 {
00576 static const std::string Name (void)
00577 {return U::Name ()
00578 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00579 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00580
00581 static const std::string Symbol (void)
00582 {return U::Symbol ()
00583 + "^(" + BSUtilities::Conversion<long>::to_string(N)
00584 + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00585
00586 };
00587
00589
00592 template<class U, long N>
00593 struct ComposedStrings<Loki::Typelist<U, Loki::NullType>,
00594 Loki::Typelist<BSUtilities::Rational<N>, Loki::NullType> >
00595 {
00596 static const std::string Name (void)
00597 {return U::Name ()
00598 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00599
00600 static const std::string Symbol (void)
00601 {return U::Symbol ()
00602 + "^" + BSUtilities::Conversion<long>::to_string(N);}
00603
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 bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00628
00630
00632 bool 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 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 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