00001 #ifndef __ENSEMBLE_H
00002 #define __ENSEMBLE_H
00003
00004 #include <list>
00005 #include <vector>
00006 #include <iostream>
00007
00009 template<typename T>
00010 struct Propriete
00011 {
00017 virtual bool operator() (const T &) const= 0;
00018 };
00019
00020 template <typename T >
00021 class Ensemble;
00022
00024 template <typename T >
00025 class Partie
00026 {
00027 protected:
00028
00029 Ensemble<T> * ens;
00030 std::list<unsigned> ids;
00031
00032 template <typename U> friend std::ostream & operator<< (std::ostream & flux, const Partie<U> & );
00033
00035 friend class Ensemble<T>;
00036
00037 T get(unsigned i) const {return *(ens->elements[i]); }
00038
00040 void push(unsigned j)
00041 {
00042 if( ids.size() && j != ids.back() )
00043 ids.push_back(j);
00044 else
00045 if(!ids.size())
00046 ids.push_back(j);
00047 }
00048
00049 private:
00050 struct Inter
00051 {
00052 bool operator() (unsigned i, unsigned j) const { return i==j; }
00053 };
00054
00055 struct Union
00056 {
00057 bool operator() (unsigned i, unsigned j) const { return true; }
00058 };
00059
00060 template <typename Foncteur>
00061 Partie parallel(const Partie & p,const Foncteur & f) const
00062 {
00063 Partie ret(ens);
00064 std::list<unsigned>::const_iterator i = ids.begin();
00065 std::list<unsigned>::const_iterator j = p.ids.begin();
00066 while( i != ids.end() && j != p.ids.end() )
00067 {
00068 if(*i <= *j)
00069 {
00070 if( f(*i,*j)==true )
00071 ret.push(*i);
00072 ++i;
00073 }
00074 else
00075 {
00076 if( f(*i,*j)==true )
00077 ret.push(*j);
00078 ++j;
00079 }
00080 }
00081 if( i != ids.end() )
00082 while( i != ids.end() )
00083 {
00084 if( f(*i,*j)==true )
00085 ret.push(*i);
00086 ++i;
00087 }
00088 else
00089 while( j != p.ids.end() )
00090 {
00091 if( f(*i,*j)==true )
00092 ret.push(*j);
00093 ++j;
00094 }
00095
00096 return ret;
00097 }
00098
00099
00100
00101 public:
00102
00106 Partie(Ensemble<T> * _ens = 0 ):ens(_ens) {}
00107
00109 Partie(const Partie & p) { *this=p;}
00110
00112 Partie & operator= ( const Partie & p)
00113 {
00114 if(this!=&p)
00115 {
00116 ens = p.ens;
00117 ids = p.ids;
00118 }
00119 return *this;
00120 }
00121
00123 Partie & operator= (const Ensemble<T> & _ens)
00124 {
00125 ens = const_cast<Ensemble<T> *>(&_ens);
00126 for(unsigned i =0; i < ens->elements.size(); ++i)
00127 ids.push_back(i);
00128 return *this;
00129 }
00130
00134 Partie _union(const Partie & partie) const
00135 {
00136 return parallel(partie,Union());
00137 }
00138
00142 Partie _inter(const Partie & partie) const
00143 {
00144 return parallel(partie,Inter());
00145 }
00146
00150 Partie _compl(const Partie & partie) const
00151 {
00152 Partie ret(ens);
00153 std::list<unsigned>::const_iterator i = ids.begin();
00154 std::list<unsigned>::const_iterator j = partie.ids.begin();
00155
00156 while( i!= ids.end() && j != partie.ids.end())
00157 {
00158 if(*i <= *j)
00159 {
00160 if(*i != *j)
00161 ret.ids.push_back(*i);
00162 ++i;
00163 }
00164 else
00165 ++j;
00166 }
00167 while(i!=ids.end())
00168 {
00169 ret.ids.push_back(*i);
00170 ++i;
00171 }
00172
00173 return ret;
00174 }
00175
00177 std::list<unsigned> GetIds() const { return ids;}
00178
00180 std::list<T> Get() const
00181 {
00182 std::list<T> ret;
00183 for(std::list<unsigned>::const_iterator i = ids.begin();
00184 i != ids.end();
00185 ++i)
00186 ret.push_back(ens->Get(i));
00187 return ret;
00188 }
00189
00191 unsigned Size() const { return ids.size();}
00192
00193 ~Partie() {}
00194 };
00195
00197
00201 template <typename T >
00202 class Ensemble
00203 {
00204 private:
00205 std::vector< T * > elements;
00207 template <typename U> friend std::ostream & operator<< (std::ostream & flux, const Ensemble<U> & ens);
00209 friend class Partie<T>;
00210 public:
00211 typedef Partie<T> Partie;
00213 Ensemble() {}
00215 Ensemble( const Ensemble & ens) { *this=ens;}
00217 Ensemble & operator= ( const Ensemble & ens)
00218 {
00219 if(this!=&ens)
00220 {
00221 for(unsigned i = 0; i < elements.size(); ++i)
00222 delete elements[i];
00223 for(unsigned i = 0; i < ens.elements.size(); ++i )
00224 elements.push_back( new T(*(ens.elements[i])) );
00225 }
00226 return *this;
00227 }
00228
00230 Ensemble( std::list<T> base)
00231 {
00232 typename std::list<T>::iterator iterList = base.begin();
00233 for( ; iterList != base.end(); ++iterList)
00234 elements.push_back( new T(*iterList));
00235 }
00236
00241 Partie partie( const Propriete<T> & p)
00242 {
00243 Partie ret(this);
00244 for(unsigned i=0; i<elements.size(); ++i )
00245 if( p( *(elements[i]) ))
00246 ret.ids.push_back( i );
00247 return ret;
00248 }
00249
00251 Partie all()
00252 {
00253 Partie ret;
00254 ret = *this;
00255 return ret;
00256 }
00257
00259 T Get(unsigned i) const { return *(elements[i]);}
00261 T & Get(unsigned i) { return *(elements[i]);}
00263 unsigned Size() const { return elements.size();}
00264
00266 void Add( const T & element)
00267 {
00268 elements.push_back( new T(element) );
00269 }
00270
00272 ~Ensemble()
00273 {
00274 for(unsigned i = 0; i < elements.size(); ++i)
00275 delete elements[i];
00276 }
00277 };
00278
00279 template<typename T>
00280 Partie<T> operator& (const Partie<T>&a, const Partie<T> &b)
00281 {
00282 return a._inter(b);
00283 }
00284
00285 template<typename T>
00286 Partie<T> operator| (const Partie<T> &a, const Partie<T> &b)
00287 {
00288 return a._union(b);
00289 }
00290
00291 template<typename T>
00292 Partie<T> operator/ (const Partie<T> &a, const Partie<T>& b)
00293 {
00294 return a._compl(b);
00295 }
00296
00297 template<typename T>
00298 Partie<T> operator/ (const Ensemble<T>& e, const Partie<T> & b)
00299 {
00300 Partie<T> all;
00301 all = e;
00302 return all._compl(b);
00303 }
00304
00305 template <typename T>
00306 std::ostream & operator<< (std::ostream & flux, const Ensemble<T> & ens)
00307 {
00308 bool first = true;
00309 flux << "{";
00310 for( unsigned i = 0;i < ens.elements.size();++i)
00311 {
00312 flux << (first?"":", ") << *(ens.elements[i]);
00313 first=false;
00314 }
00315 flux << "}";
00316 return flux;
00317 }
00318
00319 template <typename T>
00320 std::istream & operator>> (std::istream & flux, Ensemble<T> & ens)
00321 {
00322 T tmp;
00323 flux >> tmp;
00324 ens.Add(tmp);
00325 return flux;
00326 }
00327
00328 template <typename T>
00329 std::ostream & operator<< (std::ostream & flux,const Partie<T> & p)
00330 {
00331 bool first = true;
00332 flux << "{";
00333 if(p.ens != 0)
00334 for( std::list<unsigned>::const_iterator i = p.ids.begin(); i != p.ids.end(); ++i)
00335 {
00336 flux << (first?"":", ") << p.get(*i);
00337 first=false;
00338 }
00339 flux << "}";
00340 return flux;
00341 }
00342
00343 #endif