
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@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