Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 // Forward declarations. 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 } // end of namespace trait 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 // win::multiple_size<n,W,F> 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 // win::multiple_size_qiter<n,W,F> 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 // We have to first change the center so that 'invalidate' can 00331 // work when changing the target. 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 } // end of namespace mln::win 00388 00389 } // end of namespace mln 00390 00391 00392 #endif // ! MLN_WIN_MULTIPLE_SIZE_HH