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

toolbox/sequence.hh
Go to the documentation of this file.
00001 /* Sequence of elements, like array, based on std::vector with
00002    operations, output operator, and method of the particular element
00003    types.
00004  */
00005 
00006 #ifndef sequence_hh
00007 #define sequence_hh
00008 
00009 #include <vector>
00010 #include <algorithm>
00011 #include <set>
00012 #include <stdarg.h>
00013 #include <basics/outputOperator.hh>
00014 #include <basics/exceptions.hh>
00015 #include <basics/pointerOutput.hh>
00016 
00017 #define SeqInput_D 0
00018 
00019 namespace concepts {
00020 
00021   // forward declaration
00022   template<class F>
00023   class BaseSequence;
00024 
00025   // ************************************************************** Sequence **
00026 
00033   template<class F>
00034   class Sequence : public BaseSequence<F> {
00035   public:
00036     Sequence() : BaseSequence<F>() {}
00037 
00038     template<class G>
00039     Sequence(const G& seq) : BaseSequence<F>(seq) {}
00040     virtual ~Sequence() {}
00041   };
00042 
00043   template<>
00044   class Sequence<bool>;
00045 
00046 
00047  // *********************************************************** BaseSequence **
00048 
00053   template<class F>
00054   class BaseSequence : public std::vector<F>, public concepts::OutputOperator {
00055   public:
00056     BaseSequence() : std::vector<F>() {}
00062     BaseSequence(const std::string& str);
00063 
00065     template<class G>
00066     BaseSequence(const G& seq) 
00067       : std::vector<F>(seq) {}
00068     virtual ~BaseSequence() {}
00069 
00071     inline operator Sequence<F>() const { return *this; }
00072 
00073     inline operator std::set<F>() const {
00074       std::set<F> set;
00075       for(typename std::vector<F>::
00076       const_iterator i = this->begin(); i != this->end(); ++i)
00077   set.insert(*i);
00078       return set;
00079     }
00080 
00084     template<class G, class H>
00085     inline Sequence<G> operator()(G (H::*fun)() const) const;
00089     template<class G, class H>
00090     inline Sequence<G*> operator()(G& (H::*fun)() const) const;
00094     template<class G, class H, class I, class J>
00095     inline Sequence<G> operator()(G (H::*fun)(I) const, J i) const;
00096 
00097     // Return set union
00098     inline std::vector<bool> operator||(const Sequence<F>& set) const;
00099     // Return set intersection
00100     inline std::vector<bool> operator&&(const Sequence<F>& set) const;
00101 
00102 
00103     // Return a sequence with appended \c seq
00104     inline Sequence<F> operator+(const Sequence<F>& seq) const;
00105     // Return sequence, where are elements of \c set are not inside
00106     inline Sequence<F> operator-(const F& val) const;
00107     // Return sequence, where are elements of \c set are not inside
00108     inline Sequence<F> operator-(const Sequence<F>& set) const; 
00110     inline std::vector<bool> operator==(const F val) const;
00112     inline Sequence<F> operator()(const BaseSequence<bool>& seq) const;
00113 
00115     inline bool exist(F val) const;
00116   protected:
00117     virtual std::ostream& info(std::ostream& os) const;
00118   };
00119 
00120   template<class F>
00121   void operator>>(std::istream& is, BaseSequence<F>& seq) {
00122     F val;
00123     while(!is.eof()) {
00124       is >> val;
00125       DEBUGL(SeqInput_D, "val = " << val);
00126       if (!is.fail())
00127   seq.push_back(val);
00128     }
00129   }
00130 
00131   template<class F>
00132   BaseSequence<F>::BaseSequence(const std::string& str) {
00133     if (str.size() > 0) {
00134       std::stringstream s;
00135       s << str;
00136       s >> *this;
00137     }
00138   }
00139 
00140   // e.g. concepts::Key::key()
00141   template<class F>
00142   template<class G, class H>
00143   Sequence<G> BaseSequence<F>::operator()(G (H::*fun)() const) const {
00144     std::vector<G> seq;
00145     for(typename std::vector<F>::
00146     const_iterator i = this->begin(); i != this->end(); ++i) {
00147       G val = ((*i)->*fun)();
00148       seq.push_back(val);
00149     }
00150     return seq;
00151   }
00152   // e.g. concepts::Connector1::key()
00153   template<class F>
00154   template<class G, class H>
00155   Sequence<G*> BaseSequence<F>::operator()(G& (H::*fun)() const) const {
00156     std::vector<G*> seq;
00157     for(typename std::vector<F>::
00158     const_iterator i = this->begin(); i != this->end();++i) {
00159       G* val = &((*i)->*fun)();
00160       seq.push_back(val);
00161     }
00162     return seq;
00163   }
00164   // e.g. concepts::Connector1::vertex(uint i)
00165   template<class F>
00166   template<class G, class H, class I, class J>
00167   Sequence<G> BaseSequence<F>::operator()(G (H::*fun)(I) const, J i) const {
00168     std::vector<G> seq;
00169     for(typename std::vector<F>::
00170     const_iterator is = this->begin(); is != this->end();++is) {
00171       G val = ((*is)->*fun)(i);
00172       seq.push_back(val);
00173     }
00174     return seq;
00175   }
00176 
00177   template<class F>
00178   std::vector<bool> BaseSequence<F>::operator||(const Sequence<F>& seq) const 
00179   {
00180     conceptsAssert(this->size() == seq.size(), Assertion());
00181     std::vector<bool> result(this->size(), false);
00182 
00183     std::vector<bool>::iterator i = result.begin();
00184     typename std::vector<F>::
00185       const_iterator it = this->begin(), is = seq.begin();
00186     for(; it != this->end(); ++it, ++is, ++i) 
00187       *i = *it || *is;
00188     return result;
00189   }
00190 
00191   template<class F>
00192   std::vector<bool> BaseSequence<F>::operator&&(const Sequence<F>& seq) const 
00193   {
00194     conceptsAssert(this->size() == seq.size(), Assertion());
00195     std::vector<bool> result(this->size(), false);
00196 
00197     std::vector<bool>::iterator i = result.begin();
00198     typename std::vector<F>::
00199       const_iterator it = this->begin(), is = seq.begin();
00200     for(; it != this->end(); ++it, ++is, ++i) 
00201       *i = *it && *is;
00202     return result;
00203   }
00204 
00205   template<class F>
00206   Sequence<F> BaseSequence<F>::operator-(const Sequence<F>& seq) const {
00207     std::set<F> set = seq;
00208     std::vector<F> result;
00209     result.reserve(this->size());
00210     for(typename std::vector<F>::
00211     const_iterator i = this->begin(); i != this->end(); ++i)
00212       if (set.find(*i) == set.end()) result.push_back(*i);
00213     return result;
00214   }
00215 
00216   template<class F>
00217   Sequence<F> BaseSequence<F>::operator-(const F& val) const {
00218     std::vector<F> result;
00219     result.reserve(this->size());
00220     for(typename std::vector<F>::
00221     const_iterator i = this->begin(); i != this->end(); ++i)
00222       if (!(*i == val)) result.push_back(*i);
00223     return result;    
00224   }
00225 
00226   template<class F>
00227   Sequence<F> BaseSequence<F>::operator+(const Sequence<F>& seq) const {
00228     std::vector<F> result(this->size() + seq.size());
00229     typename std::vector<F>::iterator i = result.begin();
00230     typename std::vector<F>::
00231       const_iterator it = this->begin(), is = seq.begin();
00232     for(; it != this->end(); ++it, ++i) *i = *it;
00233     for(; is != seq.end(); ++is, ++i) *i = *is;
00234     return result;
00235   }
00236 
00237   template<class F>
00238   std::vector<bool> BaseSequence<F>::operator==(const F val) const {
00239     std::vector<bool> result(this->size());
00240 //     uint i = 0;
00241 //     for(typename std::vector<F>::
00242 //    const_iterator is = this->begin(); is != this->end(); ++is, ++i)
00243 //       if (*is == val) result.push_back(i);
00244     std::vector<bool>::iterator i = result.begin();
00245     for(typename std::vector<F>::
00246     const_iterator it = this->begin(); it != this->end(); ++it, ++i)
00247       *i = *it == val;
00248     return result;
00249   }
00250 
00251 //   template<class F>
00252 //   Sequence<F> BaseSequence<F>::operator()(const Sequence<uint>& seq) const {
00253 //     std::vector<F> result(seq.size());
00254 //     std::vector<uint> sortedIdx = seq;
00255 //     sort(sortedIdx.begin(), sortedIdx.end());
00256 //     sortedIdx.erase(unique(sortedIdx.begin(), sortedIdx.end()), 
00257 //        sortedIdx.end());
00258 
00259 //     uint i = 0;
00260 //     std::vector<uint>::const_iterator is = sortedIdx.begin();
00261 //     typename std::vector<F>::const_iterator it = this->begin();
00262 //     typename std::vector<F>::iterator ir = result.begin();
00263 //     while(is != sortedIdx.end() && it != this->end()) {
00264 //       if (i == *is) {
00265 //  *ir = *it;
00266 //  ++ir;
00267 //  ++is;
00268 //       }
00269 //       ++it; ++i;
00270 //     }
00271 //     conceptsAssert(is == sortedIdx.end(), Assertion());
00272 //     return result;
00273 //   }
00274 
00275   template<class F>
00276   Sequence<F> BaseSequence<F>::operator()(const BaseSequence<bool>& seq) const {
00277     conceptsAssert(this->size() == seq.size(), Assertion());
00278 
00279     std::vector<F> result(count(seq.begin(), seq.end(), true));
00280     if (result.size() > 0) {
00281       std::vector<bool>::const_iterator is = seq.begin();
00282       typename std::vector<F>::const_iterator it = this->begin();
00283       typename std::vector<F>::iterator i = result.begin();
00284       for(; it != this->end(); ++it, ++is)
00285         if (*is) {
00286           *i = *it;
00287           ++i;
00288         }
00289     }
00290     return result;
00291   }
00292 
00293   template<class F>
00294     bool BaseSequence<F>::exist(F val) const {
00295       return this->find(val) != this->end();
00296     }
00297 
00298   template<class F>
00299     std::ostream& BaseSequence<F>::info(std::ostream& os) const {
00300       os << "Sequence(";
00301       for(typename std::vector<F>::
00302           const_iterator i = this->begin(); i != this->end();) {
00303         pointerOutput(os, *i);
00304         if (++i != this->end()) os << ", ";
00305       }
00306       return os << ")";
00307     }
00308 
00309   // ******************************************************** Sequence<bool> **
00310 
00311   template<>
00312     class Sequence<bool> : public BaseSequence<bool> {
00313       public:
00315         Sequence() : BaseSequence<bool>() {}
00317         template<class F>
00318           Sequence(const F& seq) : BaseSequence<bool>(seq) {}
00319         virtual ~Sequence() {}
00320 
00322         Sequence<bool> operator&(const Sequence<bool>& seq) const;
00324         Sequence<bool> operator|(const Sequence<bool>& seq) const;
00326         Sequence<bool> operator~() const;
00327     };
00328 
00329   // ************************************************************ makeSequence **
00330 
00338   template<class F>
00339   Sequence<F> makeSequence(uint n, const F& first, ...) {
00340     Sequence<F> data(n);
00341     data[0] = first;
00342 
00343     va_list param;
00344     va_start(param, first);
00345     for(uint i = 1; i < n; ++i)
00346       data[i] = va_arg(param, F);
00347     va_end(param);  
00348     return data;
00349   }
00350 
00351 } // namespace concepts
00352 
00353 #endif // sequence_hh

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