Modelib: Fichier source de Ensemble.h

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