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
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
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;
00067 bool strict(const box<P>& lhs, const box<P>& rhs) const;
00068 };
00069
00070 }
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
00198
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
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
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
00429 return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
00430 rhs.pmin(), rhs.pmax());
00431 }
00432
00433 }
00434
00435 # endif // ! MLN_INCLUDE_ONLY
00436
00437 }
00438
00439
00440 # include <mln/core/site_set/box_piter.hh>
00441
00442
00443 #endif // ! MLN_CORE_SITE_SET_BOX_HH