• 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 
00143       template <typename P>
00144       multiple_qiter(const multiple<W,F>& w, const P& c);
00145 
00146       void change_target(const multiple<W,F>& w); // Overridden to initialize size_.
00147 
00149       bool is_valid_() const;
00150 
00152       void invalidate_();
00153 
00155       void do_start_();
00156 
00158       void do_next_();
00159 
00161       mln_psite(W) compute_p_() const;
00162 
00163     private:
00164       unsigned i_;
00165       unsigned size_;
00166     };
00167 
00168 
00169 
00170 # ifndef MLN_INCLUDE_ONLY
00171 
00172     // win::multiple<W,F>
00173 
00174     template <typename W, typename F>
00175     inline
00176     multiple<W,F>::multiple()
00177       : f_()
00178     {
00179     }
00180 
00181     template <typename W, typename F>
00182     inline
00183     multiple<W,F>::multiple(const F& f)
00184       : f_(f)
00185     {
00186     }
00187 
00188     template <typename W, typename F>
00189     inline
00190     bool
00191     multiple<W,F>::is_empty() const
00192     {
00193       return win_.is_empty();
00194     }
00195 
00196     template <typename W, typename F>
00197     inline
00198     void
00199     multiple<W,F>::set_window(unsigned i, const W& win)
00200     {
00201       mln_precondition(i == win_.nelements());
00202       if (i >= 1)
00203         mln_precondition(win.size() == win_[0].size());
00204       win_.append(win);
00205     }
00206 
00207     template <typename W, typename F>
00208     inline
00209     const W&
00210     multiple<W,F>::window_(unsigned i) const
00211     {
00212       mln_precondition(i < win_.nelements());
00213       return win_[i];
00214     }
00215 
00216     template <typename W, typename F>
00217     inline
00218     unsigned
00219     multiple<W,F>::nwindows() const
00220     {
00221       return win_.nelements();
00222     }
00223 
00224     template <typename W, typename F>
00225     inline
00226     const F&
00227     multiple<W,F>::function() const
00228     {
00229       return f_;
00230     }
00231 
00232     template <typename W, typename F>
00233     inline
00234     unsigned
00235     multiple<W,F>::size() const
00236     {
00237       mln_precondition(win_.nelements() >= 2); // Multiple cannot be just 1 element.
00238       unsigned s = win_[0].size();
00239       for (unsigned i = 1; i < win_.nelements(); ++i)
00240         mln_precondition(win_[i].size() == s);
00241       return s;
00242     }
00243 
00244     template <typename W, typename F>
00245     inline
00246     bool
00247     multiple<W,F>::is_centered() const
00248     {
00249       mln_precondition(win_.nelements() >= 1);
00250       for (unsigned i = 0; i < win_.nelements(); ++i)
00251         if (! win_[i].is_centered())
00252           return false;
00253       return true;
00254     }
00255 
00256     template <typename W, typename F>
00257     inline
00258     bool
00259     multiple<W,F>::is_symmetric() const
00260     {
00261       mln_precondition(win_.nelements() >= 1);
00262       for (unsigned i = 0; i < win_.nelements(); ++i)
00263         if (! win_[i].is_symmetric())
00264           return false;
00265       return true;
00266     }
00267 
00268 
00269     template <typename W, typename F>
00270     inline
00271     void
00272     multiple<W,F>::sym()
00273     {
00274       mln_precondition(win_.nelements() >= 1);
00275       for (unsigned i = 0; i < win_.nelements(); ++i)
00276         win_[i].sym();
00277     }
00278 
00279     template <typename W, typename F>
00280     inline
00281     unsigned
00282     multiple<W,F>::delta() const
00283     {
00284       mln_precondition(win_.nelements() >= 1);
00285       unsigned d = win_[0].delta();
00286       for (unsigned i = 1; i < win_.nelements(); ++i)
00287         {
00288           unsigned d_i = win_[i].delta();
00289           if (d_i > d)
00290             d = d_i;
00291         }
00292       return d;
00293     }
00294 
00295     template <typename W, typename F>
00296     inline
00297     const mln_dpsite(W)&
00298     multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
00299     {
00300       mln_precondition(f_(p) < win_.nelements());
00301       mln_precondition(i < win_[f_(p)].size());
00302       return win_[f_(p)].dp(i);
00303     }
00304 
00305 
00306     // win::multiple_qiter<W,F>
00307 
00308     template <typename W, typename F>
00309     inline
00310     multiple_qiter<W,F>::multiple_qiter()
00311     {
00312     }
00313 
00314     template <typename W, typename F>
00315     template <typename P>
00316     inline
00317     multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const P& c)
00318     {
00319       this->center_at(c);
00320       // We have to first change the center so that 'invalidate' can
00321       // work when changing the target.
00322       change_target(w);
00323     }
00324 
00325     template <typename W, typename F>
00326     inline
00327     void
00328     multiple_qiter<W,F>::change_target(const multiple<W,F>& w)
00329     {
00330       this->super_::change_target(w);
00331       size_ = w.size();
00332     }
00333 
00334     template <typename W, typename F>
00335     inline
00336     bool
00337     multiple_qiter<W,F>::is_valid_() const
00338     {
00339       return i_ < size_;
00340     }
00341 
00342     template <typename W, typename F>
00343     inline
00344     void
00345     multiple_qiter<W,F>::invalidate_()
00346     {
00347       i_ = size_;
00348     }
00349 
00350     template <typename W, typename F>
00351     inline
00352     void
00353     multiple_qiter<W,F>::do_start_()
00354     {
00355       i_ = 0;
00356     }
00357 
00358     template <typename W, typename F>
00359     inline
00360     void
00361     multiple_qiter<W,F>::do_next_()
00362     {
00363       ++i_;
00364     }
00365 
00366     template <typename W, typename F>
00367     inline
00368     mln_psite(W)
00369     multiple_qiter<W,F>::compute_p_() const
00370     {
00371       return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
00372     }
00373 
00374 # endif // ! MLN_INCLUDE_ONLY
00375 
00376 
00377   } // end of namespace mln::win
00378 
00379 } // end of namespace mln
00380 
00381 
00382 #endif // ! MLN_WIN_MULTIPLE_HH

Generated on Thu Sep 8 2011 18:32:09 for Milena (Olena) by  doxygen 1.7.1