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
00028 #include "Quantity/Quantity.h"
00029
00030
00031 #include "loki/HierarchyGenerators.h"
00032
00033
00034 #include <vector>
00035
00036
00037 #include <boost/serialization/vector.hpp>
00038 #include <boost/serialization/base_object.hpp>
00039
00040 namespace quantity {
00041
00043
00044
00045
00047
00049
00052 template<typename Q> class Vector;
00053
00055
00060 template<typename QT, typename ST> class Vector<Quantity<QT, ST> >
00061 {
00062 private:
00064 typedef Quantity<QT, ST> BQ;
00065
00066 public:
00068 virtual int size (void) const = 0;
00069
00071 virtual ~Vector (void) {}
00072
00074 friend class boost::serialization::access;
00075
00077
00079 private:
00080 template<typename Archive>
00081 void serialize (Archive &ar, const unsigned int )
00082 {
00083 }
00084
00085 };
00086
00088
00089
00090
00092
00094
00102 template<template<typename, typename> class M, typename BQ,
00103 typename DQ = DerivedQuantity<typename BQ::QuantityType, typename BQ::DU, typename BQ::DDQ> >
00104 class QuantityVector;
00105
00107
00117 template<template<typename, typename> class M, typename QT, typename ST, typename SU, typename DQT>
00118 class QuantityVector<M, Quantity<QT, ST>, DerivedQuantity<QT, SU, DQT> >
00119 : public Vector<Quantity<QT, ST> >
00120 {
00121 private:
00123
00124
00126
00128 typedef typename QuantityTraits<QT>::Dimension DIM;
00129
00131
00133 typedef typename QuantityTraits<QT>::UnitType UT;
00134
00136
00138 typedef typename QuantityTraits<QT>::UnitList UL;
00139
00141
00143 typedef typename QuantityTraits<QT>::DefaultUnit DU;
00144
00146
00149 typedef Quantity<QT, ST> BQ;
00150
00152 typedef Vector<Quantity<QT, ST> > VEC;
00153
00154 public:
00156
00159 typedef M<BQ, DerivedQuantity<QT, SU, DQT> > V;
00160
00162
00164 typedef QuantityVector<M, BQ, DerivedQuantity<QT, SU, DQT> > QV;
00165
00167
00169 typedef ST StorageType;
00170
00172 typedef typename unit::CheckUnit<unit::Unit<UT>, SU>::Check StorageUnit;
00173
00174 private:
00176 std::vector<ST> _values;
00177
00178 public:
00180 QuantityVector (void) {}
00181
00183
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00203
00205 QuantityVector & operator= (const QuantityVector &new_vector)
00206 {
00207 if (this != &new_vector)
00208 {
00209 VEC::operator= (new_vector);
00210 _values = new_vector._values;
00211 }
00212
00213 return *this;
00214 }
00215
00217
00221 template<typename SSU, typename SDQT>
00222 QuantityVector & operator= (const QuantityVector<M, BQ, DerivedQuantity<QT, SSU, SDQT> > &new_vector)
00223 {
00224 VEC::operator= (new_vector);
00225
00226 int size = new_vector.size ();
00227
00228 _values.empty ();
00229
00230 _values.reserve (size);
00231
00232 for (int i = 0; i < size; i++)
00233 _values.push_back(Reverse<StorageUnit, typename BQ::StorageType>::VAL
00234 (Standardize<SSU, typename BQ::StorageType>::VAL (new_vector[i].value ())));
00235
00236 return *this;
00237 }
00238
00240
00244 bool operator== (const QV &vector) const
00245 {
00246 return ((size () == vector.size ())
00247 && (_values == vector._values));
00248 }
00249
00251
00255 int size (void) const {return _values.size ();}
00256
00258
00263 template<template<typename, typename> class Q1, typename QT1,
00264 typename ST1, typename SSU, typename SDQT>
00265 void push_back (const Q1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SSU, SDQT> > &new_quantity)
00266 {_values.push_back (Reverse<StorageUnit, ST>::VAL
00267 (Standardize<typename
00268 CheckAgainstAllUnits<typename Q1<Quantity<QT1, ST1>,
00269 DerivedQuantity<QT1, SSU, SDQT> >::StorageUnit, typename Loki::TL::Append<UL,
00270 unit::NonPrefixable<unit::GenericUnitBase<DIM>, unit::GenericUnit>
00271 >::Result >::RET, ST>::VAL (new_quantity.value ())));}
00272
00274
00278 template<template<typename, typename> class Q1, typename QT1,
00279 typename ST1, typename SSU, typename SDQT>
00280 void insert (const Q1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SSU, SDQT> > &new_quantity,
00281 const int index)
00282 {if (index >= 0 && index < size ())
00283 {typename std::vector<ST>::iterator pos
00284 = _values.begin () + index;
00285 _values.insert (pos, Reverse<StorageUnit, ST>::VAL
00286 (Standardize<typename
00287 CheckAgainstAllUnits<typename Q1<Quantity<QT1, ST1>,
00288 DerivedQuantity<QT1, SSU, SDQT> >::StorageUnit,
00289 typename Loki::TL::Append<UL,
00290 unit::NonPrefixable<unit::GenericUnitBase<DIM>,
00291 unit::GenericUnit> >::Result >::RET, ST>::VAL
00292 (new_quantity.value ())));
00293 }
00294 else
00295 {throw VectorOutOfBounds();}
00296 }
00297
00299
00304 template<template<typename, typename> class Q1, typename QT1,
00305 typename ST1, typename SSU, typename SDQT>
00306 void replace
00307 (const Q1<Quantity<QT1, ST1>, DerivedQuantity<QT1, SSU, SDQT> > &new_quantity,
00308 const int index)
00309 {if (index >= 0 && index < size ())
00310 {_values[index] = Reverse<StorageUnit, ST>::VAL
00311 (Standardize<typename
00312 CheckAgainstAllUnits<typename Q1<Quantity<QT1, ST1>,
00313 DerivedQuantity<QT1, SSU, SDQT> >::StorageUnit,
00314 typename Loki::TL::Append<UL,
00315 unit::NonPrefixable<unit::GenericUnitBase<DIM>,
00316 unit::GenericUnit> >::Result >::RET, ST>::VAL
00317 (new_quantity.value ()));
00318 }
00319 else
00320 {throw VectorOutOfBounds();}
00321 }
00322
00324
00326 void erase (const int index)
00327 {
00328 if (index >= 0 && index < size ())
00329 {
00330 typename std::vector<ST>::iterator pos = _values.begin () + index;
00331 _values.erase (pos);
00332 }
00333 else
00334 {throw VectorOutOfBounds();}
00335 }
00336
00338 void clear (void) {_values.clear ();}
00339
00341
00343 std::vector<ST> values (void) {return _values;}
00344
00346
00348 V value (const int index) const
00349 {if (index >= 0 && index < size ())
00350 {return V (_values[index]);}
00351 else
00352 {throw VectorOutOfBounds();}
00353 }
00354
00356
00359 V operator[] (const int index) const {return value (index);}
00360
00362
00366 template<typename NU>
00367 M<Quantity<QT, ST>, DerivedQuantity<QT, NU, DQT> >
00368 value (const int index, const NU &) const
00369 {return M<Quantity<QT, ST>, DerivedQuantity<QT, NU, DQT> > (value (index));}
00370
00372
00375 V max (void) const
00376 {
00377 ST max_val = _values[0];
00378 typename std::vector<ST>::const_iterator index;
00379
00380 for (index = _values.begin (); index < _values.end ();
00381 index++)
00382 max_val = ((max_val < *index) ? *index : max_val);
00383
00384 return V (max_val);
00385 }
00386
00388
00392
00393
00394
00395
00396
00397
00399
00402 V min (void) const
00403 {
00404 ST min_val = _values[0];
00405 typename std::vector<ST>::const_iterator index;
00406
00407 for (index = _values.begin (); index < _values.end ();
00408 index++)
00409 min_val = ((min_val < *index) ? min_val : *index);
00410
00411 return V (min_val);
00412 }
00413
00415
00419
00420
00421
00422
00423
00424
00425 private:
00427 friend class boost::serialization::access;
00428
00430
00432 template<typename Archive>
00433 void serialize (Archive &ar, const unsigned int )
00434 {
00435 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(VEC);
00436 ar & BOOST_SERIALIZATION_NVP(_values);
00437 }
00438
00439 };
00440
00442
00445 template<class L> class QuantityVectorTuple;
00446
00448
00449
00450
00452
00454
00459 template<class TL> struct GetVar;
00460
00462
00468 template<class Head, class Tail>
00469 struct GetVar<Loki::Typelist<Head, Tail> >
00470 {
00471 private:
00472 typedef typename GetVar<Tail>::Result L1;
00473
00474 public:
00475 typedef Loki::Typelist<typename Head::V, L1> Result;
00476 };
00477
00479
00482 template<>
00483 struct GetVar<Loki::NullType>
00484 {
00485 typedef Loki::NullType Result;
00486 };
00487
00489
00492 template<int N, class L>
00493 class AddVal
00494 {
00495 public:
00497 static void addval (QuantityVectorTuple<L> &tuple,
00498 const typename QuantityVectorTuple<L>::QTuple &new_values)
00499 {Loki::Field<N-1>(tuple.vectors).push_back
00500 (Loki::Field<N-1>(new_values));
00501 AddVal<N-1, L>::addval (tuple, new_values);
00502 }
00503
00505 static void addval (QuantityVectorTuple<L> &tuple,
00506 const typename QuantityVectorTuple<L>::QTuple
00507 &new_values, const int index)
00508 {Loki::Field<N-1>(tuple.vectors).insert
00509 (Loki::Field<N-1>(new_values), index);
00510 AddVal<N-1, L>::addval (tuple, new_values, index);
00511 }
00512 };
00513
00515
00518 template<class L>
00519 class AddVal<0, L>
00520 {
00521 public:
00522 static void addval (QuantityVectorTuple<L> &,
00523 const typename QuantityVectorTuple<L>::QTuple &) {};
00524
00525 static void addval (QuantityVectorTuple<L> &,
00526 const typename QuantityVectorTuple<L>::QTuple &, const int) {};
00527 };
00528
00530
00533 template<int N, class L>
00534 class EraVal
00535 {
00536 public:
00538 static void eraval (QuantityVectorTuple<L> &tuple,
00539 const int index)
00540 {Loki::Field<N-1>(tuple.vectors).erase (index);
00541 EraVal<N-1, L>::eraval (tuple, index);
00542 }
00543 };
00544
00546
00549 template<class L>
00550 class EraVal<0, L>
00551 {
00552 public:
00553 static void eraval (QuantityVectorTuple<L> &, const int) {};
00554 };
00555
00557
00560 template<int N, class L>
00561 class GetVal
00562 {
00563 public:
00565 static typename QuantityVectorTuple<L>::QTuple getval
00566 (const QuantityVectorTuple<L> &tuple,
00567 typename QuantityVectorTuple<L>::QTuple
00568 &values, const int index)
00569 {Loki::Field<N-1>(values)
00570 = Loki::Field<N-1>(tuple.vectors)[index];
00571 return GetVal<N-1, L>::getval (tuple, values, index);
00572 }
00573 };
00574
00576
00579 template<class L>
00580 class GetVal<0, L>
00581 {
00582 public:
00583 static typename QuantityVectorTuple<L>::QTuple getval
00584 (const QuantityVectorTuple<L> &,
00585 typename QuantityVectorTuple<L>::QTuple
00586 &values, const int) {return values;}
00587 };
00588
00590
00592 template<int N, class L>
00593 class CmpVec
00594 {
00595 public:
00596 static bool cmpVec
00597 (const QuantityVectorTuple<L> &tuple1,
00598 const QuantityVectorTuple<L> &tuple2)
00599 {
00600 if (Loki::Field<N-1>(tuple1.vectors)
00601 == Loki::Field<N-1>(tuple2.vectors))
00602 return CmpVec<N-1, L>::cmpVec (tuple1, tuple2);
00603
00604 else
00605 return false;
00606 }
00607 };
00608
00610
00613 template<class L>
00614 class CmpVec<0, L>
00615 {
00616 public:
00617 static bool cmpVec
00618 (const QuantityVectorTuple<L> &, const QuantityVectorTuple<L> &)
00619 {return true;}
00620 };
00621
00623
00626 template<int N, class L, typename Archive>
00627 class SaveVec
00628 {
00629 public:
00630 static void saveVec
00631 (const QuantityVectorTuple<L> &tuple, Archive &ar)
00632 {
00633 SaveVec<N-1,L,Archive>::saveVec (tuple, ar);
00634 typename Loki::TL::TypeAt<L, N-1>::Result
00635 vec = Loki::Field<N-1>(tuple.vectors);
00636 ar << BOOST_SERIALIZATION_NVP(vec);
00637 }
00638 };
00639
00641
00644 template<class L, typename Archive>
00645 class SaveVec<0, L, Archive>
00646 {
00647 public:
00648 static void saveVec (const QuantityVectorTuple<L> &, Archive &) {}
00649 };
00650
00652
00659 template<int N, class L, typename Archive>
00660 class LoadVec
00661 {
00662 public:
00663 static void loadVec
00664 (QuantityVectorTuple<L> &tuple, Archive &ar, int &_size)
00665 {
00666 LoadVec<N-1,L,Archive>::loadVec (tuple, ar, _size);
00667 typename Loki::TL::TypeAt<L, N-1>::Result
00668 vec;
00669 ar >> BOOST_SERIALIZATION_NVP(vec);
00670 if (vec.size () == _size)
00671 Loki::Field<N-1>(tuple.vectors) = vec;
00672 else
00673 {throw VectorSizeError("vector has wrong size!");}
00674 }
00675 };
00676
00678
00681 template<class L, typename Archive>
00682 class LoadVec<0, L, Archive>
00683 {
00684 public:
00685 static void loadVec (QuantityVectorTuple<L> &, Archive &, int &) {}
00686 };
00687
00689
00690
00691 template <class V, class QVT> struct CheckVariableInVectorTuple;
00692
00694
00696 template<template<typename, typename> class T, typename V, typename QT,
00697 typename ST, typename SU, typename LTail>
00698 struct CheckVariableInVectorTuple<V,
00699 Loki::Typelist<QuantityVector<T, Quantity <QT, ST>, SU>, LTail> >
00700 {
00701 private:
00702 typedef typename BSUtilities::IF<BSUtilities::SameType<V,
00703 typename QuantityVector<T, Quantity<QT, ST>, SU>::V>::sameType,
00704 QuantityVector<T, Quantity<QT, ST>, SU>,
00705 typename CheckVariableInVectorTuple<V, LTail>::RET>::RET RET;
00706 };
00707
00709
00715 template<typename V>
00716 struct CheckVariableInVectorTuple<V, Loki::NullType>
00717 {
00718 typedef VariableError<true> RET;
00719 };
00720
00722
00723
00724
00726
00728
00735 template<template<typename, typename> class T, typename QT,
00736 typename ST, typename SU, typename LTail>
00737 class QuantityVectorTuple<Loki::Typelist<
00738 QuantityVector<T, Quantity<QT, ST>, SU>, LTail> >
00739 {
00740 private:
00742 typedef Loki::Typelist<QuantityVector<T, Quantity<QT, ST>, SU>, LTail> L;
00743
00745 typedef QuantityVectorTuple<L> QVT;
00746
00748 Loki::Tuple<L> vectors;
00749
00750 public:
00752
00756 typedef Loki::Tuple<typename GetVar<L>::Result> QTuple;
00757
00759
00761 bool operator== (const QuantityVectorTuple &tuple) const
00762 {return CmpVec<Loki::TL::Length<L>::value, L>::cmpVec
00763 (*this, tuple);}
00764
00766 int number (void) const {return Loki::TL::Length<L>::value;}
00767
00769
00770
00771
00772 int size (void) const {return Loki::Field<0>(vectors).size ();}
00773
00774
00776
00777
00778 void push_back (const QTuple &new_values)
00779 {
00780 AddVal<Loki::TL::Length<L>::value, L>::addval (*this, new_values);
00781 }
00782
00784
00785
00786 void insert (const QTuple &new_values, const int index)
00787 {
00788 AddVal<Loki::TL::Length<L>::value, L>::addval
00789 (*this, new_values, index);
00790 }
00791
00793
00795 void erase (const int index)
00796 {
00797 EraVal<Loki::TL::Length<L>::value, L>::eraval (*this, index);
00798 }
00799
00801
00804 template<int I>
00805 typename Loki::TL::TypeAt<L, I>::Result::V
00806 value (const unsigned int index) const
00807 {return (Loki::Field<I>((*this).vectors))[index];}
00808
00810
00829 template<int I, class NU>
00830 T<typename Loki::TL::TypeAt<L, I>::Result::V::BQ, NU>
00831 value (const int index, const NU &unit) const
00832 {return
00833 ((Loki::Field<I>((*this).vectors)).value (index))(unit);}
00834
00836
00840 QTuple operator[] (const int index) const
00841 {
00842 QTuple values;
00843 return GetVal<Loki::TL::Length<L>::value, L>::getval
00844 (*this, values, index);
00845 }
00846
00848
00850 QTuple values (const int index) const {return (*this)[index];}
00851
00853 template<int I>
00854 QuantityVector<T, typename Loki::TL::TypeAt<L, I>::Result::V::BQ,
00855 typename Loki::TL::TypeAt<L, I>::Result::V::Unit>
00856 getVector (Loki::Int2Type<I>) const
00857 {return QuantityVector<T,
00858 typename Loki::TL::TypeAt<L, I>::Result::V::BQ,
00859 typename Loki::TL::TypeAt<L, I>::Result::V::Unit>
00860 (Loki::Field<I>((*this).vectors));}
00861
00863 template<int N, class L1> friend class AddVal;
00864
00865 template<int N, class L1> friend class GetVal;
00866
00867 template<int N, class L1> friend class EraVal;
00868
00869 template<int N, class L1> friend class CmpVec;
00870
00871 template<int N, class L1> friend class Copy;
00872
00873 template<int N, class L1> friend class Assign;
00874
00875 template<int N, class L1, typename Archive> friend class SaveVec;
00876 template<int N, class L1, typename Archive> friend class LoadVec;
00877
00878 private:
00880 friend class boost::serialization::access;
00881
00883
00891 template<typename Archive>
00892 void save (Archive &ar, const unsigned int ) const
00893 {
00894 int _size = size ();
00895 ar << BOOST_SERIALIZATION_NVP (_size);
00896 SaveVec<Loki::TL::Length<L>::value, L, Archive>
00897 ::saveVec (*this, ar);
00898 }
00899
00901
00909 template<typename Archive>
00910 void load (Archive &ar, const unsigned int )
00911 {
00912 int _size;
00913 ar >> BOOST_SERIALIZATION_NVP (_size);
00914 LoadVec<Loki::TL::Length<L>::value, L, Archive>
00915 ::loadVec (*this, ar, _size);
00916 }
00917
00918 BOOST_SERIALIZATION_SPLIT_MEMBER()
00919
00920 };
00921
00922 }
00923
00924 #endif