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