Page principale | Liste des namespaces | Hiérarchie des classes | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de namespace | Membres de classe | Membres de fichier

Ensemble.h

Aller à la documentation de ce fichier.
00001 /*
00002     Copyright (c) 2005, Quentin Lequy and Romain Gaucher
00003     All rights reserved.
00004 
00005     Redistribution and use in source and binary forms, with or 
00006     without modification, are permitted provided that the following 
00007     conditions are met:
00008 
00009         * Redistributions of source code must retain the above copyright 
00010           notice, this list of conditions and the following disclaimer.
00011 
00012         * Redistributions in binary form must reproduce the above copyright 
00013           notice, this list of conditions and the following disclaimer in the 
00014           documentation and/or other materials provided with the distribution.
00015 
00016         * Neither the name of Quentin Lequy or Romain Gaucher nor the names 
00017           of its contributors may be used to endorse or promote products 
00018           derived from this software without specific prior written permission.
00019 
00020     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00021     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00022     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00023     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00024     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00025     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00026     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
00027     AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00028     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00029     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 //    template <typename U> friend std::ostream & operator<< (std::ostream & flux, const Partie<U> & );
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 //    template <typename U> 
00242 //   friend std::ostream & operator<< (std::ostream & flux, const Ensemble<U> & ens);
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

Généré le Sun Oct 2 19:13:11 2005 pour Modelib par  doxygen 1.4.4