00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __ENSEMBLE_H
00033 #define __ENSEMBLE_H
00034
00035 #include <list>
00036 #include <vector>
00037 #include <iostream>
00038
00039 namespace Modelib {
00040
00042 template<typename T>
00043 struct Propriete
00044 {
00050 virtual bool operator() (const T &) const= 0;
00051 };
00052
00053 template <typename T >
00054 class Ensemble;
00055
00057 template <typename T >
00058 class Partie
00059 {
00060 protected:
00061
00062 Ensemble<T> * ens;
00063 std::list<unsigned> ids;
00064
00065
00066
00068 friend class Ensemble<T>;
00069
00070 T get(unsigned i) const {return *(ens->elements[i]); }
00071
00073 void push(unsigned j)
00074 {
00075 if( ids.size() && j != ids.back() )
00076 ids.push_back(j);
00077 else
00078 if(!ids.size())
00079 ids.push_back(j);
00080 }
00081
00082 private:
00083 struct Inter
00084 {
00085 bool operator() (unsigned i, unsigned j) const { return i==j; }
00086 };
00087
00088 struct Union
00089 {
00090 bool operator() (unsigned i, unsigned j) const { return true; }
00091 };
00092
00093 template <typename Foncteur>
00094 Partie parallel(const Partie & p,const Foncteur & f) const
00095 {
00096 Partie ret(ens);
00097 std::list<unsigned>::const_iterator i = ids.begin();
00098 std::list<unsigned>::const_iterator j = p.ids.begin();
00099 while( i != ids.end() && j != p.ids.end() )
00100 {
00101 if(*i <= *j)
00102 {
00103 if( f(*i,*j)==true )
00104 ret.push(*i);
00105 ++i;
00106 }
00107 else
00108 {
00109 if( f(*i,*j)==true )
00110 ret.push(*j);
00111 ++j;
00112 }
00113 }
00114 if( i != ids.end() )
00115 while( i != ids.end() )
00116 {
00117 if( f(*i,*j)==true )
00118 ret.push(*i);
00119 ++i;
00120 }
00121 else
00122 while( j != p.ids.end() )
00123 {
00124 if( f(*i,*j)==true )
00125 ret.push(*j);
00126 ++j;
00127 }
00128
00129 return ret;
00130 }
00131
00132
00133
00134 public:
00135
00139 Partie(Ensemble<T> * _ens = 0 ):ens(_ens) {}
00140
00142 Partie(const Partie & p) { *this=p;}
00143
00145 Partie & operator= ( const Partie & p)
00146 {
00147 if(this!=&p)
00148 {
00149 ens = p.ens;
00150 ids = p.ids;
00151 }
00152 return *this;
00153 }
00154
00156 Partie & operator= (const Ensemble<T> & _ens)
00157 {
00158 ens = const_cast<Ensemble<T> *>(&_ens);
00159 for(unsigned i =0; i < ens->elements.size(); ++i)
00160 ids.push_back(i);
00161 return *this;
00162 }
00163
00167 Partie _union(const Partie & partie) const
00168 {
00169 return parallel(partie,Union());
00170 }
00171
00175 Partie _inter(const Partie & partie) const
00176 {
00177 return parallel(partie,Inter());
00178 }
00179
00183 Partie _compl(const Partie & partie) const
00184 {
00185 Partie ret(ens);
00186 std::list<unsigned>::const_iterator i = ids.begin();
00187 std::list<unsigned>::const_iterator j = partie.ids.begin();
00188
00189 while( i!= ids.end() && j != partie.ids.end())
00190 {
00191 if(*i <= *j)
00192 {
00193 if(*i != *j)
00194 ret.ids.push_back(*i);
00195 ++i;
00196 }
00197 else
00198 ++j;
00199 }
00200 while(i!=ids.end())
00201 {
00202 ret.ids.push_back(*i);
00203 ++i;
00204 }
00205
00206 return ret;
00207 }
00208
00210 inline std::list<unsigned> GetIds() const { return ids;}
00211
00213 std::list<T> Get() const
00214 {
00215 std::list<T> ret;
00216 if(ens)
00217 for(std::list<unsigned>::const_iterator i = ids.begin();
00218 i != ids.end();
00219 ++i)
00220 ret.push_back(ens->Get(*i));
00221 return ret;
00222 }
00223
00225 unsigned Size() const { return ids.size();}
00226
00227 ~Partie() {}
00228 };
00229
00231
00235 template <typename T >
00236 class Ensemble
00237 {
00238 private:
00239 std::vector< T * > elements;
00241
00242
00244 friend class Partie<T>;
00245 public:
00246 typedef Partie<T> Partie;
00248 Ensemble() {}
00250 Ensemble( const Ensemble & ens) { *this=ens;}
00252 Ensemble & operator= ( const Ensemble & ens)
00253 {
00254 if(this!=&ens)
00255 {
00256 for(unsigned i = 0; i < elements.size(); ++i)
00257 delete elements[i];
00258 for(unsigned i2 = 0; i2 < ens.elements.size(); ++i2 )
00259 elements.push_back( new T(*(ens.elements[i2])) );
00260 }
00261 return *this;
00262 }
00263
00265 Ensemble( const std::list<T>& base)
00266 {
00267 typename std::list<T>::const_iterator iterList = base.begin();
00268 for( ; iterList != base.end(); ++iterList)
00269 elements.push_back( new T(*iterList));
00270 }
00271
00276 Partie partie( const Propriete<T> & p)
00277 {
00278 Partie ret(this);
00279 for(unsigned i=0; i<elements.size(); ++i )
00280 if( p( *(elements[i]) ))
00281 ret.ids.push_back( i );
00282 return ret;
00283 }
00284
00286 Partie all()
00287 {
00288 Partie ret;
00289 ret = *this;
00290 return ret;
00291 }
00292
00294 T Get(unsigned i) const { return *(elements[i]);}
00296 T & Get(unsigned i) { return *(elements[i]);}
00298 unsigned Size() const { return elements.size();}
00299
00301 void Add( const T & element)
00302 {
00303 elements.push_back( new T(element) );
00304 }
00305
00307 ~Ensemble()
00308 {
00309 for(unsigned i = 0; i < elements.size(); ++i)
00310 delete elements[i];
00311 }
00312 };
00313
00314 template<typename T>
00315 Partie<T> operator& (const Partie<T>&a, const Partie<T> &b)
00316 {
00317 return a._inter(b);
00318 }
00319
00320 template<typename T>
00321 Partie<T> operator| (const Partie<T> &a, const Partie<T> &b)
00322 {
00323 return a._union(b);
00324 }
00325
00326 template<typename T>
00327 Partie<T> operator/ (const Partie<T> &a, const Partie<T>& b)
00328 {
00329 return a._compl(b);
00330 }
00331
00332 template<typename T>
00333 Partie<T> operator/ (const Ensemble<T>& e, const Partie<T> & b)
00334 {
00335 Partie<T> all;
00336 all = e;
00337 return all._compl(b);
00338 }
00339
00340 template <typename T>
00341 std::ostream & operator<< (std::ostream & flux, const Ensemble<T> & ens)
00342 {
00343 bool first = true;
00344 flux << "{";
00345 for( unsigned i = 0;i < ens.Size();++i)
00346 {
00347 flux << (first?"":", ") << ens.Get(i);
00348 first=false;
00349 }
00350 flux << "}";
00351 return flux;
00352 }
00353
00354 template <typename T>
00355 std::istream & operator>> (std::istream & flux, Ensemble<T> & ens)
00356 {
00357 T tmp;
00358 flux >> tmp;
00359 ens.Add(tmp);
00360 return flux;
00361 }
00362
00363 template <typename T>
00364 std::ostream & operator<< (std::ostream & flux,const Partie<T> & p)
00365 {
00366 bool first = true;
00367 flux << "{";
00368 std::list<T> liste = p.Get();
00369 typename std::list<T>::iterator i;
00370 for( i = liste.begin(); i != liste.end(); ++i)
00371 {
00372 flux << (first?"":", ") << *i;
00373 first=false;
00374 }
00375 flux << "}";
00376 return flux;
00377 }
00378
00379 }
00380
00381 #endif