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

adj_m_face_iter.hh

00001 // Copyright (C) 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_TOPO_ADJ_M_FACE_ITER_HH
00027 # define MLN_TOPO_ADJ_M_FACE_ITER_HH
00028 
00034 
00035 # include <set>
00036 # include <vector>
00037 
00038 # include <mln/topo/internal/complex_relative_iterator_base.hh>
00039 # include <mln/topo/face.hh>
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   namespace topo
00046   {
00047 
00048     // Forward declarations.
00049     template <unsigned D> class complex;
00050     namespace internal
00051     {
00052       template <unsigned D> class adj_m_face_iterator;
00053     }
00054 
00055 
00056     /*-------------------------------.
00057     | topo::adj_m_face_fwd_iter<D>.  |
00058     `-------------------------------*/
00059 
00069     template <unsigned D>
00070     class adj_m_face_fwd_iter
00071       : public internal::forward_complex_relative_iterator_base< topo::face<D>,
00072                                                                  algebraic_face<D>,
00073                                                                  adj_m_face_fwd_iter<D> >,
00074         public internal::adj_m_face_iterator<D>
00075     {
00076       // Tech note: we use topo::face to help g++-2.95.
00077     private:
00078       typedef adj_m_face_fwd_iter<D> self_;
00079       typedef internal::forward_complex_relative_iterator_base< topo::face<D>,
00080                                                                 algebraic_face<D>,
00081                                                                 self_ > super_;
00082       typedef internal::adj_m_face_iterator<D> impl_;
00083 
00084     public:
00089       adj_m_face_fwd_iter();
00092       template <typename Fref>
00093       adj_m_face_fwd_iter(const Fref& f_ref, unsigned m);
00095 
00100       void update_adj_faces_();
00101     };
00102 
00103 
00104     /*-------------------------------.
00105     | topo::adj_m_face_bkd_iter<D>.  |
00106     `-------------------------------*/
00107 
00117     template <unsigned D>
00118     class adj_m_face_bkd_iter
00119       : public internal::backward_complex_relative_iterator_base< topo::face<D>,
00120                                                                   algebraic_face<D>,
00121                                                                   adj_m_face_bkd_iter<D> >,
00122         public internal::adj_m_face_iterator<D>
00123     {
00124       // Tech note: we use topo::face to help g++-2.95.
00125     private:
00126       typedef adj_m_face_bkd_iter<D> self_;
00127       typedef internal::backward_complex_relative_iterator_base< topo::face<D>,
00128                                                                  algebraic_face<D>,
00129                                                                  self_ > super_;
00130       typedef internal::adj_m_face_iterator<D> impl_;
00131 
00132     public:
00137       adj_m_face_bkd_iter();
00140       template <typename Fref>
00141       adj_m_face_bkd_iter(const Fref& f_ref, unsigned m);
00143 
00148       void update_adj_faces_();
00149     };
00150 
00151 
00152     /*-----------------------------------------.
00153     | topo::internal::adj_m_face_iterator<D>.  |
00154     `-----------------------------------------*/
00155 
00156     namespace internal
00157     {
00158 
00159       template <unsigned D>
00160       class adj_m_face_iterator
00161       {
00162       protected:
00163         adj_m_face_iterator();
00164         adj_m_face_iterator(unsigned m);
00165 
00166       public:
00168         unsigned m() const;
00170         void set_m(unsigned m);
00171 
00172       protected:
00175         void update_adj_faces__(const topo::face<D>& center,
00176                                 std::vector< algebraic_face<D> >& adj_faces);
00177 
00179         unsigned m_;
00180       };
00181 
00182     } // end of namespace mln::topo::internal
00183 
00184 
00185 
00186 # ifndef MLN_INCLUDE_ONLY
00187 
00188     /*-------------------------------.
00189     | topo::adj_m_face_fwd_iter<D>.  |
00190     `-------------------------------*/
00191 
00192     template <unsigned D>
00193     inline
00194     adj_m_face_fwd_iter<D>::adj_m_face_fwd_iter()
00195     {
00196     }
00197 
00198     template <unsigned D>
00199     template <typename Fref>
00200     inline
00201     adj_m_face_fwd_iter<D>::adj_m_face_fwd_iter(const Fref& f_ref, unsigned m)
00202       : super_(f_ref), impl_(m)
00203     {
00204     }
00205 
00206     template <unsigned D>
00207     inline
00208     void
00209     adj_m_face_fwd_iter<D>::update_adj_faces_()
00210     {
00211       mln_precondition(this->c_);
00212       // Delegate computation to base class.
00213       this->update_adj_faces__(*this->c_, this->adj_faces_);
00214     }
00215 
00216 
00217     /*-------------------------------.
00218     | topo::adj_m_face_bkd_iter<D>.  |
00219     `-------------------------------*/
00220 
00221     template <unsigned D>
00222     inline
00223     adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter()
00224     {
00225     }
00226 
00227     template <unsigned D>
00228     template <typename Fref>
00229     inline
00230     adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter(const Fref& f_ref, unsigned m)
00231       : super_(f_ref), impl_(m)
00232     {
00233     }
00234 
00235     template <unsigned D>
00236     inline
00237     void
00238     adj_m_face_bkd_iter<D>::update_adj_faces_()
00239     {
00240       mln_precondition(this->c_);
00241       // Delegate computation to base class.
00242       this->update_adj_faces__(*this->c_, this->adj_faces_);
00243     }
00244 
00245 
00246     /*-----------------------------------------.
00247     | topo::internal::adj_m_face_iterator<D>.  |
00248     `-----------------------------------------*/
00249 
00250     namespace internal
00251     {
00252 
00253       template <unsigned D>
00254       inline
00255       adj_m_face_iterator<D>::adj_m_face_iterator()
00256         : m_(0)
00257       {
00258       }
00259 
00260       template <unsigned D>
00261       inline
00262       adj_m_face_iterator<D>::adj_m_face_iterator(unsigned m)
00263         : m_(m)
00264       {
00265         mln_precondition(m <= D);
00266       }
00267 
00268       template <unsigned D>
00269       unsigned
00270       adj_m_face_iterator<D>::m() const
00271       {
00272         return m_;
00273       }
00274 
00275       template <unsigned D>
00276       void
00277       adj_m_face_iterator<D>::set_m(unsigned m)
00278       {
00279         m_ = m;
00280       }
00281 
00282       template <unsigned D>
00283       inline
00284       void
00285       adj_m_face_iterator<D>::update_adj_faces__(const topo::face<D>& center,
00286                                                  std::vector< algebraic_face<D> >& adj_faces)
00287       {
00288         adj_faces.clear();
00289 
00290         if (center.n() == m_)
00291           return;
00292 
00293         typedef std::vector < topo::algebraic_face<D> > faces_t;
00294         typedef std::set < topo::algebraic_face<D> > faces_set_t;
00295 
00296         /* FIXME: p_faces is redundant; we could use adj_faces
00297            directly.  */
00298         /* The adjacent p-faces being built; initialized with CENTER,
00299            and filled with q-faces at each step, until q reaches
00300            m_.  */
00301         faces_t p_faces(1,
00302                         make_algebraic_face(center, true));
00303         // The set of faces being built.
00304         /* FIXME: This pattern is recurring in Milena---using an
00305            std::set (or any fast associative container) to improve
00306            the lookup speed of an std::vector; we should create a
00307            class for this, a bit like mln::util::set, but with a
00308            garantee on the order of insertion.  */
00309         faces_t work_faces;
00310         faces_set_t work_faces_set;
00311 
00312         // Iteratively compute the set of locations.
00313         for (unsigned p = center.n(); p != m_; (p < m_ ? ++p : --p) )
00314           {
00315             mln_invariant (p != m_);
00316             for (typename faces_t::const_iterator g = p_faces.begin();
00317                  g != p_faces.end(); ++g)
00318               {
00319                 mln_invariant (g->n() != m_);
00320                 faces_t q_faces = g->n() < m_ ?
00321                   g->higher_dim_adj_faces() :
00322                   g->lower_dim_adj_faces();
00323                 /* Traverse the higher- or lower-dimension adjacent
00324                    faces of G in the natural order if G's sign is
00325                    positive, or in the reverse order if G's sign is
00326                    negative.  */
00327                 /* FIXME: Factor; the code if the two branches is the
00328                    same, except for the iteration order. */
00329                 if (g->sign())
00330                   {
00331                     for (typename faces_t::const_iterator h = q_faces.begin();
00332                          h != q_faces.end(); ++h)
00333                       // Don't insert a face twice.
00334                       if (work_faces_set.find(*h) == work_faces_set.end())
00335                         {
00336                           work_faces.push_back(*h);
00337                           work_faces_set.insert(*h);
00338                         }
00339                   }
00340                 else
00341                   {
00342                     for (typename faces_t::const_reverse_iterator h =
00343                            q_faces.rbegin();
00344                          /* This is crazy.  With Apple g++ 4.0, this
00345                             code won't compile without this cast!
00346                             This is solved in MacPorts g++ 4.3.  */
00347                          h != (typename faces_t::const_reverse_iterator) q_faces.rend();
00348                          ++h)
00349                       // Don't insert a face twice.
00350                       if (work_faces_set.find(*h) == work_faces_set.end())
00351                         {
00352                           work_faces.push_back(*h);
00353                           work_faces_set.insert(*h);
00354                         }
00355                   }
00356               }
00357             work_faces.swap(p_faces);
00358             work_faces.clear();
00359             work_faces_set.clear();
00360           }
00361 
00362         adj_faces = p_faces;
00363       }
00364 
00365     } // end of namespace mln::topo::internal
00366 
00367 # endif // ! MLN_INCLUDE_ONLY
00368 
00369   } // end of namespace mln::topo
00370 
00371 } // end of namespace mln
00372 
00373 #endif // ! MLN_TOPO_ADJ_M_FACE_ITER_HH

Generated on Tue Oct 4 2011 15:23:24 for Milena (Olena) by  doxygen 1.7.1