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

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

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