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 <vector>
00032
00033 namespace Quantities {
00034
00036
00037
00038
00040
00042
00046 class QuantityVectorOutOfBounds {};
00047
00049
00050
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
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
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
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
00492
00493
00494 int length (void) {return Loki::Field<0>(vectors).length ();}
00495
00496
00498
00499
00500 void add (const VariableTuple &new_values)
00501 {
00502 AddVal<Loki::TL::Length<L>::value, L>::addval (*this, new_values);
00503 }
00504
00506
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