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

box.hh

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

Generated on Tue Oct 4 2011 15:23:28 for Milena (Olena) by  doxygen 1.7.1