• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

lazy_set.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_UTIL_LAZY_SET_HH
00027 # define MLN_UTIL_LAZY_SET_HH
00028 
00034 # include <vector>
00035 # include <set>
00036 # include <iterator>
00037 # include <algorithm>
00038 
00039 # include <mln/core/internal/force_exact.hh>
00040 # include <mln/core/contract.hh>
00041 
00042 
00043 namespace mln
00044 {
00045 
00046   namespace util
00047   {
00048 
00065     template <typename E>
00066     class lazy_set_
00067     {
00068     public:
00069 
00071       typedef E value;
00072 
00081       lazy_set_<E>& insert(const E& elt);
00082 
00083 
00092       lazy_set_<E>& remove(const E& elt);
00093 
00094 
00103       const E& element(unsigned i) const;
00104 
00113       const E& operator[](unsigned i) const;
00114 
00117       unsigned nelements() const;
00118 
00119 
00126       bool has(const E& elt) const;
00127 
00128 
00131       bool is_empty() const;
00132 
00133 
00143       void clear();
00144 
00145 
00152       const std::vector<E>& vect() const;
00153 
00155       lazy_set_();
00156 
00167       void set_const_mode(bool mode);
00168 
00170       bool get_mode() const;
00171 
00172     private:
00173 
00179       mutable std::vector<E> v_;
00180 
00185       std::set<E> s_;
00186 
00187 
00192       void update_() const;
00193 
00195       mutable bool needs_update_;
00196 
00198       bool mode_;
00199     };
00200 
00201 
00202 # ifndef MLN_INCLUDE_ONLY
00203 
00204     template <typename E>
00205     inline
00206     lazy_set_<E>::lazy_set_()
00207     {
00208       needs_update_ = false;
00209       mode_ = false;
00210     }
00211 
00212     template <typename E>
00213     inline
00214     lazy_set_<E>&
00215     lazy_set_<E>::insert(const E& elt)
00216     {
00217       mln_assertion(!mode_);
00218       s_.insert(elt);
00219       if (needs_update_ == false)
00220         needs_update_ = true;
00221       return mln::internal::force_exact< lazy_set_<E> >(*this);
00222     }
00223 
00224     template <typename E>
00225     inline
00226     lazy_set_<E>&
00227     lazy_set_<E>::remove(const E& elt)
00228     {
00229       mln_assertion(!mode_);
00230       // FIXME : doesn't compile
00231       std::remove(s_.begin(), s_.end(), elt);
00232       if (needs_update_ == false)
00233         needs_update_ = true;
00234       return mln::internal::force_exact< lazy_set_<E> >(*this);
00235     }
00236 
00237     template <typename E>
00238     inline
00239     const E&
00240     lazy_set_<E>::element(unsigned i) const
00241     {
00242       assert((!mode_ && i < s_.size())
00243              || i < v_.size());
00244       if (!mode_)
00245         if (needs_update_)
00246           update_();
00247       return v_[i];
00248     }
00249 
00250     template <typename E>
00251     inline
00252     const E&
00253     lazy_set_<E>::operator[](unsigned i) const
00254     {
00255       return this->element(i);
00256     }
00257 
00258     template <typename E>
00259     inline
00260     unsigned
00261     lazy_set_<E>::nelements() const
00262     {
00263       if (!mode_)
00264         return s_.size();
00265       else
00266         return v_.size();
00267     }
00268 
00269     template <typename E>
00270     inline
00271     bool
00272     lazy_set_<E>::has(const E& elt) const
00273     {
00274       if (!mode_)
00275         return s_.find(elt) != s_.end();
00276       else
00277         return v_.find(elt) != v_.end();
00278     }
00279 
00280     template <typename E>
00281     inline
00282     bool
00283     lazy_set_<E>::is_empty() const
00284     {
00285       return nelements() == 0;
00286     }
00287 
00288     template <typename E>
00289     inline
00290     void
00291     lazy_set_<E>::clear()
00292     {
00293       v_.clear();
00294       s_.clear();
00295       needs_update_ = false;
00296       mode_ = false;
00297       mln_postcondition(is_empty());
00298     }
00299 
00300     template <typename E>
00301     inline
00302     const std::vector<E>&
00303     lazy_set_<E>::vect() const
00304     {
00305       if (!mode_)
00306         if (needs_update_)
00307           update_();
00308       return v_;
00309     }
00310 
00311     template <typename E>
00312     inline
00313     void
00314     lazy_set_<E>::set_const_mode(bool mode)
00315     {
00316       if (mode != mode_)
00317       {
00318         if (mode)
00319         {
00320           if (needs_update_)
00321             update_();
00322           s_.clear();
00323         }
00324         else
00325         {
00326           mln_assertion(s_.size() == 0);
00327           for (typename std::vector<E>::iterator it = v_.begin();
00328                it != v_.end(); it++)
00329             s_.insert(*it);
00330           needs_update_ = false;
00331         }
00332         mode_ = mode;
00333       }
00334     }
00335 
00336     template <typename E>
00337     inline
00338     bool
00339     lazy_set_<E>::get_mode() const
00340     {
00341       return mode_;
00342     }
00343 
00344     template <typename E>
00345     inline
00346     void
00347     lazy_set_<E>::update_() const
00348     {
00349       mln_precondition(needs_update_ && !mode_);
00350       v_.clear();
00351       std::copy(s_.begin(), s_.end(), std::back_inserter(v_));
00352       // no s_.clear() here:
00353       // - we want to keep information up-to-date in s_
00354       // - we want to save some execution time
00355       needs_update_ = false;
00356     }
00357 
00358     // FIXME : ambiguous with site_set operator <<
00359     //     template <typename E>
00360     //     std::ostream& operator<<(std::ostream& ostr,
00361     //                       const lazy_set_<E>& s)
00362     //     {
00363     //       ostr << '[';
00364     //       const unsigned n = s.nelements();
00365     //       for (unsigned i = 0; i < n; ++i)
00366     //  ostr << s.element(i)
00367     //       << (i == s.nelements() - 1 ? ']' : ',');
00368     //       return ostr;
00369     //     }
00370 
00371 # endif // ! MLN_INCLUDE_ONLY
00372 
00373   } // end of namespace mln::util
00374 
00375 } // end of namespace mln
00376 
00377 
00378 #endif // ! MLN_UTIL_LAZY_SET_HH

Generated on Fri Sep 16 2011 16:33:41 for Milena (Olena) by  doxygen 1.7.1