• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

box.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010 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_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> struct box;
00047   template <typename P> struct box_fwd_piter_;
00048   template <typename P> struct 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   struct 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   {
00086     enum { dim = P::dim };
00087 
00089     typedef P element;
00090 
00092     typedef P psite;
00093 
00095     typedef P site;
00096 
00098     typedef box_fwd_piter_<P> fwd_piter;
00099 
00101     typedef fwd_piter piter;
00102 
00104     typedef box_bkd_piter_<P> bkd_piter;
00105 
00107     P  pmin() const;
00108 
00110     P& pmin();
00111 
00113     P  pmax() const;
00114 
00116     P& pmax();
00117 
00119     box();
00120 
00122     box(const site& pmin, const site& pmax);
00123 
00126     explicit box(mln_coord(P) ninds);
00127     box(mln_coord(P) nrows, mln_coord(P) ncols);
00128     box(mln_coord(P) nslices, mln_coord(P) nrows, mln_coord(P) ncols);
00130 
00135     bool has(const P& p) const;
00136 
00138     void enlarge(unsigned b);
00139 
00141     void enlarge(unsigned dim, unsigned b);
00142 
00144     box<P> to_larger(unsigned b) const;
00145 
00147     P pcenter() const;
00148 
00151     bool is_valid() const;
00152 
00154     void crop_wrt(const box<P>& b);
00155 
00157     void merge(const box<P>& b);
00158 
00160     std::size_t memory_size() const;
00161 
00162   protected:
00163 
00164     P pmin_, pmax_;
00165   };
00166 
00167 
00177   template <typename P>
00178   std::ostream& operator<<(std::ostream& ostr, const box<P>& b);
00179 
00180 
00182   template <typename P>
00183   inline
00184   box<P>
00185   larger_than(const box<P> a, const box<P> b);
00186 
00187 
00188 
00189 # ifndef MLN_INCLUDE_ONLY
00190 
00191   template <typename P>
00192   inline
00193   bool
00194   box<P>::is_valid() const
00195   {
00196     // Validity is: for all i, pmin_[i] <= pmax_[i].
00197     // Nota bene: a one-point box is valid.
00198     return util::ord_weak(pmin_, pmax_);
00199   }
00200 
00201   template <typename P>
00202   inline
00203   void
00204   box<P>::crop_wrt(const box<P>& ref)
00205   {
00206     if (pmin_.col() < ref.pmin().col())
00207       pmin_.col() = ref.pmin().col();
00208     if (pmin_.row() < ref.pmin().row())
00209       pmin_.row() = ref.pmin().row();
00210 
00211     if (pmax_.col() > ref.pmax().col())
00212       pmax_.col() = ref.pmax().col();
00213     if (pmax_.row() > ref.pmax().row())
00214       pmax_.row() = ref.pmax().row();
00215   }
00216 
00217   template <typename P>
00218   inline
00219   void
00220   box<P>::merge(const box<P>& b)
00221   {
00222     mln_precondition(is_valid());
00223     if (! b.is_valid())
00224     {
00225       // no-op
00226       return;
00227     }
00228 
00229     for (unsigned i = 0; i < P::dim; ++i)
00230     {
00231       if (b.pmin()[i] < pmin_[i])
00232         pmin_[i] = b.pmin()[i];
00233       if (b.pmax()[i] > pmax_[i])
00234         pmax_[i] = b.pmax()[i];
00235     }
00236   }
00237 
00238   template <typename P>
00239   inline
00240   P
00241   box<P>::pmin() const
00242   {
00243     mln_precondition(is_valid());
00244     return pmin_;
00245   }
00246 
00247   template <typename P>
00248   inline
00249   P&
00250   box<P>::pmin()
00251   {
00252     return pmin_;
00253   }
00254 
00255   template <typename P>
00256   inline
00257   P
00258   box<P>::pmax() const
00259   {
00260     mln_precondition(is_valid());
00261     return pmax_;
00262   }
00263 
00264   template <typename P>
00265   inline
00266   P&
00267   box<P>::pmax()
00268   {
00269     return pmax_;
00270   }
00271 
00272   template <typename P>
00273   inline
00274   box<P>::box()
00275     : pmin_(P::plus_infty()),
00276       pmax_(P::minus_infty())
00277   {
00278     // FIXME: The code above can be slow; think about removing it...
00279   }
00280 
00281   template <typename P>
00282   inline
00283   box<P>::box(const site& pmin, const site& pmax)
00284     : pmin_(pmin),
00285       pmax_(pmax)
00286   {
00287     mln_precondition(is_valid());
00288   }
00289 
00290   template <typename P>
00291   inline
00292   box<P>::box(mln_coord(P) ninds)
00293   {
00294     metal::bool_<(dim == 1)>::check();
00295     pmin_ = literal::origin;
00296     pmax_ = P(ninds - 1);
00297   }
00298 
00299   template <typename P>
00300   inline
00301   box<P>::box(mln_coord(P) nrows, mln_coord(P) ncols)
00302   {
00303     metal::bool_<(dim == 2)>::check();
00304     mln_precondition(nrows != 0 && ncols != 0);
00305 
00306     pmin_ = literal::origin;
00307     pmax_ = P(--nrows, --ncols);
00308     mln_postcondition(is_valid());
00309   }
00310 
00311   template <typename P>
00312   inline
00313   box<P>::box(mln_coord(P) nslices, mln_coord(P) nrows, mln_coord(P) ncols)
00314   {
00315     metal::bool_<(dim == 3)>::check();
00316     pmin_ = literal::origin;
00317     pmax_ = P(nslices - 1, nrows - 1, ncols - 1);
00318     mln_postcondition(is_valid());
00319   }
00320 
00321   template <typename P>
00322   inline
00323   bool
00324   box<P>::has(const P& p) const
00325   {
00326     mln_precondition(is_valid());
00327     for (unsigned i = 0; i < P::dim; ++i)
00328       if (p[i] < pmin_[i] || p[i] > pmax_[i])
00329         return false;
00330     return true;
00331   }
00332 
00333   template <typename P>
00334   inline
00335   void
00336   box<P>::enlarge(unsigned b)
00337   {
00338     mln_precondition(is_valid());
00339     for (unsigned i = 0; i < P::dim; ++i)
00340     {
00341       pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] - b);
00342       pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] + b);
00343     }
00344     mln_postcondition(is_valid());
00345   }
00346 
00347   template <typename P>
00348   inline
00349   void
00350   box<P>::enlarge(unsigned dim, unsigned b)
00351   {
00352     mln_precondition(is_valid());
00353     pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] - b);
00354     pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] + b);
00355     mln_postcondition(is_valid());
00356   }
00357 
00358   template <typename P>
00359   inline
00360   box<P>
00361   larger_than(const box<P> a, const box<P> b)
00362   {
00363     P pmin,pmax;
00364 
00365     for (unsigned i = 0; i < P::dim; i++)
00366       {
00367         pmin[i] = (a.pmin()[i] < b.pmin()[i]) ? a.pmin()[i] : b.pmin()[i];
00368         pmax[i] = (a.pmax()[i] > b.pmax()[i]) ? a.pmax()[i] : b.pmax()[i];
00369       }
00370 
00371     return box<P>(pmin, pmax);
00372   }
00373 
00374   template <typename P>
00375   inline
00376   box<P>
00377   box<P>::to_larger(unsigned b) const
00378   {
00379     mln_precondition(is_valid());
00380     box<P> tmp(*this);
00381 
00382     for (unsigned i = 0; i < P::dim; ++i)
00383     {
00384       tmp.pmin_[i] = static_cast<mln_coord(P)>(tmp.pmin_[i] - b);
00385       tmp.pmax_[i] = static_cast<mln_coord(P)>(tmp.pmax_[i] + b);
00386     }
00387     mln_postcondition(tmp.is_valid());
00388     return tmp;
00389   }
00390 
00391   template <typename P>
00392   inline
00393   P
00394   box<P>::pcenter() const
00395   {
00396     mln_precondition(is_valid());
00397     P center;
00398     for (unsigned i = 0; i < P::dim; ++i)
00399       center[i] = static_cast<mln_coord(P)>(pmin_[i] + ((pmax_[i] - pmin_[i]) / 2));
00400     return center;
00401   }
00402 
00403   template <typename P>
00404   inline
00405   std::size_t
00406   box<P>::memory_size() const
00407   {
00408     return sizeof(*this);
00409   }
00410 
00411   template <typename P>
00412   inline
00413   std::ostream& operator<<(std::ostream& ostr, const box<P>& b)
00414   {
00415     mln_precondition(b.is_valid());
00416     return ostr << "[" << b.pmin() << ".." << b.pmax() << ']';
00417   }
00418 
00419   namespace trait
00420   {
00421 
00422     template <typename P>
00423     inline
00424     bool
00425     set_precise_unary_< op::ord, box<P> >::strict(const box<P>& lhs, const box<P>& rhs) const
00426     {
00427       // Lexicographical over "pmin then pmax".
00428       return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
00429                                    rhs.pmin(), rhs.pmax());
00430     }
00431 
00432   } // end of namespace mln::trait
00433 
00434 # endif // ! MLN_INCLUDE_ONLY
00435 
00436 } // end of namespace mln
00437 
00438 
00439 # include <mln/core/site_set/box_piter.hh>
00440 
00441 
00442 #endif // ! MLN_CORE_SITE_SET_BOX_HH

Generated on Fri Oct 19 2012 04:15:37 for Milena (Olena) by  doxygen 1.7.1