Page principale | Hiérarchie des classes | Liste des composants | Liste des fichiers | Composants

Ensemble.h

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

Généré le Mon Jul 18 23:07:40 2005 pour Modelib par doxygen 1.3.6