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