00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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 }
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 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
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);
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
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
00334
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 }
00391
00392 }
00393
00394
00395 #endif // ! MLN_WIN_MULTIPLE_HH