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

multiple_size.hh

00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_WIN_MULTIPLE_SIZE_HH
00028 # define MLN_WIN_MULTIPLE_SIZE_HH
00029 
00035 
00036 # include <mln/core/internal/window_base.hh>
00037 # include <mln/core/internal/site_relative_iterator_base.hh>
00038 # include <mln/util/array.hh>
00039 # include <mln/metal/ands.hh>
00040 
00041 
00042 
00043 namespace mln
00044 {
00045 
00046   // Forward declarations.
00047   namespace win
00048   {
00049     template <unsigned n, typename W, typename F> class multiple_size;
00050     template <unsigned n, typename W, typename F> class multiple_size_qiter;
00051   }
00052 
00053 
00054 
00055   namespace trait
00056   {
00057 
00058     template <unsigned n, typename W, typename F>
00059     struct window_< win::multiple_size<n,W,F> >
00060     {
00061       typedef trait::window::size::unknown     size;
00062       typedef trait::window::support::regular  support;
00063       typedef trait::window::definition::n_ary definition;
00064     };
00065 
00066   } // end of namespace trait
00067 
00068 
00069 
00070   namespace win
00071   {
00072 
00076     //
00077     template <unsigned n, typename W, typename F>
00078     class multiple_size
00079 
00080       : public internal::window_base< mln_dpsite(W), multiple_size<n,W,F> >,
00081 
00082         private metal::ands< mlc_bool(n > 1),
00083                              mlc_is(mln_trait_window_size(W),
00084                                     trait::window::size::fixed),
00085                              mlc_is(mln_trait_window_support(W),
00086                                     trait::window::support::regular) >::check_t
00087     {
00088     public:
00089 
00090       typedef mln_dpsite(W) dpsite;
00091       typedef  mln_psite(W)  psite;
00092       typedef   mln_site(W)   site;
00093 
00094       typedef multiple_size< n, window<dpsite>, F > regular;
00095 
00096       typedef multiple_size_qiter<n,W,F> fwd_qiter;
00097       typedef multiple_size_qiter<n,W,F> bkd_qiter;
00098       typedef multiple_size_qiter<n,W,F> qiter;
00099 
00100       typedef W element;
00101 
00102       multiple_size();
00103 
00104       multiple_size(const F& f);
00105 
00106       bool is_empty() const;
00107 
00108       void set_window(unsigned i, const W& win);
00109 
00110       const W& window_(unsigned i) const;
00111 
00112       unsigned nwindows() const;
00113 
00114       const F& function() const;
00115 
00116       unsigned size_around(const mln_psite(W)& p) const;
00117 
00118       const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const;
00119 
00120       bool is_centered() const;
00121 
00122       bool is_symmetric() const;
00123 
00124       void sym();
00125 
00126       unsigned delta() const;
00127 
00128     private:
00129 
00130       util::array<W> win_;
00131       F f_;
00132     };
00133 
00134 
00135     template <unsigned n, typename W, typename F>
00136     class multiple_size_qiter
00137       : public internal::site_relative_iterator_base< multiple_size<n,W,F>,
00138                                                       multiple_size_qiter<n,W,F> >
00139     {
00140       typedef multiple_size_qiter<n,W,F> self_;
00141       typedef internal::site_relative_iterator_base< multiple_size<n,W,F>, self_ > super_;
00142     public:
00143 
00144       multiple_size_qiter();
00145 
00146       template <typename P>
00147       multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c);
00148 
00149       template <typename P>
00150       void init_(const multiple_size<n,W,F>& w, const P& c);
00151 
00153       bool is_valid_() const;
00154 
00156       void invalidate_();
00157 
00159       void do_start_();
00160 
00162       void do_next_();
00163 
00165       mln_psite(W) compute_p_() const;
00166 
00167     private:
00168       int i_;
00169       int size_() const;
00170     };
00171 
00172 
00173 
00174 # ifndef MLN_INCLUDE_ONLY
00175 
00176     // win::multiple_size<n,W,F>
00177 
00178     template <unsigned n, typename W, typename F>
00179     inline
00180     multiple_size<n,W,F>::multiple_size()
00181       : f_()
00182     {
00183     }
00184 
00185     template <unsigned n, typename W, typename F>
00186     inline
00187     multiple_size<n,W,F>::multiple_size(const F& f)
00188       : f_(f)
00189     {
00190     }
00191 
00192     template <unsigned n, typename W, typename F>
00193     inline
00194     bool
00195     multiple_size<n,W,F>::is_empty() const
00196     {
00197       return win_.is_empty();
00198     }
00199 
00200     template <unsigned n, typename W, typename F>
00201     inline
00202     void
00203     multiple_size<n,W,F>::set_window(unsigned i, const W& win)
00204     {
00205       mln_precondition(i == win_.nelements());
00206       (void) i;
00207       win_.append(win);
00208     }
00209 
00210     template <unsigned n, typename W, typename F>
00211     inline
00212     const W&
00213     multiple_size<n,W,F>::window_(unsigned i) const
00214     {
00215       mln_precondition(i < win_.nelements());
00216       return win_[i];
00217     }
00218 
00219     template <unsigned n, typename W, typename F>
00220     inline
00221     unsigned
00222     multiple_size<n,W,F>::nwindows() const
00223     {
00224       return win_.nelements();
00225     }
00226 
00227     template <unsigned n, typename W, typename F>
00228     inline
00229     const F&
00230     multiple_size<n,W,F>::function() const
00231     {
00232       return f_;
00233     }
00234 
00235     template <unsigned n, typename W, typename F>
00236     inline
00237     bool
00238     multiple_size<n,W,F>::is_centered() const
00239     {
00240       mln_precondition(win_.nelements() >= 1);
00241       for (unsigned i = 0; i < win_.nelements(); ++i)
00242         if (! win_[i].is_centered())
00243           return false;
00244       return true;
00245     }
00246 
00247     template <unsigned n, typename W, typename F>
00248     inline
00249     bool
00250     multiple_size<n,W,F>::is_symmetric() const
00251     {
00252       mln_precondition(win_.nelements() >= 1);
00253       for (unsigned i = 0; i < win_.nelements(); ++i)
00254         if (! win_[i].is_symmetric())
00255           return false;
00256       return true;
00257     }
00258 
00259     template <unsigned n, typename W, typename F>
00260     inline
00261     void
00262     multiple_size<n,W,F>::sym()
00263     {
00264       mln_precondition(win_.nelements() >= 1);
00265       for (unsigned i = 0; i < win_.nelements(); ++i)
00266         win_[i].sym();
00267     }
00268 
00269     template <unsigned n, typename W, typename F>
00270     inline
00271     unsigned
00272     multiple_size<n,W,F>::delta() const
00273     {
00274       mln_precondition(win_.nelements() >= 1);
00275       unsigned d = win_[0].delta();
00276       for (unsigned i = 1; i < win_.nelements(); ++i)
00277         {
00278           unsigned d_i = win_[i].delta();
00279           if (d_i > d)
00280             d = d_i;
00281         }
00282       return d;
00283     }
00284 
00285     template <unsigned n, typename W, typename F>
00286     inline
00287     unsigned
00288     multiple_size<n,W,F>::size_around(const mln_psite(W)& p) const
00289     {
00290       mln_precondition(win_.nelements() >= 2);
00291       mln_precondition(f_(p) < win_.nelements());
00292       return win_[f_(p)].size();
00293     }
00294 
00295     template <unsigned n, typename W, typename F>
00296     inline
00297     const mln_dpsite(W)&
00298     multiple_size<n,W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
00299     {
00300       mln_precondition(win_.nelements() >= 2);
00301       mln_precondition(f_(p) < win_.nelements());
00302       mln_precondition(i < win_[f_(p)].size());
00303       return win_[f_(p)].dp(i);
00304     }
00305 
00306 
00307     // win::multiple_size_qiter<n,W,F>
00308 
00309     template <unsigned n, typename W, typename F>
00310     inline
00311     multiple_size_qiter<n,W,F>::multiple_size_qiter()
00312     {
00313     }
00314 
00315     template <unsigned n, typename W, typename F>
00316     template <typename P>
00317     inline
00318     multiple_size_qiter<n,W,F>::multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c)
00319     {
00320       init_(w, c);
00321     }
00322 
00323     template <unsigned n, typename W, typename F>
00324     template <typename P>
00325     inline
00326     void
00327     multiple_size_qiter<n,W,F>::init_(const multiple_size<n,W,F>& w, const P& c)
00328     {
00329       this->center_at(c);
00330       // We have to first change the center so that 'invalidate' can
00331       // work when changing the target.
00332       this->change_target(w);
00333     }
00334 
00335 
00336     template <unsigned n, typename W, typename F>
00337     inline
00338     bool
00339     multiple_size_qiter<n,W,F>::is_valid_() const
00340     {
00341       return i_ != -1 && i_ < size_();
00342     }
00343 
00344     template <unsigned n, typename W, typename F>
00345     inline
00346     void
00347     multiple_size_qiter<n,W,F>::invalidate_()
00348     {
00349       i_ = -1;
00350     }
00351 
00352     template <unsigned n, typename W, typename F>
00353     inline
00354     void
00355     multiple_size_qiter<n,W,F>::do_start_()
00356     {
00357       i_ = 0;
00358     }
00359 
00360     template <unsigned n, typename W, typename F>
00361     inline
00362     void
00363     multiple_size_qiter<n,W,F>::do_next_()
00364     {
00365       ++i_;
00366     }
00367 
00368     template <unsigned n, typename W, typename F>
00369     inline
00370     mln_psite(W)
00371     multiple_size_qiter<n,W,F>::compute_p_() const
00372     {
00373       return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
00374     }
00375 
00376     template <unsigned n, typename W, typename F>
00377     inline
00378     int
00379     multiple_size_qiter<n,W,F>::size_() const
00380     {
00381       return int(this->s_->size_around(*this->c_));
00382     }
00383 
00384 # endif // ! MLN_INCLUDE_ONLY
00385 
00386 
00387   } // end of namespace mln::win
00388 
00389 } // end of namespace mln
00390 
00391 
00392 #endif // ! MLN_WIN_MULTIPLE_SIZE_HH

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