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