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

QuantityCluster.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2003 - 2006, 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 #include "Quantity/Dedimensionalization.h"
00029 
00030 #include "HierarchyGenerators.h"
00031 
00032 #include "xmlwriter.h"
00033 #include "xmlReader.h"
00034 #include <tinyxml/tinyxml.h>
00035 
00036 #include <vector>
00037 
00038 namespace quantity {
00039 
00041 //
00042 //  the Vector abstract base class
00043 //
00045 
00047 
00050 template<class Q> class Vector;
00051 
00053 
00058 template<class DIM, class BT, class UL, class DU, class ST>
00059                             class Vector<Quantity<DIM, BT, UL, DU, ST> >
00060   {
00061     private:
00063       typedef Quantity<DIM, BT, UL, DU, ST> PQ;
00064 
00065     public:
00067       static const std::string TAG;
00068 
00070       static const std::string MTAG;
00072       static const std::string QTAG;
00074       static const std::string UTAG;
00076       static const std::string DTAG;
00078       static const std::string VTAG;
00079   };
00080 
00082 template<class DIM, class BT, class UL, class DU, class ST>
00083   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >::TAG
00084                                                      = "quantityVector";
00085 
00087 template<class DIM, class BT, class UL, class DU, class ST>
00088   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >
00089                                                         ::MTAG = "mode";
00090 
00092 template<class DIM, class BT, class UL, class DU, class ST>
00093   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >
00094                                                     ::QTAG = "quantity";
00095 
00097 template<class DIM, class BT, class UL, class DU, class ST>
00098   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >
00099                                                         ::UTAG = "unit";
00100 
00102 template<class DIM, class BT, class UL, class DU, class ST>
00103   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >
00104                                                        ::VTAG = "value";
00105 
00107 template<class DIM, class BT, class UL, class DU, class ST>
00108   const std::string Vector<Quantity<DIM, BT, UL, DU, ST> >
00109                                                         ::DTAG = "data";
00110 
00112 //
00113 //  the QuantityVector 
00114 //
00116 
00118 
00127 template<template<class, class, class> class M, class PQ, 
00128   class SU = typename PQ::DefaultUnit::Unit, 
00129     class DD = typename DefaultDedimensionalizer<PQ, SU>::F> 
00130                                                    class QuantityVector;
00131 
00133 
00138 template<template<class, class, class> class M, 
00139   long RL_N, long RL_D, long RM_N, long RM_D, 
00140     long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00141       long RA_N, long RA_D, long RLU_N, long RLU_D,
00142         class BT, class UL, class DU, class SU, class ST, class R, 
00143                                                    class DDH, class DDT>
00144   class QuantityVector<M, Quantity<dimension::Dimension<
00145     BSUtilities::Rational<RL_N, RL_D>,
00146       BSUtilities::Rational<RM_N, RM_D>,  
00147         BSUtilities::Rational<RT_N, RT_D>,
00148           BSUtilities::Rational<RE_N, RE_D>,
00149             BSUtilities::Rational<RTE_N, RTE_D>, 
00150               BSUtilities::Rational<RA_N, RA_D>,
00151                 BSUtilities::Rational<RLU_N, RLU_D> >, 
00152                   BT, UL, DU, ST>, SU, 
00153                            Loki::Functor<R, Loki::Typelist<DDH, DDT> > >
00154     : public 
00155       Vector<Quantity<dimension::Dimension<
00156         BSUtilities::Rational<RL_N, RL_D>,
00157           BSUtilities::Rational<RM_N, RM_D>,  
00158             BSUtilities::Rational<RT_N, RT_D>,
00159               BSUtilities::Rational<RE_N, RE_D>,
00160                 BSUtilities::Rational<RTE_N, RTE_D>, 
00161                   BSUtilities::Rational<RA_N, RA_D>,
00162                     BSUtilities::Rational<RLU_N, RLU_D> >, 
00163                                                        BT, UL, DU, ST> >
00164   {
00165       private:
00167 
00169         typedef dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>,
00170             BSUtilities::Rational<RM_N, RM_D>,  
00171               BSUtilities::Rational<RT_N, RT_D>,
00172                 BSUtilities::Rational<RE_N, RE_D>,
00173                   BSUtilities::Rational<RTE_N, RTE_D>, 
00174                     BSUtilities::Rational<RA_N, RA_D>,
00175                               BSUtilities::Rational<RLU_N, RLU_D> > DIM;
00176 
00178         typedef typename Loki::Typelist<DDH, DDT> DDL;
00179 
00181 
00188         typedef typename Loki::TL::TypeAt<DDL, 0>::Result DDP;
00189 
00191         typedef typename Loki::Functor<R, DDL> DD;
00192 
00194 
00197         typedef Quantity<DIM, BT, UL, DU, ST> ABQ;
00198 
00200       typedef Vector<Quantity<dimension::Dimension<
00201         BSUtilities::Rational<RL_N, RL_D>,
00202           BSUtilities::Rational<RM_N, RM_D>,  
00203             BSUtilities::Rational<RT_N, RT_D>,
00204               BSUtilities::Rational<RE_N, RE_D>,
00205                 BSUtilities::Rational<RTE_N, RTE_D>, 
00206                   BSUtilities::Rational<RA_N, RA_D>,
00207                     BSUtilities::Rational<RLU_N, RLU_D> >, 
00208                                                   BT, UL, DU, ST> > VEC;
00209 
00210     public:
00212 
00217       typedef ABQ PQ;
00218 
00220 
00223       typedef M<PQ, SU, DD> V;
00224 
00226 
00228       typedef ST StorageType;
00229 
00231       typedef typename unit::CheckUnit<unit::Unit<BT>, SU>::Check Unit;
00232 
00233     private:
00235         typedef typename BSUtilities::IF<BSUtilities::SameType
00236           <DD, typename DefaultDedimensionalizer<PQ, SU>::F>::sameType,
00237                                        DedimReturn<PQ, SU>, V>::RET DDR;
00238 
00240 
00244         static DDR defaultDedimensionalizer (DDP) {return DDR(ST(1.));}
00245 
00247 
00249         static const DD _defaultDD;
00250 
00252 
00260         DD _dedimensionalizer;
00261 
00263       std::vector<ST> _values;
00264 
00265     public:
00267       QuantityVector (void) {}
00268 
00270 
00276     template<class NU, class DD1>
00277       QuantityVector (const QuantityVector<M, PQ, NU, DD1> &new_vector) 
00278       {
00279         SU unit;
00280         int size = new_vector.size ();
00281         _values.reserve (size);
00282 
00283         for (int i = 0; i < size; i++)
00284           _values.push_back (new_vector[i].value (unit));
00285       }
00286 
00288 
00290       QuantityVector & operator= (const QuantityVector &new_vector)
00291       {
00292         if (this != &new_vector)
00293         {
00294           VEC::operator= (new_vector);
00295           _values = new_vector._values;
00296         }       
00297 
00298         return *this;
00299       }
00300 
00302 
00308     template<class NU, class DD1>
00309       QuantityVector & operator= 
00310                       (const QuantityVector<M, PQ, NU, DD1> &new_vector)
00311       {
00312         VEC::operator= (new_vector);
00313 
00314         SU unit;
00315 
00316         int size = new_vector.size ();
00317 
00318         _values.empty ();
00319 
00320         _values.reserve (size);
00321 
00322         for (int i = 0; i < size; i++)
00323           _values.push_back(new_vector[i].value (unit));
00324 
00325         return *this;
00326       }
00327 
00329 
00339     void save (BSUtilities::xmlw::XmlStream &os) const
00340     {
00341       os << BSUtilities::xmlw::tag (VEC::TAG)
00342          << BSUtilities::xmlw::attr (VEC::MTAG) << V::MODE
00343            << BSUtilities::xmlw::attr (VEC::QTAG) << PQ::Name ()
00344            << BSUtilities::xmlw::attr (VEC::UTAG) << SU::Name ();
00345 
00346       for (int i = 0; i < size (); i++)
00347          os << BSUtilities::xmlw::tag (VEC::DTAG) 
00348             << BSUtilities::xmlw::attr (VEC::VTAG) << _values[i] 
00349                                         << BSUtilities::xmlw::endtag ();
00350 
00351       os << BSUtilities::xmlw::endtag (VEC::TAG);
00352     }
00353 
00355 
00365     void load (const TiXmlHandle node)
00366     {
00367        TiXmlElement *element = node.Element();
00368         if (element
00369           && (element->ValueStr () == VEC::TAG)
00370                             && (element->Attribute(VEC::MTAG) == V::MODE))
00371         {
00372 // load Quantity
00373 // load unit
00374           TiXmlNode *child = 0;
00375 
00376           std::string value;
00377 
00378           while ((child = element->IterateChildren (VEC::DTAG, child)))
00379           {
00380             if ((child->ToElement ())->Attribute (VEC::VTAG))
00381             {
00382               value = (child->ToElement ())->Attribute (VEC::VTAG);
00383               _values.push_back 
00384                 (BSUtilities::Conversion<ST>::string_to(value));
00385             }
00386           }
00387         }
00388         else
00389           throw LoadError
00390                     ("error loading Vector: incorrect element");
00391 
00392     }
00393 
00395 
00397       bool operator== 
00398         (const QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD> 
00399                                                           &vector) const
00400       {
00401         return ((size () == vector.size ()) 
00402                                           && (_values == vector._values));
00403       }
00404 
00406 
00410       int size (void) const {return _values.size ();}
00411 
00413 
00419       template<template<class, class, class> class Q1, class BT1, 
00420         class DIM1, class UL1, class DU1, class SU1, class ST1, 
00421                                                               class DD1>
00422         void push_back (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, 
00423                                                 SU1, DD1> &new_quantity)
00424           {_values.push_back (Reverse<SU, ST>::VAL
00425             (Standardize<typename
00426               CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00427                                         UL1, DU1, ST1>, SU1, DD1>::Unit,
00428               typename Loki::TL::Append<UL, unit::NonPrefixable<BT1, 
00429                     unit::GenericUnit> >::Result >::RET, ST>::VAL
00430                                              (new_quantity.value ())));}
00431 
00433 
00437       template<template<class, class, class> class Q1, class BT1, 
00438         class DIM1, class UL1, class DU1, class SU1, class ST1, 
00439                                                               class DD1>
00440         void insert (const Q1<Quantity<DIM1, BT1, UL1,
00441                     DU1, ST1>, SU1, DD1> &new_quantity, const int index)
00442           {if (index >= 0 && index < size ())
00443             {typename std::vector<ST>::iterator pos 
00444                                              = _values.begin () + index;
00445               _values.insert (pos, Reverse<SU, ST>::VAL
00446                 (Standardize<typename
00447                    CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00448                                         UL1, DU1, ST1>, SU1, DD1>::Unit,
00449                   typename Loki::TL::Append<UL,
00450                     unit::NonPrefixable<BT1, 
00451                         unit::GenericUnit> >::Result >::RET, ST>::VAL
00452                                               (new_quantity.value ())));
00453             }
00454           else
00455             {throw VectorOutOfBounds();}
00456         }                                                    
00457 
00459 
00464       template<template<class, class, class> class Q1, class BT1, 
00465         class DIM1, class UL1, class DU1, class SU1, class ST1, 
00466                                                               class DD1>
00467         void replace 
00468           (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1, DD1> 
00469                                          &new_quantity, const int index)
00470           {if (index >= 0 && index < size ())
00471             {_values[index] = Reverse<SU, ST>::VAL
00472               (Standardize<typename
00473                 CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00474                                         UL1, DU1, ST1>, SU1, DD1>::Unit,
00475                 typename Loki::TL::Append<UL,
00476                   unit::NonPrefixable<BT1,
00477                       unit::GenericUnit> >::Result >::RET, ST>::VAL
00478                                                (new_quantity.value ()));
00479             }
00480           else
00481             {throw VectorOutOfBounds();}
00482         }                                                    
00483 
00485 
00487     void erase (const int index)
00488     {
00489       if (index >= 0 && index < size ())
00490       {
00491         typename std::vector<ST>::iterator pos 
00492                                               = _values.begin () + index;
00493         _values.erase (pos);
00494       }
00495       else
00496       {throw VectorOutOfBounds();}
00497     }                                                    
00498 
00500     void clear (void) {_values.clear ();}
00501 
00503 
00505     std::vector<ST> values (void) {return _values;}   
00506 
00508 
00510       V value (const int index) const
00511         {if (index >= 0 && index < size ())
00512           {return V (_values[index]);}
00513          else
00514           {throw VectorOutOfBounds();}
00515         }                                                    
00516 
00518 
00521       V operator[] (const int index) const {return value (index);}
00522 
00524 
00529       template<class NU>
00530         M<Quantity<DIM, BT, UL, DU, ST>, NU, 
00531                            typename DefaultDedimensionalizer<PQ, NU>::F>
00532           value (const int index, const NU &unit) const
00533                                         {return (value (index))(unit);}
00534 
00536 
00539       V max (void) const
00540         {
00541           ST max_val = _values[0];
00542           typename std::vector<ST>::const_iterator index;
00543 
00544           for (index = _values.begin (); index < _values.end (); 
00545                                                                 index++)
00546             max_val = ((max_val < *index) ? *index : max_val);
00547           
00548           return V (max_val);
00549         }
00550 
00552 
00556       template<class NU>
00557         M<Quantity<DIM, BT, UL, DU, ST>, NU, 
00558                            typename DefaultDedimensionalizer<PQ, NU>::F>
00559                     max (const NU &unit) const {return (max ()) (unit);}
00560 
00562 
00565       V min (void) const
00566         {
00567           ST min_val = _values[0];
00568           typename std::vector<ST>::const_iterator index;
00569 
00570           for (index = _values.begin (); index < _values.end (); 
00571                                                                 index++)
00572             min_val = ((min_val < *index) ? min_val : *index);
00573           
00574           return V (min_val);
00575         }
00576 
00578 
00581       template<class NU>
00582         M<Quantity<DIM, BT, UL, DU, ST>, NU, 
00583                            typename DefaultDedimensionalizer<PQ, NU>::F>
00584                     min (const NU &unit) const {return (min ()) (unit);}
00585 
00586   };
00587 
00589 
00592 template<class L> class QuantityVectorTuple;
00593 
00595 //
00596 //  helper classes and structs for the QuantityVector tuples
00597 //
00599 
00601 
00606 template<class TL> struct GetVar;
00607 
00609 
00615 template<class Head, class Tail>
00616   struct GetVar<Loki::Typelist<Head, Tail> >
00617 {
00618   private:
00619     typedef typename GetVar<Tail>::Result L1;
00620 
00621   public:
00622     typedef Loki::Typelist<typename Head::V, L1> Result;
00623 };
00624 
00626 
00629 template<>
00630   struct GetVar<Loki::NullType>
00631 {
00632   typedef Loki::NullType Result;
00633 };
00634 
00636 
00639 template<int N, class L>
00640   class AddVal
00641   {
00642     public:
00644       static void addval (QuantityVectorTuple<L> &tuple, 
00645         const typename QuantityVectorTuple<L>::QTuple &new_values)
00646         {Loki::Field<N-1>(tuple.vectors).push_back 
00647                                          (Loki::Field<N-1>(new_values));
00648          AddVal<N-1, L>::addval (tuple, new_values);
00649         }
00650 
00652       static void addval (QuantityVectorTuple<L> &tuple, 
00653         const typename QuantityVectorTuple<L>::QTuple 
00654                                      &new_values, const int index)
00655         {Loki::Field<N-1>(tuple.vectors).insert 
00656                                   (Loki::Field<N-1>(new_values), index);
00657          AddVal<N-1, L>::addval (tuple, new_values, index);
00658         }
00659   };
00660 
00662 
00665 template<class L>
00666   class AddVal<0, L>
00667   {
00668     public:
00669       static void addval (QuantityVectorTuple<L> &,
00670              const typename QuantityVectorTuple<L>::QTuple &) {};
00671 
00672       static void addval (QuantityVectorTuple<L> &,
00673         const typename QuantityVectorTuple<L>::QTuple &, const int) {};
00674   };
00675 
00677 
00680 template<int N, class L>
00681   class EraVal
00682   {
00683     public:
00685       static void eraval (QuantityVectorTuple<L> &tuple, 
00686                                                         const int index)
00687         {Loki::Field<N-1>(tuple.vectors).erase (index);
00688          EraVal<N-1, L>::eraval (tuple, index);
00689         }
00690   };
00691 
00693 
00696 template<class L>
00697   class EraVal<0, L>
00698   {
00699     public:
00700       static void eraval (QuantityVectorTuple<L> &, const int) {};
00701   };
00702 
00704 
00707 template<int N, class L>
00708   class GetVal
00709   {
00710     public:
00712       static typename QuantityVectorTuple<L>::QTuple getval 
00713         (const QuantityVectorTuple<L> &tuple,
00714           typename QuantityVectorTuple<L>::QTuple 
00715                                                &values, const int index)
00716         {Loki::Field<N-1>(values) 
00717                                = Loki::Field<N-1>(tuple.vectors)[index];
00718          return GetVal<N-1, L>::getval (tuple, values, index);
00719         }
00720   };
00721 
00723 
00726 template<class L>
00727   class GetVal<0, L>
00728   {
00729     public:
00730       static typename QuantityVectorTuple<L>::QTuple getval 
00731         (const QuantityVectorTuple<L> &,
00732           typename QuantityVectorTuple<L>::QTuple 
00733                               &values, const int) {return values;}
00734   };
00735 
00737 
00739 template<int N, class L>
00740   class SaveVecType
00741   {
00742     public:
00743       static void saveVecType 
00744         (const QuantityVectorTuple<L> &tuple, 
00745                                        BSUtilities::xmlw::XmlStream &os)
00746       {
00747         os << BSUtilities::xmlw::attr 
00748              (QuantityVectorTuple<L>::MTAG
00749                           + BSUtilities::Conversion<int>::to_string (N))
00750            << Loki::TL::TypeAt<L, N-1>::Result::V::MODE
00751            << BSUtilities::xmlw::attr (QuantityVectorTuple<L>::QTAG 
00752                           + BSUtilities::Conversion<int>::to_string (N))
00753            << Loki::TL::TypeAt<L, N-1>::Result::PQ::Name ()
00754            << BSUtilities::xmlw::attr (QuantityVectorTuple<L>::UTAG 
00755                           + BSUtilities::Conversion<int>::to_string (N))
00756                      << Loki::TL::TypeAt<L, N-1>::Result::Unit::Name ();
00757         SaveVecType<N-1, L>::saveVecType (tuple, os);
00758       }
00759   };
00760 
00762 
00764 template<class L>
00765   class SaveVecType<0, L>
00766   {
00767     public:
00768       static void saveVecType 
00769         (const QuantityVectorTuple<L> &, 
00770                                       BSUtilities::xmlw::XmlStream &) {}
00771   };
00772 
00774 
00777 template<int N, class L>
00778   class SaveVec
00779   {
00780     public:
00781       static void saveVec 
00782         (const QuantityVectorTuple<L> &tuple, int index,
00783                                        BSUtilities::xmlw::XmlStream &os)
00784       {
00785         os << BSUtilities::xmlw::attr (QuantityVectorTuple<L>::VTAG 
00786                           + BSUtilities::Conversion<int>::to_string (N))
00787            << Loki::Field<N-1>(tuple.vectors)[index].value ();
00788         SaveVec<N-1, L>::saveVec (tuple, index, os);
00789       }
00790   };
00791 
00792 
00794 
00796 template<class L>
00797   class SaveVec<0, L>
00798   {
00799     public:
00800       static void saveVec 
00801         (const QuantityVectorTuple<L> &, int, 
00802                                       BSUtilities::xmlw::XmlStream &) {}
00803   };
00804 
00806 
00810 template<int N, class L>
00811   class CheckQuantities
00812   {
00813     public:
00814       static bool checkQuantities
00815         (const QuantityVectorTuple<L> &tuple, 
00816                                             const TiXmlElement *element)
00817       {
00818         if ((element->Attribute (QuantityVectorTuple<L>::QTAG 
00819                           + BSUtilities::Conversion<int>::to_string (N))
00820                        == Loki::TL::TypeAt<L, N-1>::Result::PQ::Name ())
00821           && (element->Attribute (QuantityVectorTuple<L>::UTAG 
00822                           + BSUtilities::Conversion<int>::to_string (N))
00823                     == Loki::TL::TypeAt<L, N-1>::Result::Unit::Name ())
00824           && (element->Attribute (QuantityVectorTuple<L>::MTAG 
00825                           + BSUtilities::Conversion<int>::to_string (N))
00826                           == Loki::TL::TypeAt<L, N-1>::Result::V::MODE))
00827           {return CheckQuantities<N-1, L>::checkQuantities 
00828                                                       (tuple, element);}
00829 
00830         else
00831           return false;
00832       }
00833   };
00834 
00836 
00838 template<class L>
00839   class CheckQuantities<0, L>
00840   {
00841     public:
00842       static bool checkQuantities 
00843         (const QuantityVectorTuple<L> &, const TiXmlElement *) 
00844                                                           {return true;}
00845   };
00846 
00848 
00851 template<int N, class L>
00852   class LoadVec
00853   {
00854     public:
00855       static void loadvec 
00856         (QuantityVectorTuple<L> &tuple, const TiXmlNode *child)
00857       {
00858         const TiXmlElement *element = child->ToElement();
00859 
00860         if (element->Attribute 
00861           (QuantityVectorTuple<L>::VTAG 
00862                          + BSUtilities::Conversion<int>::to_string (N)))
00863         {
00864 // check quantity type and skip if Empty!!!!!!!!!
00865 // also: read mode from MTAG
00866           Loki::Field<N-1>(tuple.vectors).push_back 
00867             (typename Loki::TL::TypeAt<L, N-1>::Result::V
00868               (BSUtilities::Conversion<typename Loki::TL::TypeAt<L, N-1>
00869                 ::Result::StorageType>::string_to
00870                   (element->Attribute (QuantityVectorTuple<L>::VTAG 
00871                       + BSUtilities::Conversion<int>::to_string (N)))));
00872           LoadVec<N-1, L>::loadvec (tuple, child);
00873         }
00874 
00875         else
00876           throw LoadError 
00877                 ("error loading QuantityVectorTuple: incorrect vector");
00878 
00879       }
00880   };
00881 
00883 
00885 template<class L>
00886   class LoadVec<0, L>
00887   {
00888     public:
00889       static void loadvec (QuantityVectorTuple<L> &, const TiXmlNode *)
00890                                                                       {}
00891   };
00892 
00894 
00896 template<int N, class L>
00897   class CmpVec
00898   {
00899     public:
00900       static bool cmpVec
00901         (const QuantityVectorTuple<L> &tuple1, 
00902                                    const QuantityVectorTuple<L> &tuple2)
00903       {
00904         if (Loki::Field<N-1>(tuple1.vectors) 
00905                                     == Loki::Field<N-1>(tuple2.vectors))
00906           return CmpVec<N-1, L>::cmpVec (tuple1, tuple2);
00907 
00908         else
00909           return false;
00910       }
00911   };
00912 
00914 
00917 template<class L>
00918   class CmpVec<0, L>
00919   {
00920     public:
00921       static bool cmpVec 
00922         (const QuantityVectorTuple<L> &, const QuantityVectorTuple<L> &)
00923                                                           {return true;}
00924   };
00925 
00927 /* primary template
00928 */
00929 template <class V, class QVT> struct CheckVariableInVectorTuple;
00930 
00932 
00934 template<template<class, class, class> class T, class V, class DIM, 
00935   class BT, class UL, class DU, class ST, class SU,  class DD, 
00936                                                             class LTail>
00937   struct CheckVariableInVectorTuple<V,
00938     Loki::Typelist<QuantityVector<T, Quantity <DIM, BT, UL, DU, ST>, 
00939                                                        SU, DD>, LTail> >
00940   {
00941     private:
00942       typedef typename BSUtilities::IF<BSUtilities::SameType<V,
00943         typename QuantityVector<T, Quantity<DIM, BT, UL, DU, ST>, 
00944                                                   SU, DD>::V>::sameType,
00945           QuantityVector<T, Quantity<DIM, BT, UL, DU, ST>, SU, DD>,
00946            typename CheckVariableInVectorTuple<V, LTail>::RET>::RET RET;
00947   };
00948 
00950 
00956 template<class V>
00957   struct CheckVariableInVectorTuple<V, Loki::NullType>
00958   {
00959     typedef VariableError<true> RET;
00960   };
00961 
00963 //
00964 //  the QuantityVector tuple
00965 //
00967 
00969 
00975 template<template<class, class, class> class T, class DIM, class BT, 
00976           class UL, class DU, class ST, class SU, class DD, class LTail>
00977   class QuantityVectorTuple<Loki::Typelist<
00978       QuantityVector<T, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
00979   {
00980   private:
00982     typedef Loki::Typelist<QuantityVector<T, 
00983                        Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> L;
00984 
00985     Loki::Tuple<L> vectors;
00986 
00987   public:
00989 
00993     typedef Loki::Tuple<typename GetVar<L>::Result> QTuple;
00994 
00996 
01001     void save (BSUtilities::xmlw::XmlStream &os) const
01002     {
01003       os << BSUtilities::xmlw::tag (TAG);
01004 
01005       SaveVecType<Loki::TL::Length<L>::value, L>::saveVecType 
01006                                                             (*this, os);
01007 
01008       for (int index = 0; index < size (); index++)
01009       {
01010         os << BSUtilities::xmlw::tag (QuantityVectorTuple<L>::DTAG);
01011         SaveVec<Loki::TL::Length<L>::value, L>::saveVec 
01012                                                      (*this, index, os);
01013         os << BSUtilities::xmlw::endtag (DTAG);
01014       }
01015 
01016       os << BSUtilities::xmlw::endtag (TAG);
01017     }
01018 
01020 
01030     void load (const TiXmlHandle node)
01031     {
01032        TiXmlElement *element = node.Element();
01033         if (element && (element->ValueStr () == TAG))
01034         {
01035           if(CheckQuantities<Loki::TL::Length<L>::value, L>
01036                                      ::checkQuantities (*this, element))
01037           {
01038             TiXmlNode *child = 0;
01039             
01040             TiXmlElement *element = node.Element();
01041 
01042             while ((child = element->IterateChildren (DTAG, child)))
01043               {LoadVec<Loki::TL::Length<L>::value, L>::loadvec 
01044                                                         (*this, child);}
01045           }
01046 
01047           else
01048             throw LoadError
01049               ("error loading QuantityVectorTuple: "
01050                                                 "incorrect attributes");
01051         }
01052 
01053         else
01054           throw LoadError
01055             ("error loading QuantityVectorTuple: incorrect element");
01056 
01057     }
01058 
01060 
01062       bool operator== (const QuantityVectorTuple &tuple) const
01063         {return CmpVec<Loki::TL::Length<L>::value, L>::cmpVec 
01064                                                         (*this, tuple);}
01065 
01067     int number (void) const {return Loki::TL::Length<L>::value;}
01068 
01070 /*  all vectors have the same size, return value determined from
01071     first vector.
01072 */
01073     int size (void) const {return Loki::Field<0>(vectors).size ();}
01074 
01075 
01077 /*  uses data from a QTuple; uses helper class AddVal.
01078 */
01079     void push_back (const QTuple &new_values)
01080     {
01081       AddVal<Loki::TL::Length<L>::value, L>::addval (*this, new_values);
01082     }
01083 
01085 /*  uses data from a QTuple; uses helper class AddVal.
01086 */
01087     void insert (const QTuple &new_values, const int index)
01088     {
01089       AddVal<Loki::TL::Length<L>::value, L>::addval 
01090                                              (*this, new_values, index);
01091     }
01092 
01094 
01096     void erase (const int index)
01097     {
01098       EraVal<Loki::TL::Length<L>::value, L>::eraval (*this, index);
01099     }
01100 
01102 
01105     template<int I>
01106       typename Loki::TL::TypeAt<L, I>::Result::V 
01107                                   value (const unsigned int index) const
01108                       {return (Loki::Field<I>((*this).vectors))[index];}
01109 
01111 
01130     template<int I, class NU>
01131       T<typename Loki::TL::TypeAt<L, I>::Result::V::PQ, NU, 
01132                          typename Loki::TL::TypeAt<L, I>::Result::V::DD>
01133         value (const int index, const NU &unit) const
01134           {return 
01135                ((Loki::Field<I>((*this).vectors)).value (index))(unit);}
01136 
01138 
01142     QTuple operator[] (const int index) const
01143     {
01144       QTuple values;
01145       return GetVal<Loki::TL::Length<L>::value, L>::getval 
01146                                                  (*this, values, index);
01147     }
01148 
01150 
01152     QTuple values (const int index) const {return (*this)[index];}
01153 
01155     template<int I>
01156       QuantityVector<T, typename Loki::TL::TypeAt<L, I>::Result::V::PQ,
01157         typename Loki::TL::TypeAt<L, I>::Result::V::Unit, 
01158           typename Loki::TL::TypeAt<L, I>::Result::V::DD>
01159                                      getVector (Loki::Int2Type<I>) const
01160       {return QuantityVector<T, 
01161         typename Loki::TL::TypeAt<L, I>::Result::V::PQ,
01162           typename Loki::TL::TypeAt<L, I>::Result::V::Unit, 
01163             typename Loki::TL::TypeAt<L, I>::Result::V::DD> 
01164                                      (Loki::Field<I>((*this).vectors));}
01165 
01167     template<int N, class L1> friend class AddVal;
01168      
01169     template<int N, class L1> friend class GetVal;
01170      
01171     template<int N, class L1> friend class EraVal;
01172      
01173     template<int N, class L1> friend class SaveVec;
01174      
01175     template<int N, class L1> friend class CmpVec;
01176      
01177     template<int N, class L1> friend class LoadVec;
01178      
01179     template<int N, class L1> friend class Copy;
01180      
01181     template<int N, class L1> friend class Assign;
01182 
01184       static const std::string TAG;
01185      
01187       static const std::string QTAG;
01188      
01190       static const std::string UTAG;
01191      
01193       static const std::string DTAG;
01194      
01196       static const std::string VTAG;
01197      
01199       static const std::string MTAG;
01200      
01201   };
01202 
01204 template<template<class, class, class> class M, class DIM, class BT, 
01205           class UL, class DU, class ST, class SU, class DD, class LTail>
01206   const std::string 
01207     QuantityVectorTuple<Loki::Typelist<
01208       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01209                                           ::TAG = "quantityVectorTuple";
01210 
01212 template<template<class, class, class> class M, class DIM, class BT, 
01213            class UL, class DU, class ST, class SU, class DD, class LTail>
01214   const std::string 
01215     QuantityVectorTuple<Loki::Typelist<
01216       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01217                                                     ::QTAG = "quantity";
01218 
01220 template<template<class, class, class> class M, class DIM, class BT, 
01221           class UL, class DU, class ST, class SU, class DD, class LTail>
01222   const std::string 
01223     QuantityVectorTuple<Loki::Typelist<
01224       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01225                                                         ::UTAG = "unit";
01226 
01228 template<template<class, class, class> class M, class DIM, class BT, 
01229           class UL, class DU, class ST, class SU, class DD, class LTail>
01230   const std::string 
01231     QuantityVectorTuple<Loki::Typelist<
01232       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01233                                                         ::DTAG = "data";
01234 
01236 template<template<class, class, class> class M, class DIM, class BT, 
01237           class UL, class DU, class ST, class SU, class DD, class LTail>
01238   const std::string 
01239     QuantityVectorTuple<Loki::Typelist<
01240       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01241                                                        ::VTAG = "value";
01242 
01244 template<template<class, class, class> class M, class DIM, class BT, 
01245           class UL, class DU, class ST, class SU, class DD, class LTail>
01246   const std::string 
01247     QuantityVectorTuple<Loki::Typelist<
01248       QuantityVector<M, Quantity<DIM, BT, UL, DU, ST>, SU, DD>, LTail> >
01249                                                        ::MTAG = "mode";
01250 
01251 }
01252 
01253 
01254 #endif /* _QuantityCluster */

Generated on Mon Feb 12 18:48:39 2007 for Quantity by doxygen 1.3.6