Modelib: Ensemble.h Source File

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