https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add operators to Proxy and make Accumulator inherit from Proxy.
* doc/tutorial/examples/accu.cc: New.
* mln/core/ops.hh: Add doc.
(operator++, operator--): Rename rhs as lhs.
* mln/core/concept/proxy.hh (include): Add mln/value/ops.hh. This
is required for the client to transparently handle builtins,
scalars, and objects.
(mln_decl_unop_proxy, mln_def_unop_proxy): New macros.
(mln_decl_binop_proxy, mln_def_binop_proxy): New macros.
(operator): Add unary and binary operators for proxies.
(operator-, operator==): Remove test versions.
* mln/core/concept/accumulator.hh (Accumulator): Change
inheritance from Object to Proxy.
(operator<<): Remove; obsolete cause already in Proxy.
* mln/metal/unqualif.hh (unqualif): Fix bug; it does not has to
rely on unptr.
Add doc.
* mln/metal/bool.hh (mlc_bool): New useful macro.
* mln/accu/sum.hh: Cleanup includes and add some comments.
* mln/accu/internal/base.hh (base_): Inherit from proxy_impl.
(subject, q_subject, unproxy): New to conform to Proxy.
(operator result_): Remove cause obsolete.
* mln/util/yes.hh (yes): Turn explicit the ctor.
(operator): Update.
* mln/core/concept/site_set.hh: Propagate util::yes update.
doc/tutorial/examples/accu.cc | 21 +++
mln/accu/internal/base.hh | 24 +++-
mln/accu/sum.hh | 10 +
mln/core/concept/accumulator.hh | 29 +----
mln/core/concept/proxy.hh | 217 +++++++++++++++++++++++++++-------------
mln/core/concept/site_set.hh | 6 -
mln/core/ops.hh | 67 ++++++++++--
mln/metal/bool.hh | 9 +
mln/metal/unqualif.hh | 12 --
mln/util/yes.hh | 10 -
10 files changed, 277 insertions(+), 128 deletions(-)
Index: doc/tutorial/examples/accu.cc
--- doc/tutorial/examples/accu.cc (revision 0)
+++ doc/tutorial/examples/accu.cc (revision 0)
@@ -0,0 +1,21 @@
+# include <mln/accu/mean.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+
+ mlc_bool(accu::mean_<int>::proxy_level == 1)::check();
+
+ accu::mean_<int> m;
+ m.take(100);
+ m.take(2);
+ mln_assertion(m == 51);
+
+ // Just for fun:
+ mln_assertion(literal::zero != m);
+ mln_assertion(m != literal::zero);
+
+ std::cout << (-m) << std::endl;
+}
Index: mln/core/ops.hh
--- mln/core/ops.hh (revision 2035)
+++ mln/core/ops.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -32,6 +32,51 @@
*
* \brief Definitions of some default implementations for operators.
*
+ * The set of operators defined in this file is:
+ *
+ * \code
+
+ l += r : l = l + r, -> l&
+ l -= r : l = l - r, -> l&
+ l *= r : l = l * r, -> l&
+ l /= r : l = l / r, -> l&
+ l %= r : l = l % r, -> l&
+
+ + r : -> r
+ - r : -> (0 - r)
+
+ l ++ : t = l, ++l, -> t
+ l -- : t = l, --l, -> t
+
+ ++ r : r += 1, -> r&
+ -- r : r -= 1, -> r&
+
+ l != r : -> ! (l == r)
+
+ l > r : -> (r < l)
+ l >= r : -> (r <= l)
+ l <= r : -> ! (r < l) warning: re-define when partial ordering
+
+ * \endcode
+ *
+ *
+ * As a consequence, the set of operators to be defined along with a
+ * client class is:
+ *
+ * \code
+
+ l + r
+ l - r
+ l * r
+ l / r
+
+ l == r
+
+ l < r
+ l <= r in case of partial ordering
+
+ * \endcode
+ *
* \todo Complete those definitions (...) + Overload for const (?)
*/
@@ -220,7 +265,7 @@
* It relies on the definition of the pre-incrementation operator.
*/
template <typename O>
- O operator++(Object<O>& rhs, int);
+ O operator++(Object<O>& lhs, int);
/* \brief Default definition of the post-decrementation operator.
@@ -228,7 +273,7 @@
* It relies on the definition of the pre-decrementation operator.
*/
template <typename O>
- O operator--(Object<O>& rhs, int);
+ O operator--(Object<O>& lhs, int);
/* \brief Default definition of the pre-incrementation operator.
@@ -422,11 +467,11 @@
template <typename O>
inline
O
- operator++(Object<O>& rhs, int)
+ operator++(Object<O>& lhs, int)
{
- O tmp(exact(rhs)); // Copy.
- ++exact(rhs); // Pre-inc.
- // FIXME: Activate: mln_postcondition(exact(rhs) == tmp + literal::one);
+ O tmp(exact(lhs)); // Copy.
+ ++exact(lhs); // Pre-inc.
+ // FIXME: Activate: mln_postcondition(exact(lhs) == tmp + literal::one);
return tmp;
}
@@ -435,11 +480,11 @@
template <typename O>
inline
O
- operator--(Object<O>& rhs, int)
+ operator--(Object<O>& lhs, int)
{
- O tmp(exact(rhs)); // Copy.
- --exact(rhs); // Pre-dec.
- // FIXME: Activate: mln_postcondition(exact(rhs) == tmp - literal::one);
+ O tmp(exact(lhs)); // Copy.
+ --exact(lhs); // Pre-dec.
+ // FIXME: Activate: mln_postcondition(exact(lhs) == tmp - literal::one);
return tmp;
}
Index: mln/core/concept/proxy.hh
--- mln/core/concept/proxy.hh (revision 2035)
+++ mln/core/concept/proxy.hh (working copy)
@@ -31,11 +31,89 @@
/*! \file mln/core/concept/proxy.hh
*
* \brief Definition of the concept of mln::Proxy.
+ *
+ * \todo preinc and predec are not tested; post-like ops are not handled.
*/
# include <mln/core/concept/object.hh>
# include <mln/core/internal/force_exact.hh>
-# include <mln/trait/all.hh>
+# include <mln/value/ops.hh> // So that we can handle builtins, scalars, and
objects.
+
+
+
+# define mln_decl_unop_proxy(Name, Symb) \
+ \
+ template <typename P> \
+ mln_trait_op_##Name(P) \
+ operator Symb (const Proxy<P>& rhs); \
+ \
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+# define mln_def_unop_proxy(Name, Symb) \
+ \
+ template <typename P> \
+ inline \
+ mln_trait_op_##Name(P) \
+ operator Symb (const mln::Proxy<P>& rhs) \
+ { \
+ return Symb exact(rhs).unproxy(); \
+ } \
+ \
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+
+
+
+# define mln_decl_binop_proxy(Name, Symb) \
+ \
+ template <typename L, typename R> \
+ mln_trait_op_##Name(L, R) \
+ operator Symb (const Proxy<L>& lhs, const Proxy<R>& rhs); \
+ \
+ template <typename P, typename O> \
+ mln_trait_op_##Name(P, O) \
+ operator Symb (const Proxy<P>& p, const Object<O>& o); \
+ \
+ template <typename O, typename P> \
+ mln_trait_op_##Name(O, P) \
+ operator Symb (const Object<O>& o, const Proxy<P>& p); \
+ \
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+
+# define mln_def_binop_proxy(Name, Symb) \
+ \
+ template <typename L, typename R> \
+ inline \
+ mln_trait_op_##Name(L, R) \
+ operator Symb (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) Symb R_unproxy::on(rhs); \
+ } \
+ \
+ template <typename P, typename O> \
+ inline \
+ mln_trait_op_##Name(P, O) \
+ operator Symb (const Proxy<P>& p, const Object<O>& o) \
+ { \
+ return exact(p).unproxy() Symb exact(o); \
+ } \
+ \
+ template <typename O, typename P> \
+ inline \
+ mln_trait_op_##Name(O, P) \
+ operator Symb (const Object<O>& o, const Proxy<P>& p) \
+ { \
+ return exact(o) Symb exact(p).unproxy(); \
+ } \
+ \
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
@@ -83,6 +161,16 @@
namespace trait
{
+ // Unary ops.
+
+ template < template <class> class Op, typename P >
+ struct set_unary_< Op, mln::Proxy, P >
+ {
+ typedef mln_trait_unary(Op, mln_subject(P)) ret;
+ };
+
+ // Binary ops.
+
template < template <class, class> class Op,
typename L, typename R >
struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
@@ -107,16 +195,11 @@
typedef mln_trait_binary(Op, O, mln_subject(P)) ret;
};
- 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.
template <>
struct Proxy<void>
@@ -150,59 +233,33 @@
- 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>
+ std::ostream& operator<<(std::ostream& ostr, const Proxy<P>&
p);
- 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();
- }
+ mln_decl_unop_proxy(uplus, + );
+ mln_decl_unop_proxy(uminus, - );
+ mln_decl_unop_proxy(preinc, ++ );
+ mln_decl_unop_proxy(predec, -- );
+ mln_decl_unop_proxy(not, ! );
+
+ mln_decl_binop_proxy(plus, + );
+ mln_decl_binop_proxy(minus, - );
+ mln_decl_binop_proxy(times, * );
+ mln_decl_binop_proxy(div, / );
+ mln_decl_binop_proxy(mod, % );
+
+ mln_decl_binop_proxy(eq, == );
+ mln_decl_binop_proxy(neq, != );
+
+ mln_decl_binop_proxy(less, < );
+ mln_decl_binop_proxy(leq, <= );
+ mln_decl_binop_proxy(geq, >= );
+ mln_decl_binop_proxy(greater, > );
+
+ mln_decl_binop_proxy(and, && );
+ mln_decl_binop_proxy(or, || );
+ mln_decl_binop_proxy(xor, ^ );
@@ -291,8 +348,10 @@
operator Subject() const
{
return mln::internal::force_exact<const E>(*this).unproxy();
- // The code above seems more effective than the one below:
+
+ // Technical note:
//
+ // The code above seems more effective than the one below:
// const Subject* adr;
// get_adr(adr, mln::internal::force_exact<const E>(*this));
// mln_postcondition(adr != 0);
@@ -304,15 +363,6 @@
} // end of namespace mln::internal
- // FIXME:...
-
-// template <typename L, typename R>
-// bool operator==(const Proxy<L>& lhs, const Proxy<R>& rhs);
-
- template <typename P>
- std::ostream& operator<<(std::ostream& ostr, const Proxy<P>&
p);
-
-
# ifndef MLN_INCLUDE_ONLY
@@ -336,7 +386,36 @@
return ostr << exact(p).unproxy();
}
- // FIXME: Code operators...
+
+ // Unary operators.
+
+ mln_def_unop_proxy(uplus, + );
+ mln_def_unop_proxy(uminus, - );
+ mln_def_unop_proxy(preinc, ++ );
+ mln_def_unop_proxy(predec, -- );
+ mln_def_unop_proxy(not, ! );
+
+
+ // Binary operators.
+
+ mln_def_binop_proxy(plus, + );
+ mln_def_binop_proxy(minus, - );
+ mln_def_binop_proxy(times, * );
+ mln_def_binop_proxy(div, / );
+ mln_def_binop_proxy(mod, % );
+
+ mln_def_binop_proxy(eq, == );
+ mln_def_binop_proxy(neq, != );
+
+ mln_def_binop_proxy(less, < );
+ mln_def_binop_proxy(leq, <= );
+ mln_def_binop_proxy(geq, >= );
+ mln_def_binop_proxy(greater, > );
+
+ mln_def_binop_proxy(and, && );
+ mln_def_binop_proxy(or, || );
+ mln_def_binop_proxy(xor, ^ );
+
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/concept/accumulator.hh
--- mln/core/concept/accumulator.hh (revision 2035)
+++ mln/core/concept/accumulator.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -31,11 +31,9 @@
/*! \file mln/core/concept/accumulator.hh
*
* \brief Definition of the concept of mln::Accumulator.
- *
- * \todo Rename value as argument + Add a conversion op.
*/
-# include <mln/core/concept/object.hh>
+# include <mln/core/concept/proxy.hh>
namespace mln
@@ -48,7 +46,7 @@
template <>
struct Accumulator<void>
{
- typedef Object<void> super;
+ typedef Proxy<void> super;
};
@@ -60,16 +58,18 @@
* class contents.
*/
template <typename E>
- struct Accumulator : public Object<E>
+ struct Accumulator : public Proxy<E>
{
typedef Accumulator<void> category;
/*
typedef argument;
typedef result;
+
void init();
void take(const argument& t);
void take(const E& other);
+
result to_result() const;
operator result_() const;
*/
@@ -82,10 +82,6 @@
Accumulator();
};
- template <typename E>
- std::ostream&
- operator<<(std::ostream& ostr, const Accumulator<E>& accu);
-
# ifndef MLN_INCLUDE_ONLY
@@ -102,10 +98,11 @@
m2 = 0;
void (E::*m3)(const E&) = & E::take;
m3 = 0;
+
result (E::*m4)() const = & E::to_result;
m4 = 0;
-// result (E::*m5)() const = & E::operator result;
-// m5 = 0;
+ result (E::*m5)() const = & E::operator result;
+ m5 = 0;
}
template <typename E>
@@ -117,14 +114,6 @@
exact(this)->take(t);
}
- template <typename E>
- inline
- std::ostream&
- operator<<(std::ostream& ostr, const Accumulator<E>& accu)
- {
- return ostr << exact(accu).to_result();
- }
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/concept/site_set.hh
--- mln/core/concept/site_set.hh (revision 2035)
+++ mln/core/concept/site_set.hh (working copy)
@@ -205,7 +205,7 @@
// // both sets are equal only if both browsings are completed
// // at the same time:
// return ! pl.is_valid() && ! pr.is_valid();
- return true;
+ return util::yes(true);
}
@@ -223,7 +223,7 @@
// if (! rhs.has(pl))
// return false;
- return true;
+ return util::yes(true);
}
@@ -235,7 +235,7 @@
// const Sl& lhs = exact(lhs_);
// const Sr& rhs = exact(rhs_);
// return lhs <= rhs && lhs != rhs;
- return true;
+ return util::yes(true);
}
Index: mln/metal/unqualif.hh
--- mln/metal/unqualif.hh (revision 2035)
+++ mln/metal/unqualif.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -31,11 +31,11 @@
/*!
* \file mln/metal/unqualif.hh
*
- * \brief FIXME.
+ * \brief Suppress possible 'const' and/or '&' (reference) from a
+ * qualified type.
*/
# include <mln/metal/unconst.hh>
-# include <mln/metal/unptr.hh>
# include <mln/metal/unref.hh>
@@ -49,14 +49,10 @@
namespace metal
{
- // FIXME: May be recursive!
-
template <typename T>
struct unqualif
{
- typedef mlc_unref(T) tmp1;
- typedef mlc_unconst(tmp1) tmp2;
- typedef mlc_unptr(tmp2) ret;
+ typedef mlc_unconst( mlc_unref(T) ) ret;
};
} // end of namespace mln::metal
Index: mln/metal/bool.hh
--- mln/metal/bool.hh (revision 2035)
+++ mln/metal/bool.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -36,6 +36,13 @@
# include <string>
+# define mlc_bool(B) mln::metal::bool_<( B )>
+
+// The macro above is very convenient for static checks on Boolean
+// expressions, e.g., "mlc_bool(m == n)::check();"
+
+
+
namespace mln
{
Index: mln/accu/sum.hh
--- mln/accu/sum.hh (revision 2035)
+++ mln/accu/sum.hh (working copy)
@@ -34,11 +34,13 @@
*/
# include <mln/core/concept/meta_accumulator.hh>
-
# include <mln/accu/internal/base.hh>
-# include <mln/trait/value_.hh>
-# include <mln/util/pix.hh>
-# include <mln/literal/zero.hh>
+
+# include <mln/util/pix.hh> // To prevent accu::sum to work on pixels (ambiguous).
+
+# include <mln/trait/value_.hh> // For mln_sum.
+# include <mln/value/builtin/all.hh> // In the case of summing builtin values.
+# include <mln/literal/zero.hh> // For initialization.
namespace mln
Index: mln/accu/internal/base.hh
--- mln/accu/internal/base.hh (revision 2035)
+++ mln/accu/internal/base.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -32,11 +32,15 @@
*
* \brief Define a base class for implementation of accumulator
* classes.
+ *
+ * \todo Cf. mln/core/pseudo_site_base.hh we get some impl from
+ * site_impl; we want here the same effect except that the subject is
+ * not always a site. Maybe we actually need a more generic mechanism
+ * s.a. subject_impl...
*/
# include <mln/core/concept/accumulator.hh>
-# include <mln/metal/unconst.hh>
-# include <mln/metal/unref.hh>
+# include <mln/metal/unqualif.hh>
namespace mln
@@ -52,15 +56,20 @@
* Base class for implementation of accumulator classes.
*/
template <typename R, typename E>
- struct base_ : public Accumulator<E>
+ class base_ : public Accumulator<E>,
+ public mln::internal::proxy_impl< mlc_unqualif(R), E >
{
typedef mlc_unconst(R) tmp_;
typedef mlc_unref(tmp_) result_;
public:
- typedef R result;
+ // As a proxy:
+ typedef R q_subject;
+ typedef mlc_unqualif(R) subject;
+ R unproxy() const;
- operator result_() const;
+ // As an accumulator:
+ typedef R result;
protected:
base_();
@@ -77,7 +86,8 @@
template <typename R, typename E>
inline
- base_<R,E>::operator typename base_<R,E>::result_ () const
+ R
+ base_<R,E>::unproxy() const
{
return exact(this)->to_result();
}
Index: mln/util/yes.hh
--- mln/util/yes.hh (revision 2035)
+++ mln/util/yes.hh (working copy)
@@ -71,7 +71,7 @@
struct yes : public Object< yes >
{
yes();
- yes(bool);
+ explicit yes(bool);
operator bool() const;
};
@@ -132,25 +132,25 @@
inline
util::yes operator == (const util::yes&, bool)
{
- return true;
+ return util::yes(true);
}
inline
util::yes operator != (const util::yes&, bool)
{
- return true;
+ return util::yes(true);
}
inline
util::yes operator && (const util::yes&, bool)
{
- return true;
+ return util::yes(true);
}
inline
util::yes operator || (const util::yes&, bool)
{
- return true;
+ return util::yes(true);
}
# endif // ! MLN_INCLUDE_ONLY