Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 // Forward declarations. 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 } // end of namespace trait 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 /* FIXME: */ 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 template <typename Pref> 00143 multiple_qiter(const multiple<W,F>& w, const Pref& c); 00144 00146 void change_target(const multiple<W,F>& w); 00147 00149 template <typename Pref> 00150 void init_(const multiple<W,F>& w, const Pref& 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 unsigned i_; 00169 unsigned size_; 00170 }; 00171 00172 00173 00174 # ifndef MLN_INCLUDE_ONLY 00175 00176 // win::multiple<W,F> 00177 00178 template <typename W, typename F> 00179 inline 00180 multiple<W,F>::multiple() 00181 : f_() 00182 { 00183 } 00184 00185 template <typename W, typename F> 00186 inline 00187 multiple<W,F>::multiple(const F& f) 00188 : f_(f) 00189 { 00190 } 00191 00192 template <typename W, typename F> 00193 inline 00194 bool 00195 multiple<W,F>::is_empty() const 00196 { 00197 return win_.is_empty(); 00198 } 00199 00200 template <typename W, typename F> 00201 inline 00202 void 00203 multiple<W,F>::set_window(unsigned i, const W& win) 00204 { 00205 mln_precondition(i == win_.nelements()); 00206 if (i >= 1) 00207 mln_precondition(win.size() == win_[0].size()); 00208 win_.append(win); 00209 } 00210 00211 template <typename W, typename F> 00212 inline 00213 const W& 00214 multiple<W,F>::window_(unsigned i) const 00215 { 00216 mln_precondition(i < win_.nelements()); 00217 return win_[i]; 00218 } 00219 00220 template <typename W, typename F> 00221 inline 00222 unsigned 00223 multiple<W,F>::nwindows() const 00224 { 00225 return win_.nelements(); 00226 } 00227 00228 template <typename W, typename F> 00229 inline 00230 const F& 00231 multiple<W,F>::function() const 00232 { 00233 return f_; 00234 } 00235 00236 template <typename W, typename F> 00237 inline 00238 unsigned 00239 multiple<W,F>::size() const 00240 { 00241 mln_precondition(win_.nelements() >= 2); // Multiple cannot be just 1 element. 00242 unsigned s = win_[0].size(); 00243 for (unsigned i = 1; i < win_.nelements(); ++i) 00244 mln_precondition(win_[i].size() == s); 00245 return s; 00246 } 00247 00248 template <typename W, typename F> 00249 inline 00250 bool 00251 multiple<W,F>::is_centered() const 00252 { 00253 mln_precondition(win_.nelements() >= 1); 00254 for (unsigned i = 0; i < win_.nelements(); ++i) 00255 if (! win_[i].is_centered()) 00256 return false; 00257 return true; 00258 } 00259 00260 template <typename W, typename F> 00261 inline 00262 bool 00263 multiple<W,F>::is_symmetric() const 00264 { 00265 mln_precondition(win_.nelements() >= 1); 00266 for (unsigned i = 0; i < win_.nelements(); ++i) 00267 if (! win_[i].is_symmetric()) 00268 return false; 00269 return true; 00270 } 00271 00272 00273 template <typename W, typename F> 00274 inline 00275 void 00276 multiple<W,F>::sym() 00277 { 00278 mln_precondition(win_.nelements() >= 1); 00279 for (unsigned i = 0; i < win_.nelements(); ++i) 00280 win_[i].sym(); 00281 } 00282 00283 template <typename W, typename F> 00284 inline 00285 unsigned 00286 multiple<W,F>::delta() const 00287 { 00288 mln_precondition(win_.nelements() >= 1); 00289 unsigned d = win_[0].delta(); 00290 for (unsigned i = 1; i < win_.nelements(); ++i) 00291 { 00292 unsigned d_i = win_[i].delta(); 00293 if (d_i > d) 00294 d = d_i; 00295 } 00296 return d; 00297 } 00298 00299 template <typename W, typename F> 00300 inline 00301 const mln_dpsite(W)& 00302 multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const 00303 { 00304 mln_precondition(f_(p) < win_.nelements()); 00305 mln_precondition(i < win_[f_(p)].size()); 00306 return win_[f_(p)].dp(i); 00307 } 00308 00309 00310 // win::multiple_qiter<W,F> 00311 00312 template <typename W, typename F> 00313 inline 00314 multiple_qiter<W,F>::multiple_qiter() 00315 { 00316 } 00317 00318 template <typename W, typename F> 00319 template <typename Pref> 00320 inline 00321 multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const Pref& c) 00322 { 00323 init_(w, c); 00324 } 00325 00326 template <typename W, typename F> 00327 template <typename Pref> 00328 inline 00329 void 00330 multiple_qiter<W,F>::init_(const multiple<W,F>& w, const Pref& c) 00331 { 00332 this->center_at(c); 00333 // We have to first change the center so that 'invalidate' can 00334 // work when changing the target. 00335 change_target(w); 00336 } 00337 00338 template <typename W, typename F> 00339 inline 00340 void 00341 multiple_qiter<W,F>::change_target(const multiple<W,F>& w) 00342 { 00343 size_ = w.size(); 00344 this->super_::change_target(w); 00345 } 00346 00347 template <typename W, typename F> 00348 inline 00349 bool 00350 multiple_qiter<W,F>::is_valid_() const 00351 { 00352 return i_ < size_; 00353 } 00354 00355 template <typename W, typename F> 00356 inline 00357 void 00358 multiple_qiter<W,F>::invalidate_() 00359 { 00360 i_ = size_; 00361 } 00362 00363 template <typename W, typename F> 00364 inline 00365 void 00366 multiple_qiter<W,F>::do_start_() 00367 { 00368 i_ = 0; 00369 } 00370 00371 template <typename W, typename F> 00372 inline 00373 void 00374 multiple_qiter<W,F>::do_next_() 00375 { 00376 ++i_; 00377 } 00378 00379 template <typename W, typename F> 00380 inline 00381 mln_psite(W) 00382 multiple_qiter<W,F>::compute_p_() const 00383 { 00384 return *this->c_ + this->s_->ith_dp_around(i_, *this->c_); 00385 } 00386 00387 # endif // ! MLN_INCLUDE_ONLY 00388 00389 00390 } // end of namespace mln::win 00391 00392 } // end of namespace mln 00393 00394 00395 #endif // ! MLN_WIN_MULTIPLE_HH