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

point.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_POINT_HH
00027 # define MLN_CORE_POINT_HH
00028 
00037 
00038 # include <mln/core/def/coord.hh>
00039 # include <mln/core/concept/proxy.hh>
00040 # include <mln/core/concept/gpoint.hh>
00041 # include <mln/core/internal/coord_impl.hh>
00042 # include <mln/fun/i2v/all_to.hh>
00043 
00044 # include <mln/metal/bool.hh>
00045 # include <mln/metal/is_not.hh>
00046 # include <mln/algebra/vec.hh>
00047 # include <mln/metal/converts_to.hh>
00048 # include <mln/algebra/h_vec.hh>
00049 # include <mln/util/yes.hh>
00050 
00051 
00052 namespace mln
00053 {
00054 
00056   template <typename G, typename C> struct  point;
00057   template <typename G, typename C> struct dpoint;
00058   namespace literal {
00059     struct zero_t;
00060     struct one_t;
00061     struct origin_t;
00062   }
00064 
00065 
00066   namespace convert
00067   {
00068 
00069     namespace over_load
00070     {
00071 
00072       template <typename G, typename C1, typename C2>
00073       void from_to_(const point<G,C1>& from, point<G,C2>& to);
00074 
00075     } // end of namespace mln::convert::over_load
00076 
00077   } // end of namespace mln::convert
00078 
00079 
00080 
00081   namespace internal
00082   {
00083     // This is a hack so that g++-2.95 can compile the method
00084     // "point<G,C>::operator vec() const".
00085     template <typename G, typename C>
00086     struct vec_of_point
00087     {
00088       typedef algebra::vec<G::dim, float> ret;
00089     };
00090   }
00091 
00096   template <typename G, typename C>
00097   struct point : public Gpoint< point<G,C> >,
00098                  public internal::mutable_coord_impl_< G::dim, C, point<G,C> >
00099   {
00100     // FIXME: Temporary hack.
00101     typedef point site;
00102     typedef point psite;
00103 
00104 
00108     enum { dim = G::dim };
00109 
00111     typedef G grid;
00112 
00114     typedef dpoint<G,C> delta;
00115 
00117     typedef dpoint<G,C> dpsite;
00118 
00120     typedef C coord;
00121 
00123     typedef algebra::vec<G::dim, float> vec;
00124 
00126     typedef algebra::h_vec<G::dim, float> h_vec;
00127 
00131     const C& operator[](unsigned i) const;
00132 
00136     C& operator[](unsigned i);
00137 
00138 
00140     const C& last_coord() const;
00141 
00143     C& last_coord();
00144 
00145 
00147     point();
00148 
00150     template <typename C2>
00151     point(const algebra::vec<dim,C2>& v);
00152 
00155     explicit point(C ind);
00156     point(C row, C col);
00157     point(C sli, C row, C col);
00159 
00161     point(const literal::origin_t&);
00162     point<G,C>& operator=(const literal::origin_t&);
00163     // Works only in 1D:
00164     point(const literal::zero_t&);
00165     point<G,C>& operator=(const literal::zero_t&);
00166     point(const literal::one_t&);
00167     point<G,C>& operator=(const literal::one_t&);
00169 
00171     template <typename F>
00172     point(const Function_v2v<F>& f);
00173 
00175     void set_all(C c);
00176 
00178     static const point<G,C> origin;
00179 
00181     point<G,C>& operator+=(const delta& dp);
00182 
00184     point<G,C>& operator-=(const delta& dp);
00185 
00186   /* FIXME: Seems highly non-generic!
00187      This (non documented change, even in ChangeLog) change was
00188      introduce by revision 1224, see
00189      https://trac.lrde.org/olena/changeset/1224#file2
00190      https://www.lrde.epita.fr/pipermail/olena-patches/2007-October/001592.html
00191   */
00192     operator typename internal::vec_of_point<G,C>::ret () const; // Hack to help g++-2.95.
00193 
00195     vec to_vec() const;
00196 
00198     h_vec to_h_vec() const;
00199 
00201     static const point<G,C>& plus_infty();
00202 
00204     static const point<G,C>& minus_infty();
00205 
00206   protected:
00207     algebra::vec<G::dim, C> coord_;
00208   };
00209 
00210   namespace internal
00211   {
00212 
00215 
00216     template <typename P, typename E>
00217     struct subject_point_impl;
00218 
00219     template <typename G, typename C, typename E>
00220     struct subject_point_impl< point<G,C>, E >
00221     {
00222       typename point<G,C>::vec to_vec() const;
00223       operator typename point<G,C>::vec () const; // Hack to help g++-2.95.
00224 
00225     private:
00226       const E& exact_() const;
00227     };
00228 
00230 
00231   } // end of namespace mln::internal
00232 
00233 
00235   template <typename G, typename C>
00236   const algebra::vec<point<G,C>::dim - 1, C>& cut_(const point<G,C>& p);
00237 
00238   template <typename C>
00239   const util::yes& cut_(const point<grid::tick,C>& p);
00240 
00241 
00242 
00243 # ifndef MLN_INCLUDE_ONLY
00244 
00245   namespace convert
00246   {
00247 
00248     namespace over_load
00249     {
00250 
00251       template <typename G, typename C1, typename C2>
00252       inline
00253       void
00254       from_to_(const point<G,C1>& from, point<G,C2>& to)
00255       {
00256         mlc_converts_to(C1,C2)::check();
00257         to = point<G,C2>(from.to_vec());
00258       }
00259 
00260     } // end of namespace mln::convert::over_load
00261 
00262   } // end of namespace mln::convert
00263 
00264 
00265   template <typename G, typename C>
00266   inline
00267   const C& point<G,C>::operator[](unsigned i) const
00268   {
00269     assert(i < dim);
00270     return this->coord_[i];
00271   }
00272 
00273   template <typename G, typename C>
00274   inline
00275   C& point<G,C>::operator[](unsigned i)
00276   {
00277     assert(i < dim);
00278     return this->coord_[i];
00279   }
00280 
00281   template <typename G, typename C>
00282   inline
00283   const C&
00284   point<G,C>::last_coord() const
00285   {
00286     return this->coord_[dim - 1];
00287   }
00288 
00289   template <typename G, typename C>
00290   inline
00291   C&
00292   point<G,C>::last_coord()
00293   {
00294     return this->coord_[dim - 1];
00295   }
00296 
00297 
00298   // Constructors.
00299 
00300   template <typename G, typename C>
00301   inline
00302   point<G,C>::point()
00303   {
00304   }
00305 
00306   template <typename G, typename C>
00307   template <typename C2>
00308   inline
00309   point<G,C>::point(const algebra::vec<dim,C2>& v)
00310   {
00311     mlc_converts_to(C2, C)::check();
00312     unsigned j = 0;
00313     //FIXME: to be improved while adding a conversion routine.
00314     if (dim < 3)
00315       coord_ = v;
00316     else
00317     {
00318       for (unsigned i = dim - 2; i < dim; ++i)
00319         coord_[i]   = static_cast<C>(v[j++]);
00320       for (unsigned i = 2; i < dim; ++i, ++j)
00321         coord_[i-j] = static_cast<C>(v[j]);
00322     }
00323   }
00324 
00325   template <typename G, typename C>
00326   inline
00327   point<G,C>::point(C ind)
00328   {
00329     metal::bool_<(dim == 1)>::check();
00330     coord_[0] = ind;
00331   }
00332 
00333   template <typename G, typename C>
00334   inline
00335   point<G,C>::point(C row, C col)
00336   {
00337     metal::bool_<(dim == 2)>::check();
00338     coord_[0] = row;
00339     coord_[1] = col;
00340   }
00341 
00342   template <typename G, typename C>
00343   inline
00344   point<G,C>::point(C sli, C row, C col)
00345   {
00346     metal::bool_<(dim == 3)>::check();
00347     coord_[0] = sli;
00348     coord_[1] = row;
00349     coord_[2] = col;
00350   }
00351 
00352   template <typename G, typename C>
00353   template <typename F>
00354   inline
00355   point<G,C>::point(const Function_v2v<F>& f_)
00356   {
00357     mlc_converts_to(mln_result(F), C)::check();
00358     const F& f = exact(f_);
00359     for (unsigned i = 0; i < dim; ++i)
00360       coord_[i] = static_cast<C>( f(i) );
00361   }
00362 
00363   template <typename G, typename C>
00364   inline
00365   point<G,C>::point(const literal::origin_t&)
00366   {
00367     coord_.set_all(0);
00368   }
00369 
00370   template <typename G, typename C>
00371   inline
00372   point<G,C>&
00373   point<G,C>::operator=(const literal::origin_t&)
00374   {
00375     coord_.set_all(0);
00376     return *this;
00377   }
00378 
00379   template <typename G, typename C>
00380   inline
00381   point<G,C>::point(const literal::zero_t&)
00382   {
00383     metal::bool_<(dim == 1)>::check();
00384     coord_[0] = 1;
00385   }
00386 
00387   template <typename G, typename C>
00388   inline
00389   point<G,C>&
00390   point<G,C>::operator=(const literal::zero_t&)
00391   {
00392     metal::bool_<(dim == 1)>::check();
00393     coord_[0] = 1;
00394     return *this;
00395   }
00396 
00397   template <typename G, typename C>
00398   inline
00399   point<G,C>::point(const literal::one_t&)
00400   {
00401     metal::bool_<(dim == 1)>::check();
00402     coord_[0] = 1;
00403   }
00404 
00405   template <typename G, typename C>
00406   inline
00407   point<G,C>&
00408   point<G,C>::operator=(const literal::one_t&)
00409   {
00410     metal::bool_<(dim == 1)>::check();
00411     coord_[0] = 1;
00412     return *this;
00413   }
00414 
00415   template <typename G, typename C>
00416   inline
00417   void point<G,C>::set_all(C c)
00418   {
00419     coord_.set_all(c);
00420   }
00421 
00422   template <typename G, typename C>
00423   const point<G,C> point<G,C>::origin = all_to(0);
00424 
00425   template <typename G, typename C>
00426   inline
00427   point<G,C>&
00428   point<G,C>::operator+=(const delta& dp)
00429   {
00430     for (unsigned i = 0; i < dim; ++i)
00431       coord_[i] = static_cast<C>(coord_[i] + dp[i]);
00432     return *this;
00433   }
00434 
00435   template <typename G, typename C>
00436   inline
00437   point<G,C>&
00438   point<G,C>::operator-=(const delta& dp)
00439   {
00440     for (unsigned i = 0; i < dim; ++i)
00441       coord_[i] -= dp[i];
00442     return *this;
00443   }
00444 
00445   template <typename G, typename C>
00446   inline
00447   point<G,C>::operator typename internal::vec_of_point<G,C>::ret () const // Hack to help g++-2.95.
00448   {
00449     return to_vec();
00450   }
00451 
00452   template <typename G, typename C>
00453   inline
00454   typename point<G,C>::vec
00455   point<G,C>::to_vec() const
00456   {
00457     //FIXME: to be improved.
00458     if (dim > 2)
00459     {
00460       algebra::vec<G::dim, float> tmp;
00461       unsigned j = 0;
00462       for (unsigned i = dim - 2; i < dim; ++i)
00463         tmp[j++] = coord_[i];
00464       for (unsigned i = 2; i < dim; ++i, ++j)
00465         tmp[j] = coord_[i-j];
00466 
00467       return tmp;
00468     }
00469 
00470     return coord_;
00471   }
00472 
00473   template <typename G, typename C>
00474   inline
00475   typename point<G,C>::h_vec
00476   point<G,C>::to_h_vec() const
00477   {
00478     algebra::h_vec<G::dim, float> tmp;
00479 
00480     //FIXME: to be improved.
00481     if (dim == 1)
00482       tmp[0] = coord_[0];
00483     else
00484     {
00485       unsigned j = 0;
00486       for (unsigned i = dim - 2; i < dim; ++i)
00487         tmp[j++] = coord_[i];
00488 
00489       for (unsigned i = 2; i < dim; ++i, ++j)
00490         tmp[j] = coord_[i-j];
00491 
00492       tmp[G::dim] = 1;
00493     }
00494 
00495     return tmp;
00496   }
00497 
00498 
00499   template <typename G, typename C>
00500   inline
00501   const point<G,C>&
00502   point<G,C>::plus_infty()
00503   {
00504     static const point<G,C> the_(all_to(mln_max(C)));
00505     return the_;
00506   }
00507 
00508   template <typename G, typename C>
00509   inline
00510   const point<G,C>&
00511   point<G,C>::minus_infty()
00512   {
00513     static const point<G,C> the_(all_to(mln_min(C)));
00514     return the_;
00515   }
00516 
00517   namespace internal
00518   {
00519 
00520     template <typename G, typename C, typename E>
00521     inline
00522     const E&
00523     subject_point_impl< point<G,C>, E >::exact_() const
00524     {
00525       return internal::force_exact<const E>(*this);
00526     }
00527 
00528     template <typename G, typename C, typename E>
00529     inline
00530     typename point<G,C>::vec
00531     subject_point_impl< point<G,C>, E >::to_vec() const
00532     {
00533       return exact_().get_subject().to_vec();
00534     }
00535 
00536     template <typename G, typename C, typename E>
00537     inline
00538     subject_point_impl< point<G,C>, E >::operator typename point<G,C>::vec () const // Hack to help g++-2.95.
00539     {
00540       return exact_().get_subject();
00541     }
00542 
00543   } // end of namespace mln::internal
00544 
00545   template <typename G, typename C>
00546   inline
00547   const algebra::vec<point<G,C>::dim - 1, C>&
00548   cut_(const point<G,C>& p)
00549   {
00550     return *(algebra::vec<point<G,C>::dim - 1, C>*)(& p.to_vec());
00551   }
00552 
00553   template <typename C>
00554   inline
00555   const util::yes&
00556   cut_(const point<grid::tick,C>& p)
00557   {
00558     util::yes* the_;
00559     return *the_;
00560   }
00561 
00562 # endif // ! MLN_INCLUDE_ONLY
00563 
00564 
00565 } // end of namespace mln
00566 
00567 
00568 #endif // ! MLN_CORE_POINT_HH

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