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_CORE_SITE_SET_BOX_HH
00027 # define MLN_CORE_SITE_SET_BOX_HH
00028
00034
00035 # include <mln/core/concept/box.hh>
00036 # include <mln/core/internal/box_impl.hh>
00037 # include <mln/core/point.hh>
00038 # include <mln/literal/origin.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044
00045 template <typename P> struct box;
00046 template <typename P> struct box_fwd_piter_;
00047 template <typename P> struct box_bkd_piter_;
00048
00049
00050 namespace trait
00051 {
00052
00053 template <typename P>
00054 struct site_set_< box<P> >
00055 {
00056 typedef trait::site_set::nsites::known nsites;
00057 typedef trait::site_set::bbox::straight bbox;
00058 typedef trait::site_set::contents::fixed contents;
00059 typedef trait::site_set::arity::unique arity;
00060 };
00061
00062 template <typename P>
00063 struct set_precise_unary_< op::ord, box<P> >
00064 {
00065 typedef set_precise_unary_< op::ord, box<P> > ret;
00066 bool strict(const box<P>& lhs, const box<P>& rhs) const;
00067 };
00068
00069 }
00070
00071
00078
00079 template <typename P>
00080 struct box : public Box< box<P> >,
00081 public internal::box_impl_< P::dim, mln_coord(P), box<P> >,
00082 private mlc_is_unqualif(P)::check_t
00083 {
00085 enum { dim = P::dim };
00086
00088 typedef P element;
00089
00091 typedef P psite;
00092
00094 typedef P site;
00095
00097 typedef box_fwd_piter_<P> fwd_piter;
00098
00100 typedef fwd_piter piter;
00101
00103 typedef box_bkd_piter_<P> bkd_piter;
00104
00106 P pmin() const;
00107
00109 P& pmin();
00110
00112 P pmax() const;
00113
00115 P& pmax();
00116
00118 box();
00119
00121 box(const site& pmin, const site& pmax);
00122
00125 explicit box(mln_coord(P) ninds);
00126 box(mln_coord(P) nrows, mln_coord(P) ncols);
00127 box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols);
00129
00134 bool has(const P& p) const;
00135
00137 void enlarge(unsigned b);
00138
00140 void enlarge(unsigned dim, unsigned b);
00141
00143 box<P> to_larger(unsigned b) const;
00144
00146 P center() const;
00147
00150 bool is_valid() const;
00151
00153 void crop_wrt(const box<P>& b);
00154
00156 std::size_t memory_size() const;
00157
00158 protected:
00159
00160 P pmin_, pmax_;
00161 };
00162
00163
00173 template <typename P>
00174 std::ostream& operator<<(std::ostream& ostr, const box<P>& b);
00175
00176
00178 template <typename P>
00179 inline
00180 box<P>
00181 larger_than(const box<P> a, const box<P> b);
00182
00183
00184
00185 # ifndef MLN_INCLUDE_ONLY
00186
00187 template <typename P>
00188 inline
00189 bool
00190 box<P>::is_valid() const
00191 {
00192
00193
00194 return util::ord_weak(pmin_, pmax_);
00195 }
00196
00197 template <typename P>
00198 inline
00199 void
00200 box<P>::crop_wrt(const box<P>& ref)
00201 {
00202 if (pmin_.col() < ref.pmin().col())
00203 pmin_.col() = ref.pmin().col();
00204 if (pmin_.row() < ref.pmin().row())
00205 pmin_.row() = ref.pmin().row();
00206
00207 if (pmax_.col() > ref.pmax().col())
00208 pmax_.col() = ref.pmax().col();
00209 if (pmax_.row() > ref.pmax().row())
00210 pmax_.row() = ref.pmax().row();
00211 }
00212
00213 template <typename P>
00214 inline
00215 P
00216 box<P>::pmin() const
00217 {
00218 mln_precondition(is_valid());
00219 return pmin_;
00220 }
00221
00222 template <typename P>
00223 inline
00224 P&
00225 box<P>::pmin()
00226 {
00227 return pmin_;
00228 }
00229
00230 template <typename P>
00231 inline
00232 P
00233 box<P>::pmax() const
00234 {
00235 mln_precondition(is_valid());
00236 return pmax_;
00237 }
00238
00239 template <typename P>
00240 inline
00241 P&
00242 box<P>::pmax()
00243 {
00244 return pmax_;
00245 }
00246
00247 template <typename P>
00248 inline
00249 box<P>::box()
00250 : pmin_(P::plus_infty()),
00251 pmax_(P::minus_infty())
00252 {
00253
00254 }
00255
00256 template <typename P>
00257 inline
00258 box<P>::box(const site& pmin, const site& pmax)
00259 : pmin_(pmin),
00260 pmax_(pmax)
00261 {
00262 mln_precondition(is_valid());
00263 }
00264
00265 template <typename P>
00266 inline
00267 box<P>::box(mln_coord(P) ninds)
00268 {
00269 metal::bool_<(dim == 1)>::check();
00270 pmin_ = literal::origin;
00271 pmax_ = P(ninds - 1);
00272 }
00273
00274 template <typename P>
00275 inline
00276 box<P>::box(mln_coord(P) nrows, mln_coord(P) ncols)
00277 {
00278 metal::bool_<(dim == 2)>::check();
00279 mln_precondition(nrows != 0 && ncols != 0);
00280
00281 pmin_ = literal::origin;
00282 pmax_ = P(--nrows, --ncols);
00283 mln_postcondition(is_valid());
00284 }
00285
00286 template <typename P>
00287 inline
00288 box<P>::box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols)
00289 {
00290 metal::bool_<(dim == 3)>::check();
00291 pmin_ = literal::origin;
00292 pmax_ = P(nslis - 1, nrows - 1, ncols - 1);
00293 mln_postcondition(is_valid());
00294 }
00295
00296 template <typename P>
00297 inline
00298 bool
00299 box<P>::has(const P& p) const
00300 {
00301 mln_precondition(is_valid());
00302 for (unsigned i = 0; i < P::dim; ++i)
00303 if (p[i] < pmin_[i] || p[i] > pmax_[i])
00304 return false;
00305 return true;
00306 }
00307
00308 template <typename P>
00309 inline
00310 void
00311 box<P>::enlarge(unsigned b)
00312 {
00313 mln_precondition(is_valid());
00314 for (unsigned i = 0; i < P::dim; ++i)
00315 {
00316 pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] - b);
00317 pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] + b);
00318 }
00319 mln_postcondition(is_valid());
00320 }
00321
00322 template <typename P>
00323 inline
00324 void
00325 box<P>::enlarge(unsigned dim, unsigned b)
00326 {
00327 mln_precondition(is_valid());
00328 pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] - b);
00329 pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] + b);
00330 mln_postcondition(is_valid());
00331 }
00332
00333 template <typename P>
00334 inline
00335 box<P>
00336 larger_than(const box<P> a, const box<P> b)
00337 {
00338 P pmin,pmax;
00339
00340 for (unsigned i = 0; i < P::dim; i++)
00341 {
00342 pmin[i] = (a.pmin()[i] < b.pmin()[i]) ? a.pmin()[i] : b.pmin()[i];
00343 pmax[i] = (a.pmax()[i] > b.pmax()[i]) ? a.pmax()[i] : b.pmax()[i];
00344 }
00345
00346 return box<P>(pmin, pmax);
00347 }
00348
00349 template <typename P>
00350 inline
00351 box<P>
00352 box<P>::to_larger(unsigned b) const
00353 {
00354 mln_precondition(is_valid());
00355 box<P> tmp(*this);
00356
00357 for (unsigned i = 0; i < P::dim; ++i)
00358 {
00359 tmp.pmin_[i] = static_cast<mln_coord(P)>(tmp.pmin_[i] - b);
00360 tmp.pmax_[i] = static_cast<mln_coord(P)>(tmp.pmax_[i] + b);
00361 }
00362 mln_postcondition(tmp.is_valid());
00363 return tmp;
00364 }
00365
00366 template <typename P>
00367 inline
00368 P
00369 box<P>::center() const
00370 {
00371 mln_precondition(is_valid());
00372 P center;
00373 for (unsigned i = 0; i < P::dim; ++i)
00374 center[i] = static_cast<mln_coord(P)>(pmin_[i] + ((pmax_[i] - pmin_[i]) / 2));
00375 return center;
00376 }
00377
00378 template <typename P>
00379 inline
00380 std::size_t
00381 box<P>::memory_size() const
00382 {
00383 return sizeof(*this);
00384 }
00385
00386 template <typename P>
00387 inline
00388 std::ostream& operator<<(std::ostream& ostr, const box<P>& b)
00389 {
00390 mln_precondition(b.is_valid());
00391 return ostr << "[" << b.pmin() << ".." << b.pmax() << ']';
00392 }
00393
00394 namespace trait
00395 {
00396
00397 template <typename P>
00398 inline
00399 bool
00400 set_precise_unary_< op::ord, box<P> >::strict(const box<P>& lhs, const box<P>& rhs) const
00401 {
00402
00403 return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
00404 rhs.pmin(), rhs.pmax());
00405 }
00406
00407 }
00408
00409 # endif // ! MLN_INCLUDE_ONLY
00410
00411 }
00412
00413
00414 # include <mln/core/site_set/box_piter.hh>
00415
00416
00417 #endif // ! MLN_CORE_SITE_SET_BOX_HH