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

QuantityCluster.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2003-2004, Bernd Speiser */
00006 /* This file is part of Quantity.
00007 
00008 Quantity is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 Quantity is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017   
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00021 02111-1307, USA.
00022 */
00023 
00024 #ifndef _QuantityCluster_h
00025 #define _QuantityCluster_h
00026 
00027 #include "Quantity/Quantity.h"
00028 
00029 #include "HierarchyGenerators.h"
00030 
00031 #include <vector>
00032 
00033 namespace Quantities {
00034 
00036 //
00037 //  Helper classes and structs for vectors
00038 //
00040 
00042 
00046 class QuantityVectorOutOfBounds {};
00047 
00049 //
00050 //  the QuantityVector abstract base class
00051 //
00053 
00055 
00058 template<class Q> class QuantityVector;
00059 
00061 
00065 template<class GT, class Head, class Tail, class DU, class ST>
00066   class 
00067        QuantityVector<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST> >
00068   {
00069     private:
00071       typedef Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST> Q;
00072   };
00073 
00075 //
00076 //  the VariableVector 
00077 //
00079 
00081 
00085 template<class PQ, class SU = typename PQ::DefaultUnit::Unit> 
00086                                                    class VariableVector;
00087 
00089 
00093 template<class GT, class Head, class Tail, class DU, class SU, class ST>
00094   class 
00095     VariableVector<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, SU>
00096       : public 
00097         QuantityVector<Quantity<GT, 
00098                                    Loki::Typelist<Head, Tail>, DU, ST> >
00099   {
00100     private:
00102       typedef typename 
00103                Units::CheckUnit<Units::Unit<GT, ST>, SU>::Check Checked;
00104 
00106       typedef Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST> PQ;
00107 
00108     public:
00110       typedef 
00111         Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, 
00112                                                                   SU> V;
00113 
00115       typedef SU Unit;
00116 
00117     protected:
00119       std::vector<ST> values;
00120 
00121     public:
00123       VariableVector (void) {}
00124 
00126 
00131     template<class NU>
00132       VariableVector (const VariableVector<PQ, NU> &new_vector) 
00133       {
00134         SU unit;
00135         int length = new_vector.length ();
00136         values.reserve (length);
00137 
00138         for (int i = 0; i < length; i++)
00139           values.push_back (new_vector[i].value (unit));
00140       }
00141 
00143 
00147       int length (void) const {return values.size ();}
00148 
00150 
00154       template<template<class, class> class Q1, class GT1, class Head1, 
00155                            class Tail1, class DU1, class SU1, class ST1>
00156         void add (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, 
00157                                           DU1, ST1>, SU1> &new_quantity)
00158           {values.push_back (SU::Reverse
00159             (CheckAgainstAllUnits<typename Q1<Quantity<GT1,
00160                     Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Unit,
00161               typename Loki::TL::Append<Loki::Typelist<Head, Tail>,
00162                 Units::NonPrefixable<typename Q1<Quantity<GT1,
00163                   Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Type,
00164                     Units::GenericUnit, ST> >::Result >::RET::Standard 
00165                                          (new_quantity.value ())));}
00166 
00168 
00172       template<template<class, class> class Q1, class GT1, class Head1, 
00173                            class Tail1, class DU1, class SU1, class ST1>
00174         void add (const Q1<Quantity<GT1, Loki::Typelist<Head1, Tail1>, 
00175                          DU1, ST1>, SU1> &new_quantity, const int index)
00176           {if (index >= 0 && index < length ())
00177             {typename std::vector<ST>::iterator pos 
00178                                               = values.begin () + index;
00179               values.insert (pos, SU::Reverse
00180                 (CheckAgainstAllUnits<typename Q1<Quantity<GT1,
00181                     Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Unit,
00182                 typename Loki::TL::Append<Loki::Typelist<Head, Tail>,
00183                   Units::NonPrefixable<typename Q1<Quantity<GT1,
00184                     Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Type,
00185                       Units::GenericUnit, ST> >::Result >::RET::Standard
00186                                          (new_quantity.value ())));
00187             }
00188           else
00189             {throw QuantityVectorOutOfBounds();}
00190         }                                                    
00191 
00193 
00197       template<template<class, class> class Q1, class GT1, class Head1, 
00198                            class Tail1, class DU1, class SU1, class ST1>
00199         void replace (const Q1<Quantity<GT1, 
00200           Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1> 
00201                                          &new_quantity, const int index)
00202           {if (index >= 0 && index < length ())
00203             {values[index] = SU::Reverse
00204                 (CheckAgainstAllUnits<typename Q1<Quantity<GT1,
00205                     Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Unit,
00206                 typename Loki::TL::Append<Loki::Typelist<Head, Tail>,
00207                   Units::NonPrefixable<typename Q1<Quantity<GT1,
00208                     Loki::Typelist<Head1, Tail1>, DU1, ST1>, SU1>::Type,
00209                       Units::GenericUnit, ST> >::Result >::RET::Standard
00210                                            (new_quantity.value ()));
00211             }
00212           else
00213             {throw QuantityVectorOutOfBounds();}
00214         }                                                    
00215 
00217 
00219     void remove (const int index)
00220     {
00221       if (index >= 0 && index < length ())
00222       {
00223         typename std::vector<ST>::iterator pos 
00224                                               = values.begin () + index;
00225         values.erase (pos);
00226       }
00227       else
00228       {throw QuantityVectorOutOfBounds();}
00229     }                                                    
00230 
00232     void clear (void) {values.clear ();}
00233 
00235 
00237       V value (const int index) const
00238         {if (index >= 0 && index < length ())
00239           {return V (values[index]);}
00240          else
00241           {throw QuantityVectorOutOfBounds();}
00242         }                                                    
00243 
00245 
00248       V operator[] (const int index) const {return value (index);}
00249 
00251 
00255       template<class NU>
00256         Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, NU> 
00257           value (const int index, const NU &unit) const
00258                                         {return (value (index))(unit);}
00259 
00261 
00264       V max (void) const
00265         {
00266           ST max_val = values[0];
00267           typename std::vector<ST>::const_iterator index;
00268 
00269           for (index = values.begin (); index < values.end (); index++)
00270             max_val = ((max_val < *index) ? *index : max_val);
00271           
00272           return V (max_val);
00273         }
00274 
00276 
00279       template<class NU>
00280         Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, NU> 
00281                     max (const NU &unit) const {return (max ()) (unit);}
00282 
00284 
00287       V min (void) const
00288         {
00289           ST min_val = values[0];
00290           typename std::vector<ST>::const_iterator index;
00291 
00292           for (index = values.begin (); index < values.end (); index++)
00293             min_val = ((min_val < *index) ? min_val : *index);
00294           
00295           return V (min_val);
00296         }
00297 
00299 
00302       template<class NU>
00303         Variable<Quantity<GT, Loki::Typelist<Head, Tail>, DU, ST>, NU> 
00304                     min (const NU &unit) const {return (min ()) (unit);}
00305 
00306   };
00307 
00309 
00312 template<class L> class VariableVectorTuple;
00313 
00315 //
00316 //  helper classes and structs for the VariableVector tuples
00317 //
00319 
00321 
00326 template<class TL> struct GetVar;
00327 
00329 
00335 template<class Head, class Tail>
00336   struct GetVar<Loki::Typelist<Head, Tail> >
00337 {
00338   private:
00339     typedef typename GetVar<Tail>::Result L1;
00340 
00341   public:
00342     typedef Loki::Typelist<typename Head::V, L1> Result;
00343 };
00344 
00346 
00349 template<>
00350   struct GetVar<Loki::NullType>
00351 {
00352   typedef Loki::NullType Result;
00353 };
00354 
00356 
00359 template<int N, class L>
00360   class AddVal
00361   {
00362     public:
00364       static void addval (VariableVectorTuple<L> &tuple, 
00365         const typename VariableVectorTuple<L>::VariableTuple 
00366                                                             &new_values)
00367         {Loki::Field<N-1>(tuple.vectors).add 
00368                                          (Loki::Field<N-1>(new_values));
00369          AddVal<N-1, L>::addval (tuple, new_values);
00370         }
00371 
00373       static void addval (VariableVectorTuple<L> &tuple, 
00374         const typename VariableVectorTuple<L>::VariableTuple 
00375                                      &new_values, const int index)
00376         {Loki::Field<N-1>(tuple.vectors).add 
00377                                   (Loki::Field<N-1>(new_values), index);
00378          AddVal<N-1, L>::addval (tuple, new_values, index);
00379         }
00380   };
00381 
00383 
00386 template<class L>
00387   class AddVal<0, L>
00388   {
00389     public:
00390       static void addval (VariableVectorTuple<L> &,
00391              const typename VariableVectorTuple<L>::VariableTuple &) {};
00392 
00393       static void addval (VariableVectorTuple<L> &,
00394         const typename VariableVectorTuple<L>::VariableTuple &, 
00395                                                           const int) {};
00396   };
00397 
00399 
00402 template<int N, class L>
00403   class RemVal
00404   {
00405     public:
00407       static void remval (VariableVectorTuple<L> &tuple, 
00408                                                         const int index)
00409         {Loki::Field<N-1>(tuple.vectors).remove (index);
00410          RemVal<N-1, L>::remval (tuple, index);
00411         }
00412   };
00413 
00415 
00418 template<class L>
00419   class RemVal<0, L>
00420   {
00421     public:
00422       static void remval (VariableVectorTuple<L> &, const int) {};
00423   };
00424 
00426 
00429 template<int N, class L>
00430   class GetVal
00431   {
00432     public:
00434       static typename VariableVectorTuple<L>::VariableTuple getval 
00435         (const VariableVectorTuple<L> &tuple,
00436           typename VariableVectorTuple<L>::VariableTuple 
00437                                                &values, const int index)
00438         {Loki::Field<N-1>(values) 
00439                                = Loki::Field<N-1>(tuple.vectors)[index];
00440          return GetVal<N-1, L>::getval (tuple, values, index);
00441         }
00442   };
00443 
00445 
00448 template<class L>
00449   class GetVal<0, L>
00450   {
00451     public:
00452       static typename VariableVectorTuple<L>::VariableTuple getval 
00453         (const VariableVectorTuple<L> &,
00454           typename VariableVectorTuple<L>::VariableTuple 
00455                               &values, const int) {return values;}
00456   };
00457 
00459 //
00460 //  the VariableVector tuple
00461 //
00463 
00465 
00470 template<class LHead, class LTail>
00471   class VariableVectorTuple<Loki::Typelist<LHead, LTail> >
00472   {
00473   private:
00475     typedef Loki::Typelist<LHead, LTail> L;
00476 
00477     Loki::Tuple<L> vectors;
00478 
00479   public:
00481 
00485     typedef Loki::Tuple<typename GetVar<L>::Result> VariableTuple;
00486 
00488     int number (void) {return Loki::TL::Length<L>::value;}
00489 
00491 /*  all vectors have the same length, return value determined from
00492     first vector.
00493 */
00494     int length (void) {return Loki::Field<0>(vectors).length ();}
00495 
00496 
00498 /*  uses data from a VariableTuple; uses helper class AddVal.
00499 */
00500     void add (const VariableTuple &new_values)
00501     {
00502       AddVal<Loki::TL::Length<L>::value, L>::addval (*this, new_values);
00503     }
00504 
00506 /*  uses data from a VariableTuple; uses helper class AddVal.
00507 */
00508     void add (const VariableTuple &new_values, const int index)
00509     {
00510       AddVal<Loki::TL::Length<L>::value, L>::addval 
00511                                              (*this, new_values, index);
00512     }
00513 
00515 
00517     void remove (const int index)
00518     {
00519       RemVal<Loki::TL::Length<L>::value, L>::remval (*this, index);
00520     }
00521 
00523 
00526     template<int I>
00527       typename Loki::TL::TypeAt<L, I>::Result::V 
00528                                            value (const int index) const
00529                       {return (Loki::Field<I>((*this).vectors))[index];}
00530 
00532 
00551     template<int I, class NU>
00552       Variable<typename Loki::TL::TypeAt<L, I>::Result::V::PQ, NU> 
00553         value (const int index, const NU &unit) const
00554           {return 
00555                ((Loki::Field<I>((*this).vectors)).value (index))(unit);}
00556 
00558 
00562     VariableTuple operator[] (const int index) const
00563     {
00564       VariableTuple values;
00565       return GetVal<Loki::TL::Length<L>::value, L>::getval 
00566                                                  (*this, values, index);
00567     }
00568 
00570 
00572     VariableTuple values (const int index) const
00573                                                 {return (*this)[index];}
00574 
00576     template<int N, class L1> friend class AddVal;
00577      
00578     template<int N, class L1> friend class GetVal;
00579      
00580     template<int N, class L1> friend class RemVal;
00581      
00582     template<int N, class L1> friend class Copy;
00583      
00584     template<int N, class L1> friend class Assign;
00585      
00586   };
00587 
00588 }
00589 
00590 #endif /* _QuantityCluster */

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