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

box.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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   // Fwd decls.
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; // Itself.
00066       bool strict(const box<P>& lhs, const box<P>& rhs) const;
00067     };
00068 
00069   } // end of namespace mln::trait
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     // Validity is: for all i, pmin_[i] <= pmax_[i].
00193     // Nota bene: a one-point box is valid.
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     // FIXME: The code above can be slow; think about removing it...
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       // Lexicographical over "pmin then pmax".
00403       return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
00404                                    rhs.pmin(), rhs.pmax());
00405     }
00406 
00407   } // end of namespace mln::trait
00408 
00409 # endif // ! MLN_INCLUDE_ONLY
00410 
00411 } // end of namespace mln
00412 
00413 
00414 # include <mln/core/site_set/box_piter.hh>
00415 
00416 
00417 #endif // ! MLN_CORE_SITE_SET_BOX_HH

Generated on Thu Sep 8 2011 18:31:33 for Milena (Olena) by  doxygen 1.7.1