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
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);
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
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);
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
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
00321
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 }
00378
00379 }
00380
00381
00382 #endif // ! MLN_WIN_MULTIPLE_HH