Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

toolbox/scannerConnectors.hh
Go to the documentation of this file.
00001 /* Scanners and Containers
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 // debugging Joiner
00015 #define JoinerConstr_D 0
00016 #define JoinerDestr_D 0
00017 
00018 namespace concepts {
00019 
00020   // ****************************************************************** Scan **
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   // ************************************************************* Joiner **
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   // ************************************************************* PListScan **
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   // ************************************************************** ListScan **
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   // ******************************************************** PStlVectorScan **
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   // ********************************************************* StlVectorScan **
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   // ************************************************************* ArrayScan **
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 } // namespace concepts
00346 
00347 #endif //  scannerConnectors_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)