https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Equip proxies to transparently handle operators.
* doc/tutorial/examples/p_array.cc: Add tests on proxy_level and
on op== applied on proxies.
* mln/core/concept/proxy.hh (internal): New meta-code.
(set_binary_, set_unary_): Re-activate and make it work.
(operator==): New; it is only a start.
(operator-): Likewise.
(proxy_level): New in Proxy requirements.
(helper_proxy_impl): Define proxy_level.
* mln/core/concept/gpoint.hh: .
doc/tutorial/examples/p_array.cc | 28 +++++++-
mln/core/concept/gpoint.hh | 2
mln/core/concept/proxy.hh | 129 ++++++++++++++++++++++++++++++++++-----
3 files changed, 142 insertions(+), 17 deletions(-)
Index: doc/tutorial/examples/p_array.cc
--- doc/tutorial/examples/p_array.cc (revision 2030)
+++ doc/tutorial/examples/p_array.cc (working copy)
@@ -27,6 +27,15 @@
using namespace mln;
typedef p_array<point2d> Arr1;
+ typedef p_array<mln_psite_(Arr1)> Arr2;
+
+ {
+ mln_assertion(mln_psite_(Arr1)::proxy_level == 1);
+ mln_assertion(mln_piter_(Arr1)::proxy_level == 2);
+ mln_assertion(mln_psite_(Arr2)::proxy_level == 2);
+ mln_assertion(mln_piter_(Arr2)::proxy_level == 3);
+ }
+
Arr1 arr1;
{
@@ -41,22 +50,26 @@
}
{
- typedef p_array< mln_psite_(Arr1) > Arr2;
+
Arr2 arr2;
+ // Fill arr2 from arr1 contents.
+ {
mln_piter_(Arr1) p(arr1);
for_all(p)
if (p.row() % 2 && p.col() % 2)
arr2.append(p);
+ }
std::cout << "arr2 = " << arr2 << std::endl;
picture(arr2);
+ // Display indices.
{
mln_piter_(Arr2) p(arr2);
for_all(p)
{
-// mln_assertion(make::point2d(p.row(), p.col()) == p); // FIXME: Make it work.
+ mln_assertion(make::point2d(p.row(), p.col()) == p);
std::cout << "point " << p << ": #"
<< index_of_in(p, arr2) << " in arr2, #"
<< index_of_in(p, arr1) << " in arr1" << std::endl;
@@ -64,6 +77,17 @@
}
mln_invariant(arr2 < arr1);
+
+ {
+ mln_piter_(Arr1) p1(arr1);
+ mln_piter_(Arr2) p2(arr2);
+ for_all_2(p1, p2)
+ {
+ mln_assertion(p2 == p1); // same as: p2.to_site() == p1.to_site()
+ p1.next(); // p1 goes twice fast as p2.
+ }
+ }
+
}
}
Index: mln/core/concept/proxy.hh
--- mln/core/concept/proxy.hh (revision 2030)
+++ mln/core/concept/proxy.hh (working copy)
@@ -46,40 +46,75 @@
template <typename E> struct Proxy;
- /*
- FIXME: Re-activate.
+ namespace internal
+ {
- namespace trait
+ template <bool b, typename P> struct unproxy_if;
+
+ template <typename P>
+ struct unproxy_if< true, P >
+ {
+ typedef mln_subject(P) ret;
+ static typename P::q_subject on(const Proxy<P>& p) { return
exact(p).unproxy(); }
+ };
+
+ template <typename P>
+ struct unproxy_if< false, P >
{
+ typedef P ret;
+ static const P& on(const Proxy<P>& p) { return exact(p); }
+ };
+
+ template <typename L, typename R>
+ struct unproxy_couple
+ {
+ enum { L_level = L::proxy_level,
+ R_level = R::proxy_level }; // To prevent a weird g++ warning.
+ typedef internal::unproxy_if<(L_level >= R_level), L> L_helper;
+ typedef internal::unproxy_if<(R_level >= L_level), R> R_helper;
+ typedef typename L_helper::ret L_ret;
+ typedef typename R_helper::ret R_ret;
+ };
- template < typename Op, typename P1, typename P2 >
- struct set_binary_< Op, mln::Proxy, P1, mln::Proxy, P2 >
+ } // end of namespace mln::internal
+
+
+
+ namespace trait
{
- typedef mln_trait_binary(Op, mln_subject(P1), mln_subject(P2)) ret;
+
+ template < template <class, class> class Op,
+ typename L, typename R >
+ struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
+ {
+ typedef mln::internal::unproxy_couple<L, R> helper;
+ typedef mln_trait_binary(Op,
+ typename helper::L_ret,
+ typename helper::R_ret) ret;
};
- template < typename Op, typename P, typename O >
+ template < template <class, class> class Op,
+ typename P, typename O >
struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
{
typedef mln_trait_binary(Op, mln_subject(P), O) ret;
};
- template < typename Op, typename E, typename P >
- struct set_binary_< Op, mln::Object, E, mln::Proxy, P >
+ template < template <class, class> class Op,
+ typename O, typename P >
+ struct set_binary_< Op, mln::Object, O, mln::Proxy, P >
{
typedef mln_trait_binary(Op, O, mln_subject(P)) ret;
};
- template < typename Op, typename P >
- struct set_binary_< Op, mln::Proxy, P >
+ template < template <class> class Op, typename P >
+ struct set_unary_< Op, mln::Proxy, P >
{
typedef mln_trait_unary(Op, mln_subject(P)) ret;
};
} // end of namespace mln::trait
- */
-
/// Proxy category flag type.
@@ -99,6 +134,7 @@
typedef Proxy<void> category;
/*
+ enum { proxy_level };
typedef subject;
typedef q_subject;
q_subject unproxy() const;
@@ -113,6 +149,63 @@
};
+
+ template <typename L, typename R>
+ inline
+ mln_trait_op_minus(L, R)
+ operator-(const mln::Proxy<L>& lhs, const mln::Proxy<R>& rhs)
+ {
+ typedef typename internal::unproxy_couple<L, R>::L_helper L_unproxy;
+ typedef typename internal::unproxy_couple<L, R>::R_helper R_unproxy;
+ return L_unproxy::on(lhs) - R_unproxy::on(rhs);
+ }
+
+ template <typename P, typename O>
+ inline
+ mln_trait_op_minus(P, O)
+ operator-(const Proxy<P>& p, const Object<O>& o)
+ {
+ return exact(p).unproxy() - exact(o);
+ }
+
+ template <typename O, typename P>
+ inline
+ mln_trait_op_minus(O, P)
+ operator-(const Object<O>& o, const Proxy<P>& p)
+ {
+ return exact(o) - exact(p).unproxy();
+ }
+
+
+
+ template <typename L, typename R>
+ inline
+ mln_trait_op_eq(L, R)
+ operator==(const mln::Proxy<L>& lhs, const mln::Proxy<R>& rhs)
+ {
+ typedef typename internal::unproxy_couple<L, R>::L_helper L_unproxy;
+ typedef typename internal::unproxy_couple<L, R>::R_helper R_unproxy;
+ return L_unproxy::on(lhs) == R_unproxy::on(rhs);
+ }
+
+ template <typename P, typename O>
+ inline
+ mln_trait_op_eq(P, O)
+ operator==(const Proxy<P>& p, const Object<O>& o)
+ {
+ return exact(p).unproxy() == exact(o);
+ }
+
+ template <typename O, typename P>
+ inline
+ mln_trait_op_eq(O, P)
+ operator==(const Object<O>& o, const Proxy<P>& p)
+ {
+ return exact(o) == exact(p).unproxy();
+ }
+
+
+
namespace internal
{
@@ -181,11 +274,15 @@
template <typename Subject, typename E, bool rec = true>
struct helper_proxy_impl : proxy_impl< mln_subject(Subject), E > // Rec.
- {};
+ {
+ enum { proxy_level = Subject::proxy_level + 1};
+ };
template <typename Subject, typename E>
struct helper_proxy_impl< Subject, E, false > // Stop rec.
- {};
+ {
+ enum { proxy_level = 1 };
+ };
template <typename Subject, typename E>
struct proxy_impl : helper_proxy_impl< Subject, E,
@@ -224,6 +321,8 @@
inline
Proxy<E>::Proxy()
{
+ enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0...
+
typedef mln_subject(E) subject;
typedef typename E::q_subject q_subject;
Index: mln/core/concept/gpoint.hh
--- mln/core/concept/gpoint.hh (revision 2030)
+++ mln/core/concept/gpoint.hh (working copy)
@@ -92,6 +92,8 @@
template <typename E>
struct Gpoint : public Object<E>
{
+ typedef Gpoint<void> category;
+
/*
typedef grid;
typedef delta;