Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Unit.h

Go to the documentation of this file.
00001 
00004 /* Unit is an abstract base class for units according to the SI, see
00005    Mills et al., 1993 */
00006 
00007 /* Copyright (C) 2002 - 2005, Bernd Speiser */
00008 /* This file is part of Quantity.
00009 
00010 Quantity is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 Quantity is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019   
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00023 02111-1307, USA.
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 //  Helper classes and structs which check that units are derived
00056 //  from certain base classes 
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 //  the Units and Unit base class templates
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 //  the NonPrefixable units
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 /*  direct static access to be used if type of unit is known at 
00212     compile time; returns the namestring;
00213     must not be a static const data member, since similar functions
00214     in other cases of units require access to possibly not yet defined
00215     static data.
00216 */
00217       static const std::string Name (void) {return Namestring;}
00218 
00220 
00223       const std::string name (void) const {return Name ();}
00224 
00226 /*  direct static access to be used if type of unit is known at 
00227     compile time; 
00228     must not be a static const data member, since similar functions
00229     in other cases of units require access to possibly not yet defined
00230     static data.
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 //  the Prefixable and Prefixed units
00245 //
00247 
00248 // forward declaration
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 /*  direct static access to be used if type of unit is known at 
00269     compile time; 
00270     get name from prefix and prepend to basename which is inherited
00271     from Prefixable<BT, U>;
00272     must not be a static const data member, since similar functions
00273     in other cases of units require access to possibly not yet defined
00274     static data.
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 /*  direct static access to be used if type of unit is known at 
00286     compile time; 
00287     get symbol from prefix and prepend to basesymbol which is inherited
00288     from Prefixable<BT, U>
00289     must not be a static const data member, since similar functions
00290     in other cases of units require access to possibly not yet defined
00291     static data.
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 /*  direct static access to be used if type of unit is known at 
00361     compile time 
00362 */
00363       static const std::string Basename;
00364 
00366 /*  direct static access to be used if type of unit is known at 
00367     compile time 
00368 */
00369       static const std::string Basesymbol;
00370 
00371   };
00372 
00374 //
00375 //  the ComposeBase and Composed units with helper classes and structs
00376 //  ComposeElement, ComposedSI, ComposedStrings
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 /*  static access
00611 */
00612       static const bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00613 
00615 
00617       bool const isSI (void) const {return IsSI ();}
00618 
00620 /*  direct static access to be used if type of unit is known at 
00621     compile time;
00622     must not be a static const data member, since it requires access
00623     to the name values of the individual elementary units; they may 
00624     not be available yet when they are needed here.
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 /*  direct static access to be used if type of unit is known at 
00637     compile time;
00638     must not be a static const data member, since it requires access
00639     to the symbol values of the individual elementary units; they may 
00640     not be available yet when they are needed here.
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 //  template ComposeBase
00836 //  a unit compounded from one or more base units
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 /* _Unit_h */

Generated on Sun Jan 15 14:05:20 2006 for Quantity by doxygen 1.3.6