Milena (Olena)
User documentation 2.0a Id
|
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_CONCEPT_GPOINT_HH 00027 # define MLN_CORE_CONCEPT_GPOINT_HH 00028 00032 00033 00034 # include <mln/core/concept/site.hh> 00035 # include <mln/core/concept/gdpoint.hh> 00036 # include <mln/value/scalar.hh> 00037 # include <mln/algebra/vec.hh> 00038 # include <mln/util/ord.hh> 00039 # include <mln/debug/format.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 // Forward declaration. 00046 template <typename E> struct Gpoint; 00047 00048 00049 00050 namespace trait 00051 { 00052 00053 template < typename P, typename D > 00054 struct set_binary_< op::plus, 00055 mln::Gpoint, P, mln::Gdpoint, D > 00056 { 00057 typedef P ret; 00058 }; 00059 00060 template < typename P, typename D > 00061 struct set_binary_< op::minus, 00062 mln::Gpoint, P, mln::Gdpoint, D > 00063 { 00064 typedef P ret; 00065 }; 00066 00067 template < typename L, typename R > 00068 struct set_binary_< op::minus, 00069 mln::Gpoint, L, mln::Gpoint, R > 00070 { 00071 typedef mln_delta(L) ret; 00072 }; 00073 00074 template < typename L, typename R > 00075 struct set_binary_< op::times, 00076 mln::Gpoint, L, 00077 mln::Object, mln::value::scalar_<R> > 00078 { 00079 typedef L ret; 00080 }; 00081 00082 template < typename L, typename R > 00083 struct set_binary_< op::div, 00084 mln::Gpoint, L, 00085 mln::Object, mln::value::scalar_<R> > 00086 { 00087 typedef L ret; 00088 }; 00089 00090 template <typename P> 00091 struct set_unary_< op::ord, mln::Gpoint, P > 00092 { 00093 typedef mln::internal::ord_vec< P > ret; 00094 }; 00095 00096 } // end of namespace mln::trait 00097 00098 00099 00100 // Gpoint category flag type. 00101 template <> 00102 struct Gpoint<void> 00103 { 00104 typedef Site<void> super; 00105 }; 00106 00107 00114 template <typename E> 00115 struct Gpoint : public Site<E> 00116 { 00117 typedef Gpoint<void> category; 00118 00119 /* 00120 typedef grid; 00121 typedef delta; 00122 typedef vec; 00123 const vec& to_vec() const 00124 */ 00125 protected: 00126 Gpoint(); 00127 }; 00128 00129 00130 namespace convert 00131 { 00132 00133 namespace over_load 00134 { 00135 00136 template <typename P> 00137 void 00138 from_to_(const Gpoint<P>& from, mln_delta(P)& to); 00139 00140 template <typename P, unsigned n, typename T> 00141 void 00142 from_to_(const Gpoint<P>& from, algebra::vec<n,T>& to); 00143 00144 template <unsigned n, typename T, typename P> 00145 void 00146 from_to_(const algebra::vec<n,T>& from, Gpoint<P>& to); 00147 00148 } // end of namespace mln::convert::over_load 00149 00150 } // end of namespace mln::convert 00151 00152 00153 00156 00168 template <typename L, typename R> 00169 bool operator==(const Gpoint<L>& lhs, const Gpoint<R>& rhs); 00170 00171 00174 00192 template <typename L, typename R> 00193 mln_delta(L) 00194 operator-(const Gpoint<L>& lhs, const Gpoint<R>& rhs); 00195 00196 00199 00209 template <typename P, typename D> 00210 P 00211 operator+(const Gpoint<P>& p, const Gdpoint<D>& dp); 00212 00213 00214 00217 00227 template <typename P, typename D> 00228 P 00229 operator-(const Gpoint<P>& p, const Gdpoint<D>& dp); 00230 00231 00233 // 00234 template <typename P, typename S> 00235 P 00236 operator*(const Gpoint<P>& p, const value::scalar_<S>& s); 00237 00238 00240 00247 template <typename P> 00248 std::ostream& operator<<(std::ostream& ostr, const Gpoint<P>& p); 00249 00250 00252 00261 template <typename P, typename D> 00262 P& operator+=(Gpoint<P>& p, const Gdpoint<D>& dp); 00263 00264 00266 00275 template <typename P, typename D> 00276 P& operator-=(Gpoint<P>& p, const Gdpoint<D>& dp); 00277 00279 00285 template <typename P, typename D> 00286 P operator/(const Gpoint<P>& p, const value::scalar_<D>& dp); 00287 00288 // FIXME : add operators and traits? 00289 00290 00291 00292 # ifndef MLN_INCLUDE_ONLY 00293 00294 00295 // Gpoint 00296 00297 template <typename E> 00298 inline 00299 Gpoint<E>::Gpoint() 00300 { 00301 typedef mln_grid(E) grid; 00302 typedef mln_delta(E) delta; 00303 typedef mln_vec(E) vec; 00304 vec (E::*m)() const = & E::to_vec; 00305 m = 0; 00306 } 00307 00308 00309 // convert::from_to_ 00310 00311 namespace convert 00312 { 00313 00314 namespace over_load 00315 { 00316 00317 // Gpoint -> delta 00318 template <typename P> 00319 inline 00320 void 00321 from_to_(const Gpoint<P>& p_, mln_delta(P)& dp) 00322 { 00323 // Instead of "dp.to_vec() = exact(p).to_vec();" that 00324 // does not compile (cause to_vec returns const), we 00325 // have: 00326 enum { n = P::dim }; 00327 const P& p = exact(p_); 00328 for (unsigned i = 0; i < n; ++i) 00329 dp[i] = p[i]; 00330 } 00331 00332 // Gpoint -> algebra::vec. 00333 template <typename P, unsigned n, typename T> 00334 inline 00335 void 00336 from_to_(const Gpoint<P>& from_, algebra::vec<n,T>& to) 00337 { 00338 mlc_bool(n == P::dim)::check(); 00339 const P& from = exact(from_); 00340 for (unsigned i = 0; i < n; ++i) 00341 to[i] = static_cast< T >(from[i]); // FIXME: cast -> best effort... 00342 } 00343 00344 // algebra::vec -> Gpoint. 00345 template <unsigned n, typename T, typename P> 00346 inline 00347 void 00348 from_to_(const algebra::vec<n,T>& from, Gpoint<P>& to_) 00349 { 00350 mlc_bool(P::dim == n)::check(); 00351 P& to = exact(to_); 00352 for (unsigned i = 0; i < n; ++i) 00353 to[i] = static_cast< typename P::coord >(from[i]); // FIXME: cast -> best effort... 00354 } 00355 00356 } // end of namespace mln::convert::over_load 00357 00358 } // end of namespace mln::convert 00359 00360 00361 // Operators. 00362 00363 template <typename L, typename R> 00364 inline 00365 bool operator==(const Gpoint<L>& lhs, const Gpoint<R>& rhs) 00366 { 00367 mlc_equal(mln_grid(L), mln_grid(R))::check(); 00368 return exact(lhs).to_vec() == exact(rhs).to_vec(); 00369 } 00370 00371 template <typename L, typename R> 00372 inline 00373 mln_delta(L) // FIXME: promote! 00374 operator-(const Gpoint<L>& lhs, const Gpoint<R>& rhs) 00375 { 00376 mlc_equal(mln_grid(L), mln_grid(R))::check(); 00377 mln_delta(L) tmp = exact(lhs).to_vec() - exact(rhs).to_vec(); 00378 mln_postcondition(rhs + tmp == lhs); 00379 return tmp; 00380 } 00381 00382 template <typename P, typename D> 00383 inline 00384 P // FIXME: promote! 00385 operator+(const Gpoint<P>& p, const Gdpoint<D>& dp) 00386 { 00387 mlc_equal(mln_grid(P), mln_grid(D))::check(); 00388 P tmp = exact(p).to_vec() + exact(dp).to_vec(); 00389 return tmp; 00390 } 00391 00392 template <typename P, typename D> 00393 inline 00394 P // FIXME: promote! 00395 operator-(const Gpoint<P>& p, const Gdpoint<D>& dp) 00396 { 00397 mlc_equal(mln_grid(P), mln_grid(D))::check(); 00398 P tmp = exact(p).to_vec() - exact(dp).to_vec(); 00399 return tmp; 00400 } 00401 00402 template <typename P, typename S> 00403 inline 00404 P 00405 operator*(const Gpoint<P>& p, const value::scalar_<S>& s) 00406 { 00407 S s_ = s.to_equiv(); 00408 const unsigned n = P::dim; 00409 P tmp = exact(p); 00410 for (unsigned i = 0; i < n; ++i) 00411 tmp[i] *= s_; 00412 return tmp; 00413 } 00414 00415 template <typename P> 00416 inline 00417 std::ostream& operator<<(std::ostream& ostr, const Gpoint<P>& p) 00418 { 00419 enum { n = P::dim }; 00420 ostr << '('; 00421 for (unsigned i = 0; i < n; ++i) 00422 ostr << debug::format(exact(p)[i]) << (i == n - 1 ? ')' : ','); 00423 return ostr; 00424 } 00425 00426 template <typename P, typename D> 00427 inline 00428 P& operator+=(Gpoint<P>& p, const Gdpoint<D>& dp) 00429 { 00430 mlc_equal(mln_grid(P), mln_grid(D))::check(); 00431 return exact(p) = p + dp; 00432 } 00433 00434 template <typename P, typename D> 00435 inline 00436 P& operator-=(Gpoint<P>& p, const Gdpoint<D>& dp) 00437 { 00438 mlc_equal(mln_grid(P), mln_grid(D))::check(); 00439 return exact(p) = p - dp; 00440 } 00441 00442 00443 template <typename P, typename S> 00444 inline 00445 P 00446 operator/(const Gpoint<P>& p, const value::scalar_<S>& s_) 00447 { 00448 S s = s_.to_equiv(); 00449 const unsigned n = P::dim; 00450 P tmp = exact(p); 00451 for (unsigned i = 0; i < n; ++i) 00452 tmp[i] /= s; 00453 return tmp; 00454 } 00455 00456 # endif // ! MLN_INCLUDE_ONLY 00457 00458 } // end of namespace mln 00459 00460 00461 00462 #endif // ! MLN_CORE_CONCEPT_GPOINT_HH