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

multiple_size.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_WIN_MULTIPLE_SIZE_HH
00027 # define MLN_WIN_MULTIPLE_SIZE_HH
00028 
00034 
00035 # include <mln/core/internal/window_base.hh>
00036 # include <mln/core/internal/site_relative_iterator_base.hh>
00037 # include <mln/util/array.hh>
00038 # include <mln/metal/ands.hh>
00039 
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   // Forward declarations.
00046   namespace win
00047   {
00048     template <unsigned n, typename W, typename F> class multiple_size;
00049     template <unsigned n, typename W, typename F> class multiple_size_qiter;
00050   }
00051 
00052 
00053 
00054   namespace trait
00055   {
00056 
00057     template <unsigned n, typename W, typename F>
00058     struct window_< win::multiple_size<n,W,F> >
00059     {
00060       typedef trait::window::size::unknown     size;
00061       typedef trait::window::support::regular  support;
00062       typedef trait::window::definition::n_ary definition;
00063     };
00064 
00065   } // end of namespace trait
00066 
00067 
00068 
00069   namespace win
00070   {
00071 
00075     //
00076     template <unsigned n, typename W, typename F>
00077     class multiple_size
00078 
00079       : public internal::window_base< mln_dpsite(W), multiple_size<n,W,F> >,
00080 
00081         private metal::ands< mlc_bool(n > 1),
00082                              mlc_is(mln_trait_window_size(W),
00083                                     trait::window::size::fixed),
00084                              mlc_is(mln_trait_window_support(W),
00085                                     trait::window::support::regular) >::check_t
00086     {
00087     public:
00088 
00089       typedef mln_dpsite(W) dpsite;
00090       typedef  mln_psite(W)  psite;
00091       typedef   mln_site(W)   site;
00092 
00093       typedef multiple_size< n, window<dpsite>, F > regular;
00094 
00095       typedef multiple_size_qiter<n,W,F> fwd_qiter;
00096       typedef multiple_size_qiter<n,W,F> bkd_qiter;
00097       typedef multiple_size_qiter<n,W,F> qiter;
00098 
00099       typedef W element;
00100 
00101       multiple_size();
00102 
00103       multiple_size(const F& f);
00104 
00105       bool is_empty() const;
00106 
00107       void set_window(unsigned i, const W& win);
00108 
00109       const W& window_(unsigned i) const;
00110 
00111       unsigned nwindows() const;
00112 
00113       const F& function() const;
00114 
00115       unsigned size_around(const mln_psite(W)& p) const;
00116 
00117       const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const;
00118 
00119       bool is_centered() const;
00120 
00121       bool is_symmetric() const;
00122 
00123       void sym();
00124 
00125       unsigned delta() const;
00126 
00127     private:
00128 
00129       util::array<W> win_;
00130       F f_;
00131     };
00132 
00133 
00134     template <unsigned n, typename W, typename F>
00135     class multiple_size_qiter
00136       : public internal::site_relative_iterator_base< multiple_size<n,W,F>,
00137                                                       multiple_size_qiter<n,W,F> >
00138     {
00139       typedef multiple_size_qiter<n,W,F> self_;
00140       typedef internal::site_relative_iterator_base< multiple_size<n,W,F>, self_ > super_;
00141     public:
00142 
00143       multiple_size_qiter();
00144 
00145       template <typename P>
00146       multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c);
00147 
00148       template <typename P>
00149       void init_(const multiple_size<n,W,F>& w, const P& c);
00150 
00152       bool is_valid_() const;
00153 
00155       void invalidate_();
00156 
00158       void do_start_();
00159 
00161       void do_next_();
00162 
00164       mln_psite(W) compute_p_() const;
00165 
00166     private:
00167       int i_;
00168       int size_() const;
00169     };
00170 
00171 
00172 
00173 # ifndef MLN_INCLUDE_ONLY
00174 
00175     // win::multiple_size<n,W,F>
00176 
00177     template <unsigned n, typename W, typename F>
00178     inline
00179     multiple_size<n,W,F>::multiple_size()
00180       : f_()
00181     {
00182     }
00183 
00184     template <unsigned n, typename W, typename F>
00185     inline
00186     multiple_size<n,W,F>::multiple_size(const F& f)
00187       : f_(f)
00188     {
00189     }
00190 
00191     template <unsigned n, typename W, typename F>
00192     inline
00193     bool
00194     multiple_size<n,W,F>::is_empty() const
00195     {
00196       return win_.is_empty();
00197     }
00198 
00199     template <unsigned n, typename W, typename F>
00200     inline
00201     void
00202     multiple_size<n,W,F>::set_window(unsigned i, const W& win)
00203     {
00204       mln_precondition(i == win_.nelements());
00205       win_.append(win);
00206     }
00207 
00208     template <unsigned n, typename W, typename F>
00209     inline
00210     const W&
00211     multiple_size<n,W,F>::window_(unsigned i) const
00212     {
00213       mln_precondition(i < win_.nelements());
00214       return win_[i];
00215     }
00216 
00217     template <unsigned n, typename W, typename F>
00218     inline
00219     unsigned
00220     multiple_size<n,W,F>::nwindows() const
00221     {
00222       return win_.nelements();
00223     }
00224 
00225     template <unsigned n, typename W, typename F>
00226     inline
00227     const F&
00228     multiple_size<n,W,F>::function() const
00229     {
00230       return f_;
00231     }
00232 
00233     template <unsigned n, typename W, typename F>
00234     inline
00235     bool
00236     multiple_size<n,W,F>::is_centered() const
00237     {
00238       mln_precondition(win_.nelements() >= 1);
00239       for (unsigned i = 0; i < win_.nelements(); ++i)
00240         if (! win_[i].is_centered())
00241           return false;
00242       return true;
00243     }
00244 
00245     template <unsigned n, typename W, typename F>
00246     inline
00247     bool
00248     multiple_size<n,W,F>::is_symmetric() const
00249     {
00250       mln_precondition(win_.nelements() >= 1);
00251       for (unsigned i = 0; i < win_.nelements(); ++i)
00252         if (! win_[i].is_symmetric())
00253           return false;
00254       return true;
00255     }
00256 
00257     template <unsigned n, typename W, typename F>
00258     inline
00259     void
00260     multiple_size<n,W,F>::sym()
00261     {
00262       mln_precondition(win_.nelements() >= 1);
00263       for (unsigned i = 0; i < win_.nelements(); ++i)
00264         win_[i].sym();
00265     }
00266 
00267     template <unsigned n, typename W, typename F>
00268     inline
00269     unsigned
00270     multiple_size<n,W,F>::delta() const
00271     {
00272       mln_precondition(win_.nelements() >= 1);
00273       unsigned d = win_[0].delta();
00274       for (unsigned i = 1; i < win_.nelements(); ++i)
00275         {
00276           unsigned d_i = win_[i].delta();
00277           if (d_i > d)
00278             d = d_i;
00279         }
00280       return d;
00281     }
00282 
00283     template <unsigned n, typename W, typename F>
00284     inline
00285     unsigned
00286     multiple_size<n,W,F>::size_around(const mln_psite(W)& p) const
00287     {
00288       mln_precondition(win_.nelements() >= 2);
00289       mln_precondition(f_(p) < win_.nelements());
00290       return win_[f_(p)].size();
00291     }
00292 
00293     template <unsigned n, typename W, typename F>
00294     inline
00295     const mln_dpsite(W)&
00296     multiple_size<n,W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
00297     {
00298       mln_precondition(win_.nelements() >= 2);
00299       mln_precondition(f_(p) < win_.nelements());
00300       mln_precondition(i < win_[f_(p)].size());
00301       return win_[f_(p)].dp(i);
00302     }
00303 
00304 
00305     // win::multiple_size_qiter<n,W,F>
00306 
00307     template <unsigned n, typename W, typename F>
00308     inline
00309     multiple_size_qiter<n,W,F>::multiple_size_qiter()
00310     {
00311     }
00312 
00313     template <unsigned n, typename W, typename F>
00314     template <typename P>
00315     inline
00316     multiple_size_qiter<n,W,F>::multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c)
00317     {
00318       init_(w, c);
00319     }
00320 
00321     template <unsigned n, typename W, typename F>
00322     template <typename P>
00323     inline
00324     void
00325     multiple_size_qiter<n,W,F>::init_(const multiple_size<n,W,F>& w, const P& c)
00326     {
00327       this->center_at(c);
00328       // We have to first change the center so that 'invalidate' can
00329       // work when changing the target.
00330       this->change_target(w);
00331     }
00332 
00333 
00334     template <unsigned n, typename W, typename F>
00335     inline
00336     bool
00337     multiple_size_qiter<n,W,F>::is_valid_() const
00338     {
00339       return i_ != -1 && i_ < size_();
00340     }
00341 
00342     template <unsigned n, typename W, typename F>
00343     inline
00344     void
00345     multiple_size_qiter<n,W,F>::invalidate_()
00346     {
00347       i_ = -1;
00348     }
00349 
00350     template <unsigned n, typename W, typename F>
00351     inline
00352     void
00353     multiple_size_qiter<n,W,F>::do_start_()
00354     {
00355       i_ = 0;
00356     }
00357 
00358     template <unsigned n, typename W, typename F>
00359     inline
00360     void
00361     multiple_size_qiter<n,W,F>::do_next_()
00362     {
00363       ++i_;
00364     }
00365 
00366     template <unsigned n, typename W, typename F>
00367     inline
00368     mln_psite(W)
00369     multiple_size_qiter<n,W,F>::compute_p_() const
00370     {
00371       return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
00372     }
00373 
00374     template <unsigned n, typename W, typename F>
00375     inline
00376     int
00377     multiple_size_qiter<n,W,F>::size_() const
00378     {
00379       return int(this->s_->size_around(*this->c_));
00380     }
00381 
00382 # endif // ! MLN_INCLUDE_ONLY
00383 
00384 
00385   } // end of namespace mln::win
00386 
00387 } // end of namespace mln
00388 
00389 
00390 #endif // ! MLN_WIN_MULTIPLE_SIZE_HH

Generated on Fri Oct 19 2012 04:16:06 for Milena (Olena) by  doxygen 1.7.1