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 "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 //  Helper classes and structs which check that units are derived
00061 //  from certain base classes 
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 //  the Units and Unit base class templates
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 //  the NonPrefixable units
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 /*  direct static access to be used if type of unit is known at 
00229     compile time; returns the namestring;
00230     must not be a static const data member, since similar functions
00231     in other cases of units require access to possibly not yet defined
00232     static data.
00233 */
00234       static const std::string Name (void) {return Namestring;}
00235 
00237 
00240       const std::string name (void) const {return Name ();}
00241 
00243 /*  direct static access to be used if type of unit is known at 
00244     compile time; 
00245     must not be a static const data member, since similar functions
00246     in other cases of units require access to possibly not yet defined
00247     static data.
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 //  the Prefixable and Prefixed units
00262 //
00264 
00265 // forward declaration
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 /*  direct static access to be used if type of unit is known at 
00286     compile time; 
00287     get name from prefix and prepend to basename 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 Name (void) 
00294                       {return UP::Name + Prefixable<BT, U>::Basename;}
00295 
00297 
00300       const std::string name (void) const {return Name ();}
00301 
00303 /*  direct static access to be used if type of unit is known at 
00304     compile time; 
00305     get symbol from prefix and prepend to basesymbol which is inherited
00306     from Prefixable<BT, U>
00307     must not be a static const data member, since similar functions
00308     in other cases of units require access to possibly not yet defined
00309     static data.
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 /*  direct static access to be used if type of unit is known at 
00379     compile time 
00380 */
00381       static const std::string Basename;
00382 
00384 /*  direct static access to be used if type of unit is known at 
00385     compile time 
00386 */
00387       static const std::string Basesymbol;
00388 
00389   };
00390 
00392 //
00393 //  the ComposeBase and Composed units with helper classes and structs
00394 //  ComposeElement, ComposedSI, ComposedStrings
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 /*  static access
00629 */
00630       static const bool IsSI (void) {return ComposedSI<UL>::isSI ();}
00631 
00633 
00635       bool const isSI (void) const {return IsSI ();}
00636 
00638 /*  direct static access to be used if type of unit is known at 
00639     compile time;
00640     must not be a static const data member, since it requires access
00641     to the name values of the individual elementary units; they may 
00642     not be available yet when they are needed here.
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 /*  direct static access to be used if type of unit is known at 
00655     compile time;
00656     must not be a static const data member, since it requires access
00657     to the symbol values of the individual elementary units; they may 
00658     not be available yet when they are needed here.
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 //  template ComposeBase
00854 //  a unit compounded from one or more base units
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 /* _Unit_h */

Generated on Mon Feb 12 18:43:57 2007 for Quantity by doxygen 1.3.6