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

toolbox/set.hh
Go to the documentation of this file.
00001 /* Set with operations, output operator, and method of the
00002    particular element types.
00003  */
00004 
00005 #ifndef set_hh
00006 #define set_hh
00007 
00008 #include <set>
00009 #include <algorithm>
00010 #include <iterator>
00011 #include <stdarg.h>
00012 #include <basics/debug.hh>
00013 #include <basics/outputOperator.hh>
00014 #include <basics/exceptions.hh>
00015 #include <basics/pointerOutput.hh>
00016 #include "array.hh"
00017 
00018 #define SetInput_D 0
00019 
00020 namespace concepts {
00021 
00022   // forward declaration
00023   template<class F>
00024   class BaseSet;
00025 
00026   // ******************************************************************* Set **
00027 
00034   template<class F>
00035   class Set : public BaseSet<F> {
00036   public:
00037     Set() : BaseSet<F>() {}
00038     Set(const F& val) : BaseSet<F>() { insert(val); }
00039     template<class G>
00040     Set(const G& set) : BaseSet<F>(set) {}
00041     virtual ~Set() {}
00042   };
00043 
00044  // *************************************************************** BaseSet **
00045 
00050   template<class F>
00051   class BaseSet : public std::set<F>, public OutputOperator {
00052   public:
00054     BaseSet() : std::set<F>() {}
00060     BaseSet(const std::string& str);
00064     BaseSet(const concepts::Array<F>& a);
00066     template<class G>
00067     BaseSet(const G& set) : std::set<F>(set) {}
00068     virtual ~BaseSet() {}
00069 
00072     template<class G, class H>
00073     inline Set<G> operator()(G (H::*fun)() const) const;
00077     template<class G, class H>
00078     inline Set<G*> operator()(G& (H::*fun)() const) const;
00082     template<class G, class H, class I, class J>
00083     inline Set<G> operator()(G (H::*fun)(I) const, J i) const;
00084 
00085     // Return set union
00086     inline Set<F> operator||(const Set<F>& set) const;
00087     inline Set<F> operator||(Set<F>& set) const;
00088     // Return set intersection
00089     inline Set<F> operator&&(const Set<F>& set) const;
00090     inline Set<F> operator&&(Set<F>& set) const;
00091     // Return set difference
00092     inline Set<F> operator-(const Set<F>& set) const;
00093     inline Set<F> operator-(Set<F>& set) const;
00095     inline Set<uint> operator==(const F val) const;
00097     inline Set<F> operator()(const Set<uint>& set) const;
00098 
00099     // Return set union
00100     inline BaseSet<F>& operator|=(const Set<F>& set);
00101 
00103     inline bool exist(F val) const;
00105     inline bool isempty() const { return this->begin() == this->end(); }
00106   protected:
00107     virtual std::ostream& info(std::ostream& os) const;
00108 
00109     typedef typename std::set<F>::const_iterator const_iterator_;
00110     typedef typename std::insert_iterator<std::set<F> > insert_iterator_;
00114     virtual void union_(const_iterator_ first, const_iterator_ last,
00115                         insert_iterator_ i) const;
00119     virtual void intersection_(const_iterator_ first, const_iterator_ last,
00120                                insert_iterator_ i) const;
00124     virtual void difference_(const_iterator_ first, const_iterator_ last,
00125                              insert_iterator_ i) const;
00126   };
00127 
00128   template<class F>
00129   void operator>>(std::istream& is, BaseSet<F>& set) {
00130     F val;
00131     while(!is.eof()) {
00132       is >> val;
00133       DEBUGL(SetInput_D, "val = " << val);
00134       if (!is.fail())
00135         set.insert(val);
00136     }
00137   }
00138 
00139   template<class F>
00140   BaseSet<F>::BaseSet(const std::string& str) {
00141     if (str.size() > 0) {
00142       std::stringstream s;
00143       s << str;
00144       s >> *this;
00145     }
00146   }
00147 
00148   template<class F>
00149   BaseSet<F>::BaseSet(const concepts::Array<F>& a) {
00150     const F* e = (const F*)a;
00151     for(uint i = a.size(); i--;) this->insert(*e++);
00152   }
00153 
00154   // e.g. Key::key()
00155   template<class F>
00156   template<class G, class H>
00157   Set<G> BaseSet<F>::operator()(G (H::*fun)() const) const {
00158     std::set<G> set;
00159     for(const_iterator_ i = this->begin(); i != this->end(); ++i) {
00160       G val = ((*i)->*fun)();
00161       set.insert(val);
00162     }
00163     return set;
00164   }
00165   // e.g. Connector1::key()
00166   template<class F>
00167   template<class G, class H>
00168   Set<G*> BaseSet<F>::operator()(G& (H::*fun)() const) const {
00169     std::set<G*> set;
00170     for(const_iterator_ i = this->begin(); i != this->end();++i) {
00171       G* val = &((*i)->*fun)();
00172       set.insert(val);
00173     }
00174     return set;
00175   }
00176   // e.g. Connector1::vertex(uint i)
00177   template<class F>
00178   template<class G, class H, class I, class J>
00179   Set<G> BaseSet<F>::operator()(G (H::*fun)(I) const, J i) const {
00180     std::set<G> set;
00181     for(const_iterator_ is = this->begin(); is != this->end();++is) {
00182       G val = ((*is)->*fun)(i);
00183       set.insert(val);
00184     }
00185     return set;
00186   }
00187 
00188   template<class F>
00189   Set<F> BaseSet<F>::operator||(const Set<F>& set) const {
00190     std::set<F> result;
00191     union_(set.begin(), set.end(), inserter(result, result.begin()));
00192     return result;
00193   }
00194 
00195   template<class F>
00196   Set<F> BaseSet<F>::operator||(Set<F>& set) const {
00197     std::set<F> result;
00198     union_(set.begin(), set.end(), inserter(result, result.begin()));
00199     return result;
00200   }
00201 
00202   template<class F>
00203   Set<F> BaseSet<F>::operator&&(const Set<F>& set) const {
00204     std::set<F> result;
00205     intersection_(set.begin(), set.end(), inserter(result, result.begin()));
00206     return result;
00207   }
00208 
00209   template<class F>
00210   Set<F> BaseSet<F>::operator&&(Set<F>& set) const {
00211     std::set<F> result;
00212     intersection_(set.begin(), set.end(), inserter(result, result.begin()));
00213     return result;
00214   }
00215 
00216   template<class F>
00217   void BaseSet<F>::intersection_
00218   (const_iterator_ first, const_iterator_ last, insert_iterator_ i) const {
00219     set_intersection(this->begin(), this->end(), first, last, i);
00220   }
00221 
00222   template<class F>
00223   void BaseSet<F>::union_
00224   (const_iterator_ first, const_iterator_ last, insert_iterator_ i) const {
00225     set_union(this->begin(), this->end(), first, last, i);
00226   }
00227 
00228   template<class F>
00229   void BaseSet<F>::difference_
00230   (const_iterator_ first, const_iterator_ last, insert_iterator_ i) const {
00231     set_difference(this->begin(), this->end(), first, last, i);
00232   }
00233     
00234   template<class F>
00235   Set<F> BaseSet<F>::operator-(const Set<F>& set) const {
00236     std::set<F> result;
00237     difference_(set.begin(), set.end(), inserter(result, result.begin()));
00238     return result;
00239   }
00240 
00241   template<class F>
00242   Set<F> BaseSet<F>::operator-(Set<F>& set) const {
00243     std::set<F> result;
00244     difference_(set.begin(), set.end(), inserter(result, result.begin()));
00245     return result;
00246   }
00247 
00248   template<class F>
00249   Set<uint> BaseSet<F>::operator==(const F val) const {
00250     std::set<uint> result;
00251     uint i = 0;
00252     for(const_iterator_ is = this->begin(); is != this->end(); ++is, ++i)
00253       if (*is == val) result.insert(i);
00254     return result;
00255   }
00256 
00257   template<class F>
00258   Set<F> BaseSet<F>::operator()(const Set<uint>& set) const {
00259     std::set<F> result;
00260     uint i = 0;
00261     typename std::set<uint>::const_iterator it = set.begin();
00262     const_iterator_ is = this->begin();
00263     while(it != set.end() && is != this->end()) {
00264       if (i == *it) {
00265         result.insert(*is);
00266         ++it;
00267       }
00268       ++is; ++i;
00269     }
00270     conceptsAssert(it == set.end(), Assertion());
00271     return result;
00272   }
00273 
00274   template<class F>
00275   BaseSet<F>& BaseSet<F>::operator|=(const Set<F>& set) {
00276     set_union(this->begin(), this->end(),
00277               set.begin(), set.end(),
00278               inserter(*this, this->begin())); 
00279     return *this;
00280   }
00281 
00282   template<class F>
00283   bool BaseSet<F>::exist(F val) const {
00284     return this->find(val) != this->end();
00285   }
00286 
00287   template<class F>
00288   std::ostream& BaseSet<F>::info(std::ostream& os) const {
00289     os << "Set(";
00290     for(const_iterator_ i = this->begin(); i != this->end();) {
00291       pointerOutput(os, *i);
00292       if (++i != this->end()) os << ", ";
00293     }
00294     return os << ")";
00295   }
00296 
00297   // *************************************************************** makeSet **
00298 
00306   template<class F>
00307   Set<F> makeSet(uint n, const F& first, ...) {
00308     Set<F> data;
00309     data.insert(first);
00310 
00311     va_list param;
00312     va_start(param, first);
00313     for(uint i = 1; i < n; ++i)
00314       data.insert(va_arg(param, F));
00315     va_end(param);  
00316     return data;
00317   }
00318 
00319 
00320 } // namespace concepts
00321 
00322 #endif // set_hh

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