00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _QuantityCluster_h
00025 #define _QuantityCluster_h
00026
00027 #include "Quantity/Quantity.h"
00028
00029 #include "HierarchyGenerators.h"
00030
00031 #include "xmlwriter.h"
00032 #include "xmlReader.h"
00033 #include <tinyxml/tinyxml.h>
00034
00035 #include <vector>
00036
00037 namespace quantity {
00038
00040
00041
00042
00044
00046
00049 template<class Q> class QuantityVector;
00050
00052
00057 template<class DIM, class BT, class UL, class DU, class ST>
00058 class QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00059 {
00060 private:
00062 typedef Quantity<DIM, BT, UL, DU, ST> Q;
00063
00064 public:
00066 static const std::string TAG;
00067
00069 static const std::string IDTAG;
00071 static const std::string QTAG;
00073 static const std::string UTAG;
00075 static const std::string DTAG;
00077 static const std::string VTAG;
00078 };
00079
00081 template<class DIM, class BT, class UL, class DU, class ST>
00082 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >::TAG
00083 = "quantityVector";
00084
00086 template<class DIM, class BT, class UL, class DU, class ST>
00087 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00088 ::IDTAG = "ID";
00089
00091 template<class DIM, class BT, class UL, class DU, class ST>
00092 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00093 ::QTAG = "quantity";
00094
00096 template<class DIM, class BT, class UL, class DU, class ST>
00097 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00098 ::UTAG = "unit";
00099
00101 template<class DIM, class BT, class UL, class DU, class ST>
00102 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00103 ::VTAG = "value";
00104
00106 template<class DIM, class BT, class UL, class DU, class ST>
00107 const std::string QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00108 ::DTAG = "data";
00109
00111
00112
00113
00115
00117
00121 template<class PQ, class SU = typename PQ::DefaultUnit::Unit>
00122 class VariableVector;
00123
00125
00129 template<class BT, class DIM, class UL, class DU, class SU, class ST>
00130 class VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>
00131 : public QuantityVector<Quantity<DIM, BT, UL, DU, ST> >
00132 {
00133 private:
00135 typedef typename unit::CheckUnit<unit::Unit<BT>, SU>::Check Check;
00136
00137 public:
00139 typedef Quantity<DIM, BT, UL, DU, ST> PQ;
00140
00142 typedef Variable<Quantity<DIM, BT, UL, DU, ST>, SU> V;
00143
00145 typedef SU Unit;
00146
00147 protected:
00149 std::vector<ST> values;
00150
00151 public:
00153 VariableVector (void) {}
00154
00156
00161 template<class NU>
00162 VariableVector (const VariableVector<PQ, NU> &new_vector)
00163 {
00164 SU unit;
00165 int size = new_vector.size ();
00166 values.reserve (size);
00167
00168 for (int i = 0; i < size; i++)
00169 values.push_back (new_vector[i].value (unit));
00170 }
00171
00173
00182 void save (BSUtilities::xmlw::XmlStream &os) const
00183 {
00184 os << BSUtilities::xmlw::tag (TAG)
00185 << BSUtilities::xmlw::attr (IDTAG) << ID
00186 << BSUtilities::xmlw::attr (QTAG) << PQ::Name ()
00187 << BSUtilities::xmlw::attr (UTAG) << SU::Name ();
00188
00189 for (int i = 0; i < size (); i++)
00190 os << BSUtilities::xmlw::tag (DTAG)
00191 << BSUtilities::xmlw::attr (VTAG) << values[i]
00192 << BSUtilities::xmlw::endtag ();
00193
00194 os << BSUtilities::xmlw::endtag (TAG);
00195 }
00196
00198
00207 void load (const TiXmlHandle node)
00208 {
00209 TiXmlElement *element = node.Element();
00210 if (element
00211 && (element->ValueStr () == TAG)
00212 && (element->Attribute(IDTAG) == ID))
00213 {
00214
00215
00216 TiXmlNode *child = 0;
00217
00218 std::string value;
00219
00220 while (child = element->IterateChildren (DTAG, child))
00221 {
00222 if ((child->ToElement ())->Attribute (VTAG))
00223 {
00224 value = (child->ToElement ())->Attribute (VTAG);
00225 values.push_back
00226 (BSUtilities::Conversion<ST>::string_to(value));
00227 }
00228 }
00229 }
00230 else
00231 throw LoadError
00232 ("error loading QuantityVector: incorrect element");
00233
00234 }
00235
00237
00239 bool operator==
00240 (const VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>
00241 &vector) const
00242 {
00243 return ((size () == vector.size ())
00244 && (values == vector.values));
00245 }
00246
00248
00252 int size (void) const {return values.size ();}
00253
00255
00260 template<template<class, class> class Q1, class BT1, class DIM1,
00261 class UL1, class DU1, class SU1, class ST1>
00262 void push_back (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>,
00263 SU1> &new_quantity)
00264 {values.push_back (Reverse<SU>::VAL
00265 (Standardize<typename
00266 CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00267 UL1, DU1, ST1>, SU1>::Unit,
00268 typename Loki::TL::Append<UL, unit::NonPrefixable<BT1,
00269 unit::GenericUnit> >::Result >::RET>::VAL
00270 (new_quantity.value ())));}
00271
00273
00277 template<template<class, class> class Q1, class BT1, class DIM1,
00278 class UL1, class DU1, class SU1, class ST1>
00279 void insert (const Q1<Quantity<DIM1, BT1, UL1,
00280 DU1, ST1>, SU1> &new_quantity, const int index)
00281 {if (index >= 0 && index < size ())
00282 {typename std::vector<ST>::iterator pos
00283 = values.begin () + index;
00284 values.insert (pos, Reverse<SU>::VAL
00285 (Standardize<typename
00286 CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00287 UL1, DU1, ST1>, SU1>::Unit,
00288 typename Loki::TL::Append<UL,
00289 unit::NonPrefixable<BT1,
00290 unit::GenericUnit> >::Result >::RET>::VAL
00291 (new_quantity.value ())));
00292 }
00293 else
00294 {throw VectorOutOfBounds();}
00295 }
00296
00298
00303 template<template<class, class> class Q1, class BT1, class DIM1,
00304 class UL1, class DU1, class SU1, class ST1>
00305 void replace (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1>
00306 &new_quantity, const int index)
00307 {if (index >= 0 && index < size ())
00308 {values[index] = Reverse<SU>::VAL
00309 (Standardize<typename
00310 CheckAgainstAllUnits<typename Q1<Quantity<DIM1, BT1,
00311 UL1, DU1, ST1>, SU1>::Unit,
00312 typename Loki::TL::Append<UL,
00313 unit::NonPrefixable<BT1,
00314 unit::GenericUnit> >::Result >::RET>::VAL
00315 (new_quantity.value ()));
00316 }
00317 else
00318 {throw VectorOutOfBounds();}
00319 }
00320
00322
00324 void erase (const int index)
00325 {
00326 if (index >= 0 && index < size ())
00327 {
00328 typename std::vector<ST>::iterator pos
00329 = values.begin () + index;
00330 values.erase (pos);
00331 }
00332 else
00333 {throw VectorOutOfBounds();}
00334 }
00335
00337 void clear (void) {values.clear ();}
00338
00340
00342 V value (const int index) const
00343 {if (index >= 0 && index < size ())
00344 {return V (values[index]);}
00345 else
00346 {throw VectorOutOfBounds();}
00347 }
00348
00350
00353 V operator[] (const int index) const {return value (index);}
00354
00356
00360 template<class NU>
00361 Variable<Quantity<DIM, BT, UL, DU, ST>, NU>
00362 value (const int index, const NU &unit) const
00363 {return (value (index))(unit);}
00364
00366
00369 V max (void) const
00370 {
00371 ST max_val = values[0];
00372 typename std::vector<ST>::const_iterator index;
00373
00374 for (index = values.begin (); index < values.end (); index++)
00375 max_val = ((max_val < *index) ? *index : max_val);
00376
00377 return V (max_val);
00378 }
00379
00381
00384 template<class NU>
00385 Variable<Quantity<DIM, BT, UL, DU, ST>, NU>
00386 max (const NU &unit) const {return (max ()) (unit);}
00387
00389
00392 V min (void) const
00393 {
00394 ST min_val = values[0];
00395 typename std::vector<ST>::const_iterator index;
00396
00397 for (index = values.begin (); index < values.end (); index++)
00398 min_val = ((min_val < *index) ? min_val : *index);
00399
00400 return V (min_val);
00401 }
00402
00404
00407 template<class NU>
00408 Variable<Quantity<DIM, BT, UL, DU, ST>, NU>
00409 min (const NU &unit) const {return (min ()) (unit);}
00410
00412
00414 static const std::string ID;
00415
00416 };
00417
00419 template<class BT, class DIM, class UL, class DU, class SU, class ST>
00420 const std::string VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>::ID
00421 = "Variable";
00422
00424
00427 template<class L> class VariableVectorTuple;
00428
00430
00431
00432
00434
00436
00441 template<class TL> struct GetVar;
00442
00444
00450 template<class Head, class Tail>
00451 struct GetVar<Loki::Typelist<Head, Tail> >
00452 {
00453 private:
00454 typedef typename GetVar<Tail>::Result L1;
00455
00456 public:
00457 typedef Loki::Typelist<typename Head::V, L1> Result;
00458 };
00459
00461
00464 template<>
00465 struct GetVar<Loki::NullType>
00466 {
00467 typedef Loki::NullType Result;
00468 };
00469
00471
00474 template<int N, class L>
00475 class AddVal
00476 {
00477 public:
00479 static void addval (VariableVectorTuple<L> &tuple,
00480 const typename VariableVectorTuple<L>::VariableTuple
00481 &new_values)
00482 {Loki::Field<N-1>(tuple.vectors).push_back
00483 (Loki::Field<N-1>(new_values));
00484 AddVal<N-1, L>::addval (tuple, new_values);
00485 }
00486
00488 static void addval (VariableVectorTuple<L> &tuple,
00489 const typename VariableVectorTuple<L>::VariableTuple
00490 &new_values, const int index)
00491 {Loki::Field<N-1>(tuple.vectors).insert
00492 (Loki::Field<N-1>(new_values), index);
00493 AddVal<N-1, L>::addval (tuple, new_values, index);
00494 }
00495 };
00496
00498
00501 template<class L>
00502 class AddVal<0, L>
00503 {
00504 public:
00505 static void addval (VariableVectorTuple<L> &,
00506 const typename VariableVectorTuple<L>::VariableTuple &) {};
00507
00508 static void addval (VariableVectorTuple<L> &,
00509 const typename VariableVectorTuple<L>::VariableTuple &,
00510 const int) {};
00511 };
00512
00514
00517 template<int N, class L>
00518 class EraVal
00519 {
00520 public:
00522 static void eraval (VariableVectorTuple<L> &tuple,
00523 const int index)
00524 {Loki::Field<N-1>(tuple.vectors).erase (index);
00525 EraVal<N-1, L>::eraval (tuple, index);
00526 }
00527 };
00528
00530
00533 template<class L>
00534 class EraVal<0, L>
00535 {
00536 public:
00537 static void eraval (VariableVectorTuple<L> &, const int) {};
00538 };
00539
00541
00544 template<int N, class L>
00545 class GetVal
00546 {
00547 public:
00549 static typename VariableVectorTuple<L>::VariableTuple getval
00550 (const VariableVectorTuple<L> &tuple,
00551 typename VariableVectorTuple<L>::VariableTuple
00552 &values, const int index)
00553 {Loki::Field<N-1>(values)
00554 = Loki::Field<N-1>(tuple.vectors)[index];
00555 return GetVal<N-1, L>::getval (tuple, values, index);
00556 }
00557 };
00558
00560
00563 template<class L>
00564 class GetVal<0, L>
00565 {
00566 public:
00567 static typename VariableVectorTuple<L>::VariableTuple getval
00568 (const VariableVectorTuple<L> &,
00569 typename VariableVectorTuple<L>::VariableTuple
00570 &values, const int) {return values;}
00571 };
00572
00574
00576 template<int N, class L>
00577 class SaveVecType
00578 {
00579 public:
00580 static void saveVecType
00581 (const VariableVectorTuple<L> &tuple,
00582 BSUtilities::xmlw::XmlStream &os)
00583 {
00584 os << BSUtilities::xmlw::attr (VariableVectorTuple<L>::QTAG
00585 + BSUtilities::Conversion<int>::to_string (N))
00586 << Loki::TL::TypeAt<L, N-1>::Result::PQ::Name ()
00587 << BSUtilities::xmlw::attr (VariableVectorTuple<L>::UTAG
00588 + BSUtilities::Conversion<int>::to_string (N))
00589 << Loki::TL::TypeAt<L, N-1>::Result::Unit::Name ();
00590 SaveVecType<N-1, L>::saveVecType (tuple, os);
00591 }
00592 };
00593
00595
00597 template<class L>
00598 class SaveVecType<0, L>
00599 {
00600 public:
00601 static void saveVecType
00602 (const VariableVectorTuple<L> &,
00603 BSUtilities::xmlw::XmlStream &) {}
00604 };
00605
00607
00610 template<int N, class L>
00611 class SaveVec
00612 {
00613 public:
00614 static void saveVec
00615 (const VariableVectorTuple<L> &tuple, int index,
00616 BSUtilities::xmlw::XmlStream &os)
00617 {
00618 os << BSUtilities::xmlw::attr (VariableVectorTuple<L>::VTAG
00619 + BSUtilities::Conversion<int>::to_string (N))
00620 << Loki::Field<N-1>(tuple.vectors)[index].value ();
00621 SaveVec<N-1, L>::saveVec (tuple, index, os);
00622 }
00623 };
00624
00626
00628 template<class L>
00629 class SaveVec<0, L>
00630 {
00631 public:
00632 static void saveVec
00633 (const VariableVectorTuple<L> &, int,
00634 BSUtilities::xmlw::XmlStream &) {}
00635 };
00636
00638
00642 template<int N, class L>
00643 class CheckQuantities
00644 {
00645 public:
00646 static bool checkQuantities
00647 (const VariableVectorTuple<L> &tuple,
00648 const TiXmlElement *element)
00649 {
00650 if ((element->Attribute (VariableVectorTuple<L>::QTAG
00651 + BSUtilities::Conversion<int>::to_string (N))
00652 == Loki::TL::TypeAt<L, N-1>::Result::PQ::Name ())
00653 && (element->Attribute (VariableVectorTuple<L>::UTAG
00654 + BSUtilities::Conversion<int>::to_string (N))
00655 == Loki::TL::TypeAt<L, N-1>::Result::Unit::Name ()))
00656 {return CheckQuantities<N-1, L>::checkQuantities
00657 (tuple, element);}
00658
00659 else
00660 return false;
00661 }
00662 };
00663
00665
00667 template<class L>
00668 class CheckQuantities<0, L>
00669 {
00670 public:
00671 static bool checkQuantities
00672 (const VariableVectorTuple<L> &, const TiXmlElement *)
00673 {return true;}
00674 };
00675
00677
00680 template<int N, class L, class ST>
00681 class LoadVec
00682 {
00683 public:
00684 static void loadvec
00685 (VariableVectorTuple<L> &tuple, const TiXmlNode *child)
00686 {
00687 const TiXmlElement *element = child->ToElement();
00688
00689 if (element->Attribute
00690 (VariableVectorTuple<L>::VTAG
00691 + BSUtilities::Conversion<int>::to_string (N)))
00692 {
00693 Loki::Field<N-1>(tuple.vectors).push_back
00694 (typename Loki::TL::TypeAt<L, N-1>::Result::V
00695 (BSUtilities::Conversion<ST>::string_to
00696 (element->Attribute (VariableVectorTuple<L>::VTAG
00697 + BSUtilities::Conversion<int>::to_string (N)))));
00698 LoadVec<N-1, L, ST>::loadvec (tuple, child);
00699 }
00700
00701 else
00702 throw LoadError
00703 ("error loading VariableVectorTuple: incorrect vector");
00704
00705 }
00706 };
00707
00709
00711 template<class L, class ST>
00712 class LoadVec<0, L, ST>
00713 {
00714 public:
00715 static void loadvec (VariableVectorTuple<L> &, const TiXmlNode *)
00716 {}
00717 };
00718
00720
00722 template<int N, class L>
00723 class CmpVec
00724 {
00725 public:
00726 static bool cmpVec
00727 (const VariableVectorTuple<L> &tuple1,
00728 const VariableVectorTuple<L> &tuple2)
00729 {
00730 if (Loki::Field<N-1>(tuple1.vectors)
00731 == Loki::Field<N-1>(tuple2.vectors))
00732 return CmpVec<N-1, L>::cmpVec (tuple1, tuple2);
00733
00734 else
00735 return false;
00736 }
00737 };
00738
00740
00743 template<class L>
00744 class CmpVec<0, L>
00745 {
00746 public:
00747 static bool cmpVec
00748 (const VariableVectorTuple<L> &, const VariableVectorTuple<L> &)
00749 {return true;}
00750 };
00751
00753
00754
00755
00757
00759
00765 template<class DIM, class BT, class UL, class DU,
00766 class ST, class SU, class LTail>
00767 class VariableVectorTuple<Loki::Typelist<
00768 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >
00769 {
00770 private:
00772 typedef Loki::Typelist<VariableVector<
00773 Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> L;
00774
00775 Loki::Tuple<L> vectors;
00776
00777 public:
00779
00783 typedef Loki::Tuple<typename GetVar<L>::Result> VariableTuple;
00784
00786
00790 void save (BSUtilities::xmlw::XmlStream &os) const
00791 {
00792 os << BSUtilities::xmlw::tag (TAG);
00793
00794 SaveVecType<Loki::TL::Length<L>::value, L>::saveVecType
00795 (*this, os);
00796
00797 for (int index = 0; index < size (); index++)
00798 {
00799 os << BSUtilities::xmlw::tag (VariableVectorTuple<L>::DTAG);
00800 SaveVec<Loki::TL::Length<L>::value, L>::saveVec
00801 (*this, index, os);
00802 os << BSUtilities::xmlw::endtag (DTAG);
00803 }
00804
00805 os << BSUtilities::xmlw::endtag (TAG);
00806 }
00807
00809
00818 void load (const TiXmlHandle node)
00819 {
00820 TiXmlElement *element = node.Element();
00821 if (element && (element->ValueStr () == TAG))
00822 {
00823 if(CheckQuantities<Loki::TL::Length<L>::value, L>
00824 ::checkQuantities (*this, element))
00825 {
00826 TiXmlNode *child = 0;
00827
00828 TiXmlElement *element = node.Element();
00829
00830 while (child = element->IterateChildren (DTAG, child))
00831 {LoadVec<Loki::TL::Length<L>::value, L, ST>::loadvec
00832 (*this, child);}
00833 }
00834
00835 else
00836 throw LoadError
00837 ("error loading VariableVectorTuple: "
00838 "incorrect attributes");
00839 }
00840
00841 else
00842 throw LoadError
00843 ("error loading VariableVectorTuple: incorrect element");
00844
00845 }
00846
00848
00850 bool operator== (const VariableVectorTuple &tuple) const
00851 {return CmpVec<Loki::TL::Length<L>::value, L>::cmpVec
00852 (*this, tuple);}
00853
00855 int number (void) const {return Loki::TL::Length<L>::value;}
00856
00858
00859
00860
00861 int size (void) const {return Loki::Field<0>(vectors).size ();}
00862
00863
00865
00866
00867 void push_back (const VariableTuple &new_values)
00868 {
00869 AddVal<Loki::TL::Length<L>::value, L>::addval (*this, new_values);
00870 }
00871
00873
00874
00875 void insert (const VariableTuple &new_values, const int index)
00876 {
00877 AddVal<Loki::TL::Length<L>::value, L>::addval
00878 (*this, new_values, index);
00879 }
00880
00882
00884 void erase (const int index)
00885 {
00886 EraVal<Loki::TL::Length<L>::value, L>::eraval (*this, index);
00887 }
00888
00890
00893 template<int I>
00894 typename Loki::TL::TypeAt<L, I>::Result::V
00895 value (const int index) const
00896 {return (Loki::Field<I>((*this).vectors))[index];}
00897
00899
00918 template<int I, class NU>
00919 Variable<typename Loki::TL::TypeAt<L, I>::Result::V::PQ, NU>
00920 value (const int index, const NU &unit) const
00921 {return
00922 ((Loki::Field<I>((*this).vectors)).value (index))(unit);}
00923
00925
00929 VariableTuple operator[] (const int index) const
00930 {
00931 VariableTuple values;
00932 return GetVal<Loki::TL::Length<L>::value, L>::getval
00933 (*this, values, index);
00934 }
00935
00937
00939 VariableTuple values (const int index) const
00940 {return (*this)[index];}
00941
00943 template<int N, class L1> friend class AddVal;
00944
00945 template<int N, class L1> friend class GetVal;
00946
00947 template<int N, class L1> friend class EraVal;
00948
00949 template<int N, class L1> friend class SaveVec;
00950
00951 template<int N, class L1> friend class CmpVec;
00952
00953 template<int N, class L1, class ST1> friend class LoadVec;
00954
00955 template<int N, class L1> friend class Copy;
00956
00957 template<int N, class L1> friend class Assign;
00958
00960 static const std::string TAG;
00961
00963 static const std::string QTAG;
00964
00966 static const std::string UTAG;
00967
00969 static const std::string DTAG;
00970
00972 static const std::string VTAG;
00973
00974 };
00975
00977 template<class DIM, class BT, class UL, class DU,
00978 class ST, class SU, class LTail>
00979 const std::string
00980 VariableVectorTuple<Loki::Typelist<
00981 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >::TAG
00982 = "variableVectorTuple";
00983
00985 template<class DIM, class BT, class UL, class DU,
00986 class ST, class SU, class LTail>
00987 const std::string
00988 VariableVectorTuple<Loki::Typelist<
00989 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >::QTAG
00990 = "quantity";
00991
00993 template<class DIM, class BT, class UL, class DU,
00994 class ST, class SU, class LTail>
00995 const std::string
00996 VariableVectorTuple<Loki::Typelist<
00997 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >::UTAG
00998 = "unit";
00999
01001 template<class DIM, class BT, class UL, class DU,
01002 class ST, class SU, class LTail>
01003 const std::string
01004 VariableVectorTuple<Loki::Typelist<
01005 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >::DTAG
01006 = "data";
01007
01009 template<class DIM, class BT, class UL, class DU,
01010 class ST, class SU, class LTail>
01011 const std::string
01012 VariableVectorTuple<Loki::Typelist<
01013 VariableVector<Quantity<DIM, BT, UL, DU, ST>, SU>, LTail> >::VTAG
01014 = "value";
01015
01016 }
01017
01018 #endif