00001
00007 #ifndef __LOOPSPEC_H__
00008 #define __LOOPSPEC_H__
00009
00010 #include <string>
00011 using std::string;
00012 #include <iostream>
00013
00014 #include "../src/valuegen.h"
00015
00016
00017
00026 template<class T>
00027 class LoopSpec {
00028 public:
00029 typedef LoopSpec self;
00030 typedef T value_type;
00031
00070 LoopSpec(const string& name_, const int max_count_, const bool exclusive=true, ValueGenerator<T>* g=0,
00071 const int discrete_levels_=-1)
00072 : namestr(name_), max_count(max_count_),
00073 end(exclusive? max_count : max_count+1), valuegen(g),
00074
00075 discrete_levels((discrete_levels_==max_count && g==0)? -1 : discrete_levels_),
00076 counter(0) { }
00077
00078 inline bool next() { if (valuegen) valuegen->next(); return (counter++ < end); }
00079 inline void reset() { if (valuegen) { valuegen->reset(); valuegen->next(); } counter=0; }
00080
00081 inline bool valid() const { return (counter < end); }
00082 inline int count() const { return counter; }
00083 inline int num() const { return end; }
00084 inline T operator*() const { return value(); }
00085
00086 inline string name() const { return namestr; }
00087
00088 inline T value() const {
00089 const T val = (!valuegen? (max_count? T(counter)/T(max_count) : 0) : valuegen->value());
00090 return (discrete_levels <=0 ? val : T(int(val*discrete_levels))/T(discrete_levels));
00091 }
00092
00093 private:
00094 const string namestr;
00095 const int max_count;
00096 const int end;
00097 OwningPointer<ValueGenerator<T> > valuegen;
00098 const int discrete_levels;
00099
00100 int counter;
00101 };
00102
00103
00104
00107 template<class TT>
00108 std::ostream& operator<<(std::ostream& s, const LoopSpec<TT>& ls)
00109 { s << (ls.name()==""? string() : (ls.name() + "=")) << ls.value(); return s; }
00110
00111
00112
00121 template<class LoopContainer, class LoopContainerIterator, class Action>
00122 bool LoopSpecs_ExecuteNested(LoopContainer& loops, const LoopContainerIterator& current, Action& fn)
00123 {
00124 if (current == loops.end()) return false;
00125 else {
00126 (*current)->reset();
00127 while ((*current)->valid()) {
00128 if (!LoopSpecs_ExecuteNested(loops,current+1,fn))
00129 fn();
00130 (*current)->next();
00131 }
00132 }
00133 return true;
00134 }
00135
00136
00137 #endif
00138