00001
00002
00003
00004 #ifndef scannerConnectors_hh
00005 #define scannerConnectors_hh
00006
00007 #include <vector>
00008 #include "basics/typedefs.hh"
00009 #include "basics/outputOperator.hh"
00010 #include "basics/debug.hh"
00011 #include "basics/exceptions.hh"
00012 #include "toolbox/array.hh"
00013
00014
00015 #define JoinerConstr_D 0
00016 #define JoinerDestr_D 0
00017
00018 namespace concepts {
00019
00020
00021
00026 template <class T>
00027 class Scan {
00028 public:
00029 virtual ~Scan() {};
00030
00032 operator int() { return !eos(); }
00033
00035 virtual bool eos() const = 0;
00037 virtual T& operator++(int) = 0;
00039 virtual Scan* clone() const = 0;
00040 };
00041
00042
00043
00044 template<class T, unsigned nlnk>
00045 class Joiner;
00046
00047 template<class T, unsigned nlnk>
00048 std::ostream& operator<<(std::ostream& os,
00049 const Joiner<T, nlnk>& j);
00050
00070 template<class T, unsigned nlnk>
00071 class Joiner {
00072 friend std::ostream& operator<< <>(std::ostream& os,
00073 const Joiner<T, nlnk>& j);
00074 public:
00081 inline Joiner(const T& val, Joiner* lnk = 0);
00082
00086 inline ~Joiner() {}
00087
00093 static void destructor(Joiner<T, nlnk>*& j, bool values = true);
00094
00099 inline Joiner*& operator[](uint i) {
00100 conceptsAssert(i < nlnk, Assertion());
00101 return lnk_[i];
00102 }
00103
00105 inline T& value() { return val_; }
00106
00107 private:
00109 Joiner<T, nlnk>* lnk_[nlnk];
00110
00112 T val_;
00113
00115 Joiner(const Joiner&);
00116 void operator =(const Joiner&);
00117
00119 static void destructor_(Joiner<T, nlnk>* j, bool values = true);
00120 };
00121
00122 template <class T, unsigned nlnk>
00123 Joiner<T, nlnk>::Joiner(const T& val, Joiner<T, nlnk>* lnk) :
00124 val_(val) {
00125 DEBUGL(JoinerConstr_D, "start.");
00126 for(uint i = 0; i < nlnk - 1; ++i)
00127 lnk_[i] = 0;
00128 lnk_[nlnk - 1] = lnk;
00129 DEBUGL(JoinerConstr_D, "done.");
00130 }
00131
00132 template <class T, unsigned nlnk>
00133 void Joiner<T, nlnk>::destructor(Joiner<T, nlnk>*& j, bool values) {
00134 DEBUGL(JoinerDestr_D, "start.");
00135 if (nlnk > 1) {
00136 if (j) {destructor_(j); j = 0;}
00137 }
00138 else {
00139 while (j) {
00140 Joiner<T, 1>* foo = j;
00141 j = j->lnk_[0];
00142 if (values) delete foo->val_;
00143 delete foo;
00144 }
00145 }
00146 DEBUGL(JoinerDestr_D, "done.");
00147 }
00148
00149 template <class T, unsigned nlnk>
00150 void Joiner<T, nlnk>::destructor_(Joiner<T, nlnk>* j, bool values) {
00151 for(uint i = 0; i < nlnk; i++) {
00152 if (j->lnk_[i]) destructor_(j->lnk_[i]);
00153 }
00154 if (values) delete j->val_;
00155 delete j;
00156 }
00157
00158 template<class T, unsigned nlnk>
00159 std::ostream& operator<<(std::ostream& os, const Joiner<T, nlnk>& j) {
00160 os << "J(" << j.val_ << " -> [" << std::flush;
00161 for(uint i = 0; i < nlnk-1; ++i)
00162 if (j.lnk_[i])
00163 os << *j.lnk_[i] << ", " << std::flush;
00164 if (j.lnk_[nlnk-1])
00165 os << *j.lnk_[nlnk-1] << std::flush;
00166 return os << "])" << std::flush;
00167 }
00168
00169
00170
00173 template <class T>
00174 class PListScan : public Scan<T> {
00176 Joiner<T*, 1>* head_;
00177
00179 Joiner<T*, 1>* current_;
00180
00182 bool eos_;
00183 public:
00187 PListScan(Joiner<T*, 1>& cnr) :
00188 head_(&cnr), current_(&cnr), eos_(head_ ? false : true) {}
00189
00190 bool eos() const { return eos_; }
00191
00192 PListScan<T>* clone() const { return new PListScan<T>(*this); }
00193
00194 T& operator++(int);
00195 };
00196
00197 template <class T>
00198 T& PListScan<T>::operator++(int) {
00199
00200 T* tmp = 0;
00201 if (!eos_) {
00202 tmp = current_->value();
00203 current_ = (*current_)[0];
00204 if ((eos_ = current_ == 0)) current_ = head_;
00205 }
00206 return *tmp;
00207 }
00208
00209
00210
00213 template <class T>
00214 class ListScan : public Scan<T> {
00216 Joiner<T, 1>* head_;
00217
00219 Joiner<T, 1>* current_;
00220
00222 bool eos_;
00223 public:
00227 ListScan(Joiner<T, 1>& cnr) :
00228 head_(&cnr), current_(&cnr), eos_(head_ ? false : true) {}
00229
00230 bool eos() const { return eos_; }
00231
00232 ListScan<T>* clone() const { return new ListScan<T>(*this); }
00233
00234 T& operator++(int);
00235 };
00236
00237 template <class T>
00238 T& ListScan<T>::operator++(int) {
00239
00240 T& tmp = current_->value();
00241
00242 if (!eos_) {
00243 current_ = (*current_)[0];
00244 if ((eos_ = current_ == 0)) current_ = head_;
00245 }
00246
00247 return tmp;
00248 }
00249
00250
00251
00254 template<class T>
00255 class PStlVectorScan : public Scan<T> {
00256 public:
00257 inline PStlVectorScan(typename std::vector<T*>& v)
00258 : i_(v.begin()), last_(v.end()) {}
00259 inline PStlVectorScan(typename std::vector<T*>::iterator first,
00260 typename std::vector<T*>::const_iterator last)
00261 : i_(first), last_(last) {}
00262 inline PStlVectorScan(const PStlVectorScan<T> &scan)
00263 : i_(scan.i_), last_(scan.last_) {}
00264 inline bool eos() const { return i_ == last_; }
00265 inline T& operator++(int) { return **i_++; }
00266 inline PStlVectorScan<T>* clone() const { return new PStlVectorScan(*this); }
00267 private:
00268 typename std::vector<T*>::iterator i_;
00269 typename std::vector<T*>::const_iterator last_;
00270 };
00271
00272
00273
00278 template <class T, class ItType = typename std::vector<T*>::const_iterator >
00279 class StlVectorScan : public Scan<T> {
00280 typedef std::vector<T*> Vector;
00281
00282 const Vector& vec;
00283 ItType it;
00284
00285
00286 public:
00291 StlVectorScan(const Vector& vec, ItType it)
00292 : vec(vec), it(it)
00293 {}
00294
00298 StlVectorScan(Vector& vec)
00299 : vec(vec), it(vec.begin())
00300 {}
00301
00302 bool eos() const { return it == vec.end(); }
00303
00304 StlVectorScan* clone() const { return new StlVectorScan(*this); }
00305
00306 T& operator*() {
00307 return **it;
00308 }
00309
00311 T& operator++(int) {
00312 T* old = *it;
00313 ++it;
00314 return *old;
00315 }
00316
00318 T& operator++() {
00319 return *(++it);
00320 }
00321
00322 };
00323
00324
00325
00330 template<class T>
00331 class ArrayScan : public Scan<T> {
00332 public:
00333 inline ArrayScan(Array<T>& container)
00334 : idx_(0), container_(container) {}
00335 inline ArrayScan(const ArrayScan& scan) :
00336 idx_(scan.idx_), container_(scan.container_) {}
00337 inline bool eos() const { return idx_ == container_.size(); }
00338 inline T& operator++(int) { return container_[idx_++]; }
00339 inline Scan<T>* clone() const { return new ArrayScan(*this); }
00340 private:
00341 uint idx_;
00342 Array<T>& container_;
00343 };
00344
00345 }
00346
00347 #endif // scannerConnectors_hh