Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and 00002 // Development 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_CORE_SITE_SET_BOX_HH 00028 # define MLN_CORE_SITE_SET_BOX_HH 00029 00035 00036 # include <mln/core/concept/box.hh> 00037 # include <mln/core/internal/box_impl.hh> 00038 # include <mln/core/point.hh> 00039 # include <mln/literal/origin.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 // Fwd decls. 00046 template <typename P> class box; 00047 template <typename P> class box_fwd_piter_; 00048 template <typename P> class box_bkd_piter_; 00049 00050 00051 namespace trait 00052 { 00053 00054 template <typename P> 00055 struct site_set_< box<P> > 00056 { 00057 typedef trait::site_set::nsites::known nsites; 00058 typedef trait::site_set::bbox::straight bbox; 00059 typedef trait::site_set::contents::fixed contents; 00060 typedef trait::site_set::arity::unique arity; 00061 }; 00062 00063 template <typename P> 00064 struct set_precise_unary_< op::ord, box<P> > 00065 { 00066 typedef set_precise_unary_< op::ord, box<P> > ret; // Itself. 00067 bool strict(const box<P>& lhs, const box<P>& rhs) const; 00068 }; 00069 00070 } // end of namespace mln::trait 00071 00072 00079 // 00080 template <typename P> 00081 class box : public Box< box<P> >, 00082 public internal::box_impl_< P::dim, mln_coord(P), box<P> >, 00083 private mlc_is_unqualif(P)::check_t 00084 { 00085 public: 00087 enum { dim = P::dim }; 00088 00090 typedef P element; 00091 00093 typedef P psite; 00094 00096 typedef P site; 00097 00099 typedef box_fwd_piter_<P> fwd_piter; 00100 00102 typedef fwd_piter piter; 00103 00105 typedef box_bkd_piter_<P> bkd_piter; 00106 00108 P pmin() const; 00109 00111 P& pmin(); 00112 00114 P pmax() const; 00115 00117 P& pmax(); 00118 00120 box(); 00121 00123 box(const site& pmin, const site& pmax); 00124 00127 explicit box(mln_coord(P) ninds); 00128 box(mln_coord(P) nrows, mln_coord(P) ncols); 00129 box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols); 00131 00136 bool has(const P& p) const; 00137 00139 void enlarge(unsigned b); 00140 00142 void enlarge(unsigned dim, unsigned b); 00143 00145 box<P> to_larger(unsigned b) const; 00146 00148 P pcenter() const; 00149 00152 bool is_valid() const; 00153 00155 void crop_wrt(const box<P>& b); 00156 00158 void merge(const box<P>& b); 00159 00161 std::size_t memory_size() const; 00162 00163 protected: 00164 00165 P pmin_, pmax_; 00166 }; 00167 00168 00178 template <typename P> 00179 std::ostream& operator<<(std::ostream& ostr, const box<P>& b); 00180 00181 00183 template <typename P> 00184 inline 00185 box<P> 00186 larger_than(const box<P> a, const box<P> b); 00187 00188 00189 00190 # ifndef MLN_INCLUDE_ONLY 00191 00192 template <typename P> 00193 inline 00194 bool 00195 box<P>::is_valid() const 00196 { 00197 // Validity is: for all i, pmin_[i] <= pmax_[i]. 00198 // Nota bene: a one-point box is valid. 00199 return util::ord_weak(pmin_, pmax_); 00200 } 00201 00202 template <typename P> 00203 inline 00204 void 00205 box<P>::crop_wrt(const box<P>& ref) 00206 { 00207 if (pmin_.col() < ref.pmin().col()) 00208 pmin_.col() = ref.pmin().col(); 00209 if (pmin_.row() < ref.pmin().row()) 00210 pmin_.row() = ref.pmin().row(); 00211 00212 if (pmax_.col() > ref.pmax().col()) 00213 pmax_.col() = ref.pmax().col(); 00214 if (pmax_.row() > ref.pmax().row()) 00215 pmax_.row() = ref.pmax().row(); 00216 } 00217 00218 template <typename P> 00219 inline 00220 void 00221 box<P>::merge(const box<P>& b) 00222 { 00223 mln_precondition(is_valid()); 00224 if (! b.is_valid()) 00225 { 00226 // no-op 00227 return; 00228 } 00229 00230 for (unsigned i = 0; i < P::dim; ++i) 00231 { 00232 if (b.pmin()[i] < pmin_[i]) 00233 pmin_[i] = b.pmin()[i]; 00234 if (b.pmax()[i] > pmax_[i]) 00235 pmax_[i] = b.pmax()[i]; 00236 } 00237 } 00238 00239 template <typename P> 00240 inline 00241 P 00242 box<P>::pmin() const 00243 { 00244 mln_precondition(is_valid()); 00245 return pmin_; 00246 } 00247 00248 template <typename P> 00249 inline 00250 P& 00251 box<P>::pmin() 00252 { 00253 return pmin_; 00254 } 00255 00256 template <typename P> 00257 inline 00258 P 00259 box<P>::pmax() const 00260 { 00261 mln_precondition(is_valid()); 00262 return pmax_; 00263 } 00264 00265 template <typename P> 00266 inline 00267 P& 00268 box<P>::pmax() 00269 { 00270 return pmax_; 00271 } 00272 00273 template <typename P> 00274 inline 00275 box<P>::box() 00276 : pmin_(P::plus_infty()), 00277 pmax_(P::minus_infty()) 00278 { 00279 // FIXME: The code above can be slow; think about removing it... 00280 } 00281 00282 template <typename P> 00283 inline 00284 box<P>::box(const site& pmin, const site& pmax) 00285 : pmin_(pmin), 00286 pmax_(pmax) 00287 { 00288 mln_precondition(is_valid()); 00289 } 00290 00291 template <typename P> 00292 inline 00293 box<P>::box(mln_coord(P) ninds) 00294 { 00295 metal::bool_<(dim == 1)>::check(); 00296 pmin_ = literal::origin; 00297 pmax_ = P(ninds - 1); 00298 } 00299 00300 template <typename P> 00301 inline 00302 box<P>::box(mln_coord(P) nrows, mln_coord(P) ncols) 00303 { 00304 metal::bool_<(dim == 2)>::check(); 00305 mln_precondition(nrows != 0 && ncols != 0); 00306 00307 pmin_ = literal::origin; 00308 pmax_ = P(--nrows, --ncols); 00309 mln_postcondition(is_valid()); 00310 } 00311 00312 template <typename P> 00313 inline 00314 box<P>::box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols) 00315 { 00316 metal::bool_<(dim == 3)>::check(); 00317 pmin_ = literal::origin; 00318 pmax_ = P(nslis - 1, nrows - 1, ncols - 1); 00319 mln_postcondition(is_valid()); 00320 } 00321 00322 template <typename P> 00323 inline 00324 bool 00325 box<P>::has(const P& p) const 00326 { 00327 mln_precondition(is_valid()); 00328 for (unsigned i = 0; i < P::dim; ++i) 00329 if (p[i] < pmin_[i] || p[i] > pmax_[i]) 00330 return false; 00331 return true; 00332 } 00333 00334 template <typename P> 00335 inline 00336 void 00337 box<P>::enlarge(unsigned b) 00338 { 00339 mln_precondition(is_valid()); 00340 for (unsigned i = 0; i < P::dim; ++i) 00341 { 00342 pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] - b); 00343 pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] + b); 00344 } 00345 mln_postcondition(is_valid()); 00346 } 00347 00348 template <typename P> 00349 inline 00350 void 00351 box<P>::enlarge(unsigned dim, unsigned b) 00352 { 00353 mln_precondition(is_valid()); 00354 pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] - b); 00355 pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] + b); 00356 mln_postcondition(is_valid()); 00357 } 00358 00359 template <typename P> 00360 inline 00361 box<P> 00362 larger_than(const box<P> a, const box<P> b) 00363 { 00364 P pmin,pmax; 00365 00366 for (unsigned i = 0; i < P::dim; i++) 00367 { 00368 pmin[i] = (a.pmin()[i] < b.pmin()[i]) ? a.pmin()[i] : b.pmin()[i]; 00369 pmax[i] = (a.pmax()[i] > b.pmax()[i]) ? a.pmax()[i] : b.pmax()[i]; 00370 } 00371 00372 return box<P>(pmin, pmax); 00373 } 00374 00375 template <typename P> 00376 inline 00377 box<P> 00378 box<P>::to_larger(unsigned b) const 00379 { 00380 mln_precondition(is_valid()); 00381 box<P> tmp(*this); 00382 00383 for (unsigned i = 0; i < P::dim; ++i) 00384 { 00385 tmp.pmin_[i] = static_cast<mln_coord(P)>(tmp.pmin_[i] - b); 00386 tmp.pmax_[i] = static_cast<mln_coord(P)>(tmp.pmax_[i] + b); 00387 } 00388 mln_postcondition(tmp.is_valid()); 00389 return tmp; 00390 } 00391 00392 template <typename P> 00393 inline 00394 P 00395 box<P>::pcenter() const 00396 { 00397 mln_precondition(is_valid()); 00398 P center; 00399 for (unsigned i = 0; i < P::dim; ++i) 00400 center[i] = static_cast<mln_coord(P)>(pmin_[i] + ((pmax_[i] - pmin_[i]) / 2)); 00401 return center; 00402 } 00403 00404 template <typename P> 00405 inline 00406 std::size_t 00407 box<P>::memory_size() const 00408 { 00409 return sizeof(*this); 00410 } 00411 00412 template <typename P> 00413 inline 00414 std::ostream& operator<<(std::ostream& ostr, const box<P>& b) 00415 { 00416 mln_precondition(b.is_valid()); 00417 return ostr << "[" << b.pmin() << ".." << b.pmax() << ']'; 00418 } 00419 00420 namespace trait 00421 { 00422 00423 template <typename P> 00424 inline 00425 bool 00426 set_precise_unary_< op::ord, box<P> >::strict(const box<P>& lhs, const box<P>& rhs) const 00427 { 00428 // Lexicographical over "pmin then pmax". 00429 return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(), 00430 rhs.pmin(), rhs.pmax()); 00431 } 00432 00433 } // end of namespace mln::trait 00434 00435 # endif // ! MLN_INCLUDE_ONLY 00436 00437 } // end of namespace mln 00438 00439 00440 # include <mln/core/site_set/box_piter.hh> 00441 00442 00443 #endif // ! MLN_CORE_SITE_SET_BOX_HH