Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class 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, 2003, 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 /* a Unit has a symbol and a name, as defined by Mills et al., 1993 */
00027 /* symbol and/or name of a Unit is/are retrieved by the corresponding
00028    functions as a C++ style string */
00029 /* a Unit can be a SI unit; if not, its use is not recommended;
00030    this property can be tested by is_SI */
00031 /* to some Units a prefix can be attached; these are in particular 
00032    the SI base units, the SI derived units with special names (except
00033    the degree Celsius), some other derived SI units and some of the
00034    `units in use together with the SI' */ 
00035 /* prefixing is done by adding a private data member UnitPrefix * to 
00036    the class */
00037 /* Units are often used in close relation to Quantities 
00038    if several Units are valid for a given Quantity, conversion functions
00039    are provided;
00040    one of the appropriate Units is defined as `standard' Unit; 
00041    the standard unit must correspond to a (combination of) SI unit(s);
00042    the standardize_function converts the argument value (given in Unit)
00043    into the standard Unit;
00044    the destandardize_function converts the argument value (which is 
00045    assumed to be in the standard Unit) into Unit;
00046    the conversion functions for the standard Unit return the argument 
00047    value itself; */
00048 /* a conversion function (?) can be exact or approximate; this property 
00049    can be tested by is_exact; exact in this context means that it does
00050    not depend on experimentally determined constants or other 
00051    variables */
00052 /* copy returns a pointer to a new Unit object of the same type as 
00053    this function was invoked from */
00054 
00055 #ifndef _Unit_h
00056 #define _Unit_h
00057 
00058 #include <vector>
00059 #include <string>
00060 
00061 #include "Quantity/UnitPrefix.h"
00062 
00063 #include "NullType.h"
00064 #include "EmptyType.h"
00065 #include "TypeManip.h"
00066 #include "Typelist.h"
00067 
00068 #include "TemplateTools.h"
00069 #include "Conversion.h"
00070 
00072 
00080 namespace Units {
00081 
00083 //
00084 //  Helper classes and structs which check that units are derived
00085 //  from certain base classes 
00086 //
00088 
00090 
00092 template<bool> 
00093   struct UnitError;
00094 
00096 
00100 template<> 
00101   struct UnitError<false> 
00102     { 
00104 
00106       typedef UnitError<false> RET;
00107     };
00108 
00109  
00111 
00113 template<class BU, class U>
00114   struct CheckUnit
00115   {
00117 
00126     typedef typename
00127       BSUtilities::IF<Loki::SuperSubclass<BU, U>::value, 
00128                     UnitError<false>, UnitError<true> >::RET::RET Check;
00129   };
00130 
00132 
00138 template<class BU, class U>
00139   struct CheckUnits
00140   {
00141     private: 
00142       typedef typename CheckUnit<BU, typename U::Head>::Check UnitCheck;
00143 
00144     public: 
00145       typedef typename CheckUnits<BU, typename U::Tail>::Checked 
00146                                                                 Checked;
00147   };
00148 
00150 
00153 template<class BU>
00154   struct CheckUnits<BU, Loki::NullType>
00155   {
00157     typedef Loki::EmptyType Checked;
00158   };
00159 
00161 //
00162 //  the Units and Unit base class templates
00163 //
00165 
00167 class Units
00168   {
00169     public:
00171 
00173       static std::string version (void)
00174         {static const std::string v_string ("Units version 1.0");
00175                                                        return v_string;}
00176 
00177   };
00178 
00180 
00185 template<class GT, class ST = double> class Unit : public Units
00186   {
00187     public:
00189 
00191       virtual const std::string name (void) const = 0;
00192 
00194 
00196       virtual const std::string symbol (void) const = 0;
00197 
00199 
00201       virtual ST standard (const ST &) const = 0;
00202 
00204 
00206       virtual ST reverse (const ST &) const = 0;
00207 
00209 
00211       virtual bool is_SI (void) const = 0;
00212 
00214 
00216       virtual bool is_exact (void) const = 0;
00217   };
00218 
00220 //
00221 //  the NonPrefixable units
00222 //
00224 
00226 
00235 template<class GT, class U, class ST = double> 
00236   class NonPrefixable : public Unit<GT, ST>
00237   {
00238     private:
00240       static const bool SI;
00241 
00243       static const bool Exact;
00244 
00246 
00248       static const std::string Namestring;
00249 
00251 
00253       static const std::string Symbolstring;
00254 
00255     public:
00257 
00261       static bool Is_SI (void) {return SI;}
00262 
00264 
00266       bool is_SI (void) const {return Is_SI ();}
00267 
00269 
00273       static bool Is_exact (void) {return Exact;}
00274 
00276 
00278       bool is_exact (void) const {return Is_exact ();}
00279 
00281 
00284       static const ST StandardRatio;
00285 
00287 
00290       static ST standardRatio (void) {return StandardRatio;}
00291 
00293 
00296       static ST Standard (const ST &value) 
00297                                          {return value * StandardRatio;}
00298 
00300 
00303       ST standard (const ST &value) const {return Standard (value);}
00304 
00306 
00309       static ST Reverse (const ST &value)
00310                                          {return value / StandardRatio;}
00311 
00313 
00316       ST reverse (const ST &value) const {return Reverse (value);}
00317 
00319 /*  direct static access to be used if type of unit is known at 
00320     compile time; returns the namestring;
00321     must not be a static const data member, since similar functions
00322     in other cases of units require access to possibly not yet defined
00323     static data.
00324 */
00325       static std::string Name (void) {return Namestring;}
00326 
00328 
00331       const std::string name (void) const {return Name ();}
00332 
00334 /*  direct static access to be used if type of unit is known at 
00335     compile time; 
00336     must not be a static const data member, since similar functions
00337     in other cases of units require access to possibly not yet defined
00338     static data.
00339 */
00340       static std::string Symbol (void) {return Symbolstring;}
00341 
00343 
00346       const std::string symbol (void) const {return Symbol ();}
00347 
00348   };
00349 
00351 //
00352 //  the Prefixable and Prefixed units
00353 //
00355 
00356 // forward declaration
00357 template<class GT, class U, class ST = double> class Prefixable;
00358 
00360 
00363 template<class PU, class P = No> class Prefixed;
00364 
00366 
00373 template<class GT, class U, class P, class ST> 
00374   class Prefixed<Prefixable<GT, U, ST>, P> 
00375                                          : public Prefixable<GT, U, ST>
00376   {
00377     public:
00379 
00382       static ST Standard (const ST &value) 
00383         {return ST(Prefixable<GT, U, ST>::StandardRatio
00384                                                   * value * P::factor);}
00386 
00389       ST standard (const ST &value) const {return Standard (value);}
00390 
00392 
00395       static ST standardRatio (void) 
00396               {return Prefixable<GT, U, ST>::StandardRatio * P::factor;}
00397 
00399 
00402       static ST Reverse (const ST &value) 
00403         {return ST(value / (Prefixable<GT, U, ST>::StandardRatio *
00404                                                            P::factor));}
00405 
00407 
00410       ST reverse (const ST &value) const {return Reverse (value);}
00411 
00413 /*  direct static access to be used if type of unit is known at 
00414     compile time; 
00415     get name from prefix and prepend to basename which is inherited
00416     from Prefixable<GT, U, ST>;
00417     must not be a static const data member, since similar functions
00418     in other cases of units require access to possibly not yet defined
00419     static data.
00420 */
00421       static std::string Name (void) {return P::Name + Basename;}
00422 
00424 
00427       const std::string name (void) const {return Name ();}
00428 
00430 /*  direct static access to be used if type of unit is known at 
00431     compile time; 
00432     get symbol from prefix and prepend to basesymbol which is inherited
00433     from Prefixable<GT, U, ST>
00434     must not be a static const data member, since similar functions
00435     in other cases of units require access to possibly not yet defined
00436     static data.
00437 */
00438       static std::string Symbol (void) {return P::Symbol + Basesymbol;}
00439 
00441 
00444       const std::string symbol (void) const {return Symbol ();}
00445   };
00446 
00448 
00460 template<class GT, class U, class ST> class Prefixable 
00461                                                    : public Unit<GT, ST>
00462   {
00463     private:
00465 
00467       static const bool SI;
00468 
00470 
00472       static const bool Exact;
00473 
00474     public:
00476       typedef Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Yotta>, 
00477               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Zetta>, 
00478               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Exa>, 
00479               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Peta>, 
00480               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Tera>, 
00481               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Giga>, 
00482               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Mega>, 
00483               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Kilo>, 
00484               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Hecto>, 
00485               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Deca>, 
00486               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, No>, 
00487               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Deci>, 
00488               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Centi>, 
00489               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Milli>, 
00490               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Micro>, 
00491               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Nano>, 
00492               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Pico>, 
00493               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Femto>, 
00494               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Atto>, 
00495               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Zepto>, 
00496               Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, Yocto>, 
00497               Loki::NullType> > > > > > > > > > > > > > > > > > > > > 
00498                                                                   Units;
00499 
00501 
00505       static bool Is_SI (void) {return SI;}
00506 
00508 
00510       bool is_SI (void) const {return Is_SI ();}
00511 
00513 
00517       static bool Is_exact (void) {return Exact;}
00518 
00520 
00522       bool is_exact (void) const {return Is_exact ();}
00523 
00525 
00528       static const ST StandardRatio;
00529 
00531 
00534       static ST standardRatio (void) {return StandardRatio;}
00535 
00536     protected:
00538 /*  direct static access to be used if type of unit is known at 
00539     compile time 
00540 */
00541       static const std::string Basename;
00542 
00544 /*  direct static access to be used if type of unit is known at 
00545     compile time 
00546 */
00547       static const std::string Basesymbol;
00548 
00550 
00555       static ST Standard (const ST &value) 
00556                                          {return value * StandardRatio;}
00557 
00559 
00564       ST standard (const ST &value) const {return Standard (value);}
00565 
00567 
00572       static ST Reverse (const ST &value) 
00573                                          {return value / StandardRatio;}
00574 
00576 
00581       ST reverse (const ST &value) const {return Reverse (value);}
00582 
00583   };
00584 
00586 //
00587 //  the Compound and Composed units with helper classes and structs
00588 //  CompoundElement, CheckBoolProperty
00589 //
00591 
00593 
00595 template<class GT, class UE, class ST = double> class Compound;
00596 
00598 
00601 template<class BC, class EL> class Composed;
00602 
00604 
00610 template<class GT, class U, class R, class ST = double> 
00611                                                 struct CompoundElement;
00612 
00614 
00619 template<class GT, class GT1, class U, class Tail, long N, long D, 
00620                                                                class ST>
00621   struct CompoundElement<GT, 
00622     Loki::Typelist<NonPrefixable<GT1, U, ST>, Tail>, 
00623                                         BSUtilities::Rational<N, D>, ST>
00624   {
00625     private:
00626       typedef typename CheckUnits<Unit<GT1, ST>, 
00627         Loki::Typelist<NonPrefixable<GT1, U, ST>, Tail> >::Checked 
00628                                                                 Checked;
00629 
00630     public:
00631       typedef Loki::Typelist<NonPrefixable<GT1, U, ST>, Tail> Units;
00632       typedef BSUtilities::Rational<N, D> Power;
00633   };
00634 
00635 template<class GT, class GT1, class U, class P, class Tail, 
00636                                                long N, long D, class ST>
00637   struct CompoundElement<GT, 
00638     Loki::Typelist<Prefixed<Prefixable<GT1, U, ST>, P>, Tail>, 
00639                                         BSUtilities::Rational<N, D>, ST>
00640   {
00641     private:
00642       typedef typename CheckUnits<Unit<GT1, ST>, 
00643             Loki::Typelist<Prefixed<Prefixable<GT1, U, ST>, P>, Tail> >
00644                                                       ::Checked Checked;
00645 
00646     public:
00647       typedef Loki::Typelist<Prefixed<Prefixable<GT1, U, ST>, P>, Tail>
00648                                                                   Units;
00649       typedef BSUtilities::Rational<N, D> Power;
00650   };
00651 
00652 template<class GT, class GT1, class U, class EL, class Tail, 
00653                                                long N, long D, class ST>
00654   struct CompoundElement<GT, 
00655     Loki::Typelist<Composed<Compound<GT1, U, ST>, EL>, Tail>, 
00656                                         BSUtilities::Rational<N, D>, ST>
00657   {
00658     private:
00659       typedef typename CheckUnits<Unit<GT1, ST>, 
00660         Loki::Typelist<Composed<Compound<GT1, U, ST>, EL>, Tail> >
00661                                                       ::Checked Checked;
00662 
00663     public:
00664       typedef Loki::Typelist<Composed<Compound<GT1, U, ST>, EL>, Tail> 
00665                                                                   Units;
00666       typedef BSUtilities::Rational<N, D> Power;
00667   };
00668 
00670 
00672 template<class U> struct CheckBoolProperty;
00673 
00675 
00678 template<class GT, class U, class Tail, class ST>
00679   struct 
00680       CheckBoolProperty<Loki::Typelist<NonPrefixable<GT, U, ST>, Tail> >
00681   {
00686     static bool is_SI (void) 
00687       {return ((NonPrefixable<GT, U, ST>::Is_SI ()
00688                         && CheckBoolProperty<Tail>::is_SI ()) ? 1 : 0);}
00693     static bool is_exact (void) 
00694       {return ((NonPrefixable<GT, U, ST>::Is_exact () 
00695                      && CheckBoolProperty<Tail>::is_exact ()) ? 1 : 0);}
00696   };
00697   
00699 
00702 template<class GT, class U, class P, class Tail, class ST>
00703   struct 
00704     CheckBoolProperty<Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, P>,
00705                                                                  Tail> >
00706   {
00711     static bool is_SI (void) 
00712       {return ((Prefixable<GT, U, ST>::Is_SI () 
00713                        && CheckBoolProperty<Tail>::is_SI ()) ? 1 : 0);}
00718     static bool is_exact (void) 
00719       {return ((Prefixable<GT, U, ST>::Is_exact () 
00720                      && CheckBoolProperty<Tail>::is_exact ()) ? 1 : 0);}
00721   };
00722 
00724 
00727 template<class GT, class EL, class UL, class Tail, class ST>
00728   struct 
00729     CheckBoolProperty<Loki::Typelist<Composed<Compound<GT, EL, ST>, UL>,
00730                                                                  Tail> >
00731   {
00736     static bool is_SI (void) 
00737       {return ((Composed<Compound<GT, EL, ST>, UL>::Is_SI () 
00738                        && CheckBoolProperty<Tail>::is_SI ()) ? 1 : 0);}
00743     static bool is_exact (void) 
00744       {return ((Composed<Compound<GT, EL, ST>, UL>::Is_exact () 
00745                      && CheckBoolProperty<Tail>::is_exact ()) ? 1 : 0);}
00746   };
00747 
00751 template<>
00752   struct CheckBoolProperty<Loki::NullType>
00753   {
00754     static bool is_SI (void) {return true;}
00755     static bool is_exact (void) {return true;}
00756   };
00757 
00759 
00762 template<class UL, class UR, class ST = double> class ComposedStandard;
00763 
00765 
00770 template<class U, class UTail, long N, long D, class RTail, class ST>
00771   class ComposedStandard<Loki::Typelist<U, UTail>, 
00772                  Loki::Typelist<BSUtilities::Rational<N, D>, RTail>, ST>
00773   {
00774     public:
00775       static ST StandardRatio (void)
00776         {return std::pow(U::standardRatio (),
00777              static_cast<double>(N)/static_cast<double>(D)) *
00778                   ComposedStandard<UTail, RTail, ST>::StandardRatio ();}
00779   };
00780 
00782 
00784 template<class U, long N, long D, class ST>
00785   class ComposedStandard<Loki::Typelist<U, Loki::NullType>, 
00786         Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType>, ST>
00787   {
00788     public:
00789       static ST StandardRatio (void)
00790         {return std::pow(U::standardRatio (),
00791                         static_cast<double>(N)/static_cast<double>(D));}
00792   };
00793 
00795 
00798 template<class Ul, class RL> class ComposedStrings;
00799 
00801 
00803 template<class U, long N, long D>
00804   class ComposedStrings<Loki::Typelist<U, Loki::NullType>, 
00805            Loki::Typelist<BSUtilities::Rational<N, D>, Loki::NullType> >
00806   {
00807     public:
00808       static std::string Name (void)
00809        {return U::Name ()
00810          + "^(" + BSUtilities::Conversion<long>::to_string(N) 
00811              + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00812 
00813       static std::string Symbol (void)
00814        {return U::Symbol ()
00815          + "^(" + BSUtilities::Conversion<long>::to_string(N) 
00816              + "/" + BSUtilities::Conversion<long>::to_string(D) + ")";}
00817   };
00818 
00820 
00823 template<class U, long N>
00824   class ComposedStrings<Loki::Typelist<U, Loki::NullType>, 
00825               Loki::Typelist<BSUtilities::Rational<N>, Loki::NullType> >
00826   {
00827     public:
00828       static std::string Name (void)
00829        {return U::Name ()
00830          + "^" + BSUtilities::Conversion<long>::to_string(N);}
00831 
00832       static std::string Symbol (void)
00833        {return U::Symbol ()
00834          + "^" + BSUtilities::Conversion<long>::to_string(N);}
00835   };
00836 
00838 
00840 template<class U, class UTail, long N, long D, class RTail>
00841   class ComposedStrings<Loki::Typelist<U, UTail>, 
00842                     Loki::Typelist<BSUtilities::Rational<N, D>, RTail> >
00843   {
00844     public:
00845       static const std::string Name (void)
00846         {return U::Name ()
00847           + "^(" + BSUtilities::Conversion<long>::to_string(N) 
00848               + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00849                               + ComposedStrings<UTail, RTail>::Name ();}
00850 
00851       static const std::string Symbol (void)
00852         {return U::Symbol ()
00853           + "^(" + BSUtilities::Conversion<long>::to_string(N) 
00854               + "/" + BSUtilities::Conversion<long>::to_string(D) + ")"
00855                             + ComposedStrings<UTail, RTail>::Symbol ();}
00856   };
00857 
00859 
00861 template<class U, class UTail, long N, class RTail>
00862   class ComposedStrings<Loki::Typelist<U, UTail>, 
00863                    Loki::Typelist<BSUtilities::Rational<N, 1L>, RTail> >
00864   {
00865     public:
00866       static const std::string Name (void)
00867         {return U::Name ()
00868           + "^" + BSUtilities::Conversion<long>::to_string(N) 
00869                               + ComposedStrings<UTail, RTail>::Name ();}
00870 
00871       static const std::string Symbol (void)
00872         {return U::Symbol ()
00873           + "^" + BSUtilities::Conversion<long>::to_string(N) + " "
00874                             + ComposedStrings<UTail, RTail>::Symbol ();}
00875   };
00876 
00878 
00880 template<class U, class UTail, class RTail>
00881   class ComposedStrings<Loki::Typelist<U, UTail>, 
00882                   Loki::Typelist<BSUtilities::Rational<1L, 1L>, RTail> >
00883   {
00884     public:
00885       static const std::string Name (void)
00886         {return U::Name () + ComposedStrings<UTail, RTail>::Name ();}
00887 
00888       static const std::string Symbol (void)
00889         {return U::Symbol () + " "
00890                             + ComposedStrings<UTail, RTail>::Symbol ();}
00891   };
00892 
00893 
00895 
00903 template<class GT, class U, class UTail, class CUL, class ST>
00904   class Composed<Compound<GT, CUL, ST>, Loki::Typelist<U, UTail> > 
00905                                          : public Compound<GT, CUL, ST>
00906   {
00907     private:
00908       typedef Loki::Typelist<U, UTail> List;
00909       typedef Composed<Compound<GT, CUL, ST>, List> Unit;
00910       typedef Compound<GT, CUL, ST> Comp;
00911 
00912     public:
00914 /*  static access
00915 */
00916       static bool Is_SI (void) 
00917                              {return CheckBoolProperty<List>::is_SI ();}
00918 
00920 
00922       bool is_SI (void) const {return Is_SI ();}
00923 
00925 
00927       static bool Is_exact (void) 
00928                           {return CheckBoolProperty<List>::is_exact ();}
00929 
00931 
00933       bool is_exact (void) const {return Is_exact ();}
00934 
00936 
00939       static ST standardRatio (void) 
00940         {return ComposedStandard<List,
00941                   typename Comp::Powers::Result, ST>::StandardRatio ();}
00942 
00944 
00946       static ST Standard (const ST value)
00947                                       {return value * standardRatio ();}
00948 
00950 
00952       ST standard (const ST &value) const {return Standard (value);}
00953 
00955 /*  static access
00956 */
00957       static ST Reverse (const ST value)
00958                                       {return value / standardRatio ();}
00959 
00961 /*  dynamic access
00962 */
00963       ST reverse (const ST &value) const {return Reverse (value);}
00964 
00966 /*  direct static access to be used if type of unit is known at 
00967     compile time;
00968     must not be a static const data member, since it requires access
00969     to the name values of the individual elementary units; they may 
00970     not be available yet when they are needed here.
00971 */
00972         static std::string Name (void)
00973           {return ComposedStrings<List, 
00974                             typename Comp::Powers::Result>::Name ();}
00975 
00977 
00980       inline const std::string name (void) const {return Name ();}
00981 
00983 /*  direct static access to be used if type of unit is known at 
00984     compile time;
00985     must not be a static const data member, since it requires access
00986     to the symbol values of the individual elementary units; they may 
00987     not be available yet when they are needed here.
00988 */
00989         static std::string Symbol (void)
00990           {return ComposedStrings<List, 
00991                              typename Comp::Powers::Result>::Symbol ();}
00992 
00994 
00997       inline const std::string symbol (void) const {return Symbol ();}
00998 
00999   };
01000 
01002 template<class UList, class CEList> struct GenComposedList;
01003 
01005 template<class GT, class U, class UTail, class ST>
01006   struct GenComposedList<Loki::Typelist<NonPrefixable<GT, U, ST>, 
01007                                                  UTail>, Loki::NullType>
01008   {
01009       typedef 
01010         Loki::Typelist<Loki::Typelist<NonPrefixable<GT, U, ST>, 
01011                                                         Loki::NullType>,
01012           typename GenComposedList<UTail, Loki::NullType>::Result> 
01013                                                                  Result;
01014   };
01015 
01016 template<class GT, class U, class P, class UTail, class ST>
01017   struct GenComposedList< 
01018     Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, P>, UTail>, 
01019                                                          Loki::NullType>
01020   {
01021       typedef 
01022         Loki::Typelist<Loki::Typelist<Prefixed<Prefixable<GT, U, ST>, 
01023                                                     P>, Loki::NullType>,
01024           typename GenComposedList<UTail, Loki::NullType>::Result> 
01025                                                                  Result;
01026   };
01027 
01028 template<class BC, class EL, class UTail>
01029   struct GenComposedList<Loki::Typelist<Composed<BC, EL>, UTail>, 
01030                                                          Loki::NullType>
01031   {
01032       typedef Loki::Typelist<Loki::Typelist<Composed<BC, EL>, 
01033                                                         Loki::NullType>,
01034         typename GenComposedList<UTail, Loki::NullType>::Result> Result;
01035   };
01036 
01038 template<>
01039   struct GenComposedList<Loki::NullType, Loki::NullType>
01040   {
01041     typedef Loki::NullType Result;
01042   };
01043 
01045 template<class GT1, class U, 
01046                           class U1, class UTail, class ELTail, class ST>
01047   struct GenComposedList<NonPrefixable<GT1, U1, ST>, 
01048                       Loki::Typelist<Loki::Typelist<U, UTail>, ELTail> >
01049   {
01050      typedef Loki::Typelist<Loki::Typelist<NonPrefixable<GT1, U1, ST>, 
01051         Loki::Typelist<U, UTail> >, 
01052           typename GenComposedList<NonPrefixable<GT1, U1, ST>, 
01053                                                ELTail> ::Result> Result;
01054   };
01055 
01056 template<class GT, class U, class ST>
01057   struct GenComposedList<NonPrefixable<GT, U, ST>, Loki::NullType>
01058   {
01059       typedef Loki::NullType Result;
01060   };
01061 
01063 template<class GT1, 
01064       class U, class U1, class P, class UTail, class ELTail, class ST>
01065   struct GenComposedList<Prefixed<Prefixable<GT1, U1, ST>, P>, 
01066                       Loki::Typelist<Loki::Typelist<U, UTail>, ELTail> >
01067   {
01068      typedef 
01069        Loki::Typelist<Loki::Typelist<Prefixed<Prefixable<GT1, U1, ST>, 
01070          P>, Loki::Typelist<U, UTail> >, 
01071            typename GenComposedList<Prefixed<Prefixable<GT1, U1, ST>, 
01072                                             P>, ELTail>::Result> Result;
01073   };
01074 
01075 template<class GT, class U, class P, class ST>
01076   struct 
01077      GenComposedList<Prefixed<Prefixable<GT, U, ST>, P>, Loki::NullType>
01078   {
01079       typedef Loki::NullType Result;
01080   };
01081 
01083 template<class U, class BC1, class EL1, class UTail, class ELTail>
01084   struct GenComposedList<Composed<BC1, EL1>, 
01085                       Loki::Typelist<Loki::Typelist<U, UTail>, ELTail> >
01086   {
01087     typedef Loki::Typelist<Loki::Typelist<Composed<BC1, EL1>, 
01088       Loki::Typelist<U, UTail> >, typename GenComposedList< 
01089                             Composed<BC1, EL1>, ELTail>::Result> Result;
01090   };
01091 
01092 template<class BC1, class EL1>
01093   struct GenComposedList<Composed<BC1, EL1>, Loki::NullType>
01094   {
01095       typedef Loki::NullType Result;
01096   };
01097 
01099 template<class GT1, 
01100   class U, class U1, class UTail, class U1Tail, class ELTail, class ST>
01101   struct GenComposedList<Loki::Typelist<NonPrefixable<GT1, U1, ST>, 
01102                                                UTail>, 
01103                      Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >
01104   {
01105       typedef typename 
01106         BSUtilities::Concatenate<typename GenComposedList< 
01107           NonPrefixable<GT1, U1, ST>, 
01108             Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >::Result,
01109             typename GenComposedList<UTail, 
01110               Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> 
01111                                               >::Result>::Result Result;
01112   };
01113 
01115 template<class GT1, class P,
01116   class U, class U1, class UTail, class U1Tail, class ELTail, class ST>
01117   struct GenComposedList<Loki::Typelist<Prefixed<Prefixable<GT1, U1, 
01118                                       ST>, P>, UTail>, 
01119                      Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >
01120   {
01121       typedef typename BSUtilities::Concatenate<typename 
01122         GenComposedList<Prefixed<Prefixable<GT1, U1, ST>, P>, 
01123           Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >::Result,
01124             typename GenComposedList<UTail,
01125               Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> 
01126                                               >::Result>::Result Result;
01127   };
01128 
01130 template<class U, 
01131   class BC1, class EL1, class UTail, class U1Tail, class ELTail>
01132   struct GenComposedList<Loki::Typelist<Composed<BC1, EL1>, UTail>, 
01133                      Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >
01134   {
01135      typedef typename 
01136        BSUtilities::Concatenate<typename GenComposedList< 
01137          Composed<BC1, EL1>, 
01138             Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >::Result,
01139            typename GenComposedList<UTail, 
01140                                Loki::Typelist<Loki::Typelist<U, U1Tail>,
01141                                       ELTail> >::Result>::Result Result;
01142   };
01143 
01145 template<class U, class U1Tail, class ELTail>
01146   struct GenComposedList<Loki::NullType, 
01147                      Loki::Typelist<Loki::Typelist<U, U1Tail>, ELTail> >
01148   {
01149       typedef Loki::NullType Result;
01150   };
01151 
01153 template<class CEL, class ST = double> struct ExpandCompoundElementList;
01154 
01155 template<class GT, class UHead, class UTail, long N, long D, 
01156                                                  class CETail, class ST>
01157   struct ExpandCompoundElementList< 
01158     Loki::Typelist<CompoundElement<GT, Loki::Typelist<UHead, UTail>, 
01159                          BSUtilities::Rational<N, D>, ST>, CETail>, ST>
01160   {
01161       typedef typename GenComposedList<typename CompoundElement<GT, 
01162         Loki::Typelist<UHead, UTail>, 
01163           BSUtilities::Rational<N, D>, ST>::Units,
01164             typename ExpandCompoundElementList<CETail>::Result>::Result 
01165                                                                  Result;
01166   };
01167 
01168 template<>
01169   struct ExpandCompoundElementList<Loki::NullType>
01170   {
01171       typedef Loki::NullType Result;
01172   };
01173 
01174 template<class C, class CEList> struct GenComposedUnits;
01175 
01176 template<class GT, class EList, class CELHead, class CELTail, class ST>
01177   struct GenComposedUnits<Compound<GT, EList, ST>, 
01178                                       Loki::Typelist<CELHead, CELTail> >
01179   {
01180       typedef Loki::Typelist<Composed<Compound<GT, EList, ST>, CELHead>,
01181         typename GenComposedUnits<Compound<GT, EList, ST>, 
01182                                                CELTail>::Result> Result;
01183   };
01184           
01185 template<class GT, class EList, class ST>
01186   struct GenComposedUnits<Compound<GT, EList, ST>, Loki::NullType>
01187   {
01188       typedef Loki::NullType Result;
01189   };
01190 
01192 
01194 template<class EL> struct GenPowers;
01195 
01197 
01201 template<class EHead, class ETail>
01202   struct GenPowers<Loki::Typelist<EHead, ETail> >
01203   {
01204     typedef Loki::Typelist<typename EHead::Power, 
01205                               typename GenPowers<ETail>::Result> Result;
01206   };
01207 
01209 
01214 template<class EHead>
01215   struct GenPowers<Loki::Typelist<EHead, Loki::NullType> >
01216   {
01217     typedef 
01218            Loki::Typelist<typename EHead::Power, Loki::NullType> Result;
01219   };
01220 
01221           
01222 
01224 //
01225 //  template Compound
01226 //  a unit compounded from one or more base units
01227 //
01229 
01231 
01239 template<class GT, class UHead, class UTail, 
01240   long N, long D, class Tail, class ST> 
01241   class Compound<GT, Loki::Typelist<CompoundElement<GT, 
01242         Loki::Typelist<UHead, UTail>, BSUtilities::Rational<N, D>, ST>, 
01243                                         Tail>, ST> : public Unit<GT, ST>
01244   {
01245     private:
01246       typedef 
01247         Loki::Typelist<CompoundElement<GT, Loki::Typelist<UHead, UTail>,
01248                    BSUtilities::Rational<N, D>, ST >, Tail> ElementList;
01249 
01250     public:
01251       typedef GenPowers<ElementList> Powers;
01252 
01253       typedef typename 
01254         GenComposedUnits<Compound<GT, ElementList, ST>, typename
01255           ExpandCompoundElementList<ElementList>::Result>::Result Units;
01256   };
01257 
01258 }
01259 
01260 #endif /* _Unit_h */

Generated on Sun Jan 15 13:58:00 2006 for Quantity by doxygen 1.3.6