proto-1.0 228: Fix operators on oln::value_box<>

C'est pas encore gagné avec les collisions d'opérateurs entre Integre et Olena (voir le commentaire dans olena/oln/morpho/lower_completion.hh), mais ça marche mieux. Peut-être qu'il faudrait tous les placer dans un seul namespace ? ChangeLog | 28 ++ oln/core/gen/internal/value_box.hh | 377 ++++++++++++++++++++++++++++--------- oln/core/pw/arith.hh | 5 oln/morpho/lower_completion.hh | 19 + 4 files changed, 333 insertions(+), 96 deletions(-) Index: olena/ChangeLog from Roland Levillain <roland@lrde.epita.fr> Fix operators on oln::value_box<>. * oln/core/gen/internal/value_box.hh (value_box<I>::operator==) (value_box<I>::operator!=, value_box<I>::operator<) (value_box<I>::operator>, value_box<const I>::operator==) (value_box<const I>::operator!=, value_box<const I>::operator<): Remove operators. (oln_decl_comp_binop_all, oln_decl_comp_binop_with_builtin) (oln_decl_comp_binop_builtin_vb, oln_decl_comp_binop_vb_builtin) (oln_decl_comp_binop_with_ntgval, oln_decl_comp_binop_ntgval_vb) (oln_decl_comp_binop_vb_ntgval, oln_decl_comp_binop_vb_vb) (oln_decl_arith_binop_all) (oln_decl_arith_binop_all_but_builtin_float) (oln_decl_arith_binop_with_builtin_float) (oln_decl_arith_binop_with_builtin_int) (oln_decl_arith_binop_with_builtin) (oln_decl_arith_binop_builtin_vb, oln_decl_arith_binop_vb_builtin) (oln_decl_arith_binop_with_ntgval, oln_decl_arith_binop_ntgval_vb) (oln_decl_arith_binop_vb_ntgval, oln_decl_arith_binop_vb_vb): New macros. Use them to implement operators whose (at least) one operand is an oln::value_box. * oln/morpho/lower_completion.hh (lower_completion): Adjust. * oln/core/pw/arith.hh: Move all operators on point-wise functions to... (oln): ...this namespace. 2005-07-04 Roland Levillain <roland@lrde.epita.fr> Index: olena/oln/core/gen/internal/value_box.hh --- olena/oln/core/gen/internal/value_box.hh (révision 226) +++ olena/oln/core/gen/internal/value_box.hh (copie de travail) @@ -31,6 +31,8 @@ # include <iostream> # include <mlc/cmp.hh> # include <oln/core/abstract/image.hh> +# include <ntg/core/value.hh> +# include <ntg/core/internal/global_ops_traits.hh> // FIXME: not coherent cause in internal/ but not internal:: @@ -80,55 +82,6 @@ typedef oln_type_of(I, point) point_type; - /// Operator == (rhs is a value_box). - template <typename II> - bool operator==(const value_box<II>& rhs) const - { - return this->value() == rhs.value(); - } - - /// Operator == (rhs is a value). - template <typename V> - bool operator==(const V& rhs) const - { - return this->value() == rhs; - } - - /// Operator !=. - template <typename V> - bool operator!=(const V& rhs) const - { - return ! this->operator==(rhs); - } - - /// Operator < (rhs is a value_box). - template <typename II> - bool operator<(const value_box<II>& rhs) const - { - return this->value() < rhs.value(); - } - - /// Operator < (rhs is a value). - template <typename V> - bool operator<(const V& rhs) const - { - return this->value() < rhs; - } - - /// Operator > (rhs is a value_box). - template <typename II> - bool operator>(const value_box<II>& rhs) const - { - return this->value() > rhs.value(); - } - - /// Operator > (rhs is a value). - template <typename V> - bool operator>(const V& rhs) const - { - return this->value() > rhs; - } - /*! \brief op= ** FIXME:... @@ -142,7 +95,6 @@ return *this; } - /*! \brief op= ** FIXME:... ** @@ -150,7 +102,7 @@ ** ** \return (*this) */ - + /// \{ template <typename II> value_box& operator=(const value_box<II>& rhs) { @@ -163,6 +115,7 @@ ima_->set(p_, rhs.value()); // automatic conversion from rhs to value_type return *this; } + /// \} /*! \brief Set @@ -264,9 +217,6 @@ }; - - - /*! \class value_box<const I> ** ** Specialization of 'value_box<I>'. @@ -288,42 +238,6 @@ typedef oln_type_of(I, point) point_type; - /// Operator == (rhs is a value_box). - template <typename II> - bool operator==(const value_box<II>& rhs) const - { - return this->value() == rhs.value(); - } - - /// Operator == (rhs is a value). - template <typename V> - bool operator==(const V& rhs) const - { - return this->value() == rhs; - } - - /// Operator !=. - template <typename V> - bool operator!=(const V& rhs) const - { - return ! this->operator==(rhs); - } - - /// Operator < (rhs is a value_box). - template <typename II> - bool operator<(const value_box<II>& rhs) const - { - return this->value() < rhs.value(); - } - - /// Operator < (rhs is a value). - template <typename V> - bool operator<(const V& rhs) const - { - return this->value() < rhs; - } - - /*! \brief Assignment (op=) is declared but undefined. */ @@ -431,6 +345,289 @@ } // end of namespace oln + +/*-----------------------. +| Comparison operators. | +`-----------------------*/ + +// FIXME: Should we equip Integre to support oln::value_box<> values instead? + +// ------------------------- // +// value_box and value_box. // +// ------------------------- // + +// oln::value_box<I> OpSymbol oln::value_box<II> +# define oln_decl_comp_binop_vb_vb(OpSymbol) \ + template <typename I, typename II> \ + bool \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + const oln::value_box<II>& rhs) \ + { \ + return lhs.value() OpSymbol rhs.value(); \ + } + + +// ------------------------------ // +// value_box and Integre values. // +// ------------------------------ // + +// oln::value_box<I> OpSymbol ntg::value<V> +# define oln_decl_comp_binop_vb_ntgval(OpSymbol) \ + template <typename I, typename V> \ + bool \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + const ntg::value<V>& rhs) \ + { \ + return lhs.value() OpSymbol rhs.exact (); \ + } + +// ntg::value<V> OpSymbol oln::value_box<I> +# define oln_decl_comp_binop_ntgval_vb(OpSymbol) \ + template <typename I, typename V> \ + bool \ + operator OpSymbol (const ntg::value<V>& lhs, \ + const oln::value_box<I>& rhs) \ + { \ + return lhs.exact() OpSymbol rhs.value(); \ + } + +# define oln_decl_comp_binop_with_ntgval(OpSymbol) \ + oln_decl_comp_binop_vb_ntgval(OpSymbol) \ + oln_decl_comp_binop_ntgval_vb(OpSymbol) + + +// -------------------------------------------- // +// value_box and C++ builtin arithmetic types. // +// -------------------------------------------- // + +// oln::value_box<I> OpSymbol Builtin +# define oln_decl_comp_binop_vb_builtin(OpSymbol, Builtin) \ + template <typename I> \ + bool \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + Builtin rhs) \ + { \ + return lhs.value() OpSymbol rhs; \ + } + +// Builtin OpSymbol oln::value_box<I> +# define oln_decl_comp_binop_builtin_vb(OpSymbol, Builtin) \ + template <typename I> \ + bool \ + operator OpSymbol (Builtin lhs, \ + const oln::value_box<I>& rhs) \ + { \ + return lhs OpSymbol rhs.value(); \ + } + +# define oln_decl_comp_binop_with_builtin(OpSymbol, Builtin) \ + oln_decl_comp_binop_vb_builtin(OpSymbol, Builtin) \ + oln_decl_comp_binop_builtin_vb(OpSymbol, Builtin) + + +// ----------- // +// Shortcuts. // +// ----------- // + +# define oln_decl_comp_binop_all(OpSymbol) \ + \ + oln_decl_comp_binop_vb_vb(OpSymbol) \ + \ + oln_decl_comp_binop_with_ntgval(OpSymbol) \ + \ + oln_decl_comp_binop_with_builtin(OpSymbol, signed long) \ + oln_decl_comp_binop_with_builtin(OpSymbol, unsigned long) \ + oln_decl_comp_binop_with_builtin(OpSymbol, signed int) \ + oln_decl_comp_binop_with_builtin(OpSymbol, unsigned int) \ + oln_decl_comp_binop_with_builtin(OpSymbol, signed short) \ + oln_decl_comp_binop_with_builtin(OpSymbol, unsigned short) \ + oln_decl_comp_binop_with_builtin(OpSymbol, char) \ + oln_decl_comp_binop_with_builtin(OpSymbol, signed char) \ + oln_decl_comp_binop_with_builtin(OpSymbol, unsigned char) \ + \ + oln_decl_comp_binop_with_builtin(OpSymbol, bool) \ + \ + oln_decl_comp_binop_with_builtin(OpSymbol, float) \ + oln_decl_comp_binop_with_builtin(OpSymbol, double) + + +// ------------------------------------ // +// ``Instantiation'' of the operators. // +// ------------------------------------ // + +namespace oln +{ + +// ``Instantiation'' of the operators. +oln_decl_comp_binop_all(==) +oln_decl_comp_binop_all(!=) +oln_decl_comp_binop_all(<) +oln_decl_comp_binop_all(<=) +oln_decl_comp_binop_all(>) +oln_decl_comp_binop_all(>=) + +} // end of namespace oln + + +# undef oln_decl_comp_binop_vb_vb +# undef oln_decl_comp_binop_vb_ntgval +# undef oln_decl_comp_binop_ntgval_vb +# undef oln_decl_comp_binop_with_ntgval +# undef oln_decl_comp_binop_vb_builtin +# undef oln_decl_comp_binop_builtin_vb +# undef oln_decl_comp_binop_with_builtin +# undef oln_decl_comp_binop + + + +/*-------------------------. +| Arithmetical operators. | +`-------------------------*/ + +// FIXME: Should we equip Integre to support oln::value_box<> values instead? + +// ------------------------- // +// value_box and value_box. // +// ------------------------- // + +// oln::value_box<I> OpSymbol oln::value_box<II> +# define oln_decl_arith_binop_vb_vb(OpSymbol, OpName) \ + template <typename I, typename II> \ + ntg_return_type(OpName, \ + typename oln::value_box<I>::value_type, \ + typename oln::value_box<II>::value_type) \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + const oln::value_box<II>& rhs) \ + { \ + return lhs.value() OpSymbol rhs.value(); \ + } + + +// ------------------------------ // +// value_box and Integre values. // +// ------------------------------ // + +// oln::value_box<I> OpSymbol ntg::value<V> +# define oln_decl_arith_binop_vb_ntgval(OpSymbol, OpName) \ + template <typename I, typename V> \ + ntg_return_type(OpName, \ + typename oln::value_box<I>::value_type, \ + V) \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + const ntg::value<V>& rhs) \ + { \ + return lhs.value() OpSymbol rhs.exact (); \ + } + +// ntg::value<V> OpSymbol oln::value_box<I> +# define oln_decl_arith_binop_ntgval_vb(OpSymbol, OpName) \ + template <typename I, typename V> \ + ntg_return_type(OpName, \ + V, \ + typename oln::value_box<I>::value_type) \ + operator OpSymbol (const ntg::value<V>& lhs, \ + const oln::value_box<I>& rhs) \ + { \ + return lhs.exact() OpSymbol rhs.value(); \ + } + +# define oln_decl_arith_binop_with_ntgval(OpSymbol, OpName) \ + oln_decl_arith_binop_vb_ntgval(OpSymbol, OpName) \ + oln_decl_arith_binop_ntgval_vb(OpSymbol, OpName) + + +// -------------------------------------------- // +// value_box and C++ builtin arithmetic types. // +// -------------------------------------------- // + +// oln::value_box<I> OpSymbol Builtin +# define oln_decl_arith_binop_vb_builtin(OpSymbol, OpName, Builtin) \ + template <typename I> \ + ntg_return_type(OpName, \ + typename oln::value_box<I>::value_type, \ + Builtin) \ + operator OpSymbol (const oln::value_box<I>& lhs, \ + Builtin rhs) \ + { \ + return lhs.value() OpSymbol rhs; \ + } + +// Builtin OpSymbol oln::value_box<I> +# define oln_decl_arith_binop_builtin_vb(OpSymbol, OpName, Builtin) \ + template <typename I> \ + ntg_return_type(OpName, \ + Builtin, \ + typename oln::value_box<I>::value_type) \ + operator OpSymbol (Builtin lhs, \ + const oln::value_box<I>& rhs) \ + { \ + return lhs OpSymbol rhs.value(); \ + } + +# define oln_decl_arith_binop_with_builtin(OpSymbol, OpName, Builtin) \ + oln_decl_arith_binop_vb_builtin(OpSymbol, OpName, Builtin) \ + oln_decl_arith_binop_builtin_vb(OpSymbol, OpName, Builtin) + +# define oln_decl_arith_binop_with_builtin_int(OpSymbol, OpName) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, signed long) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, unsigned long) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, signed int) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, unsigned int) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, signed short) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, unsigned short) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, char) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, signed char) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, unsigned char) + +# define oln_decl_arith_binop_with_builtin_float(OpSymbol, OpName) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, float) \ + oln_decl_arith_binop_with_builtin(OpSymbol, OpName, double) + + +// ----------- // +// Shortcuts. // +// ----------- // + +# define oln_decl_arith_binop_all_but_builtin_float(OpSymbol, OpName) \ + oln_decl_arith_binop_vb_vb(OpSymbol, OpName) \ + oln_decl_arith_binop_with_ntgval(OpSymbol, OpName) \ + oln_decl_arith_binop_with_builtin_int(OpSymbol, OpName) + +# define oln_decl_arith_binop_all(OpSymbol, OpName) \ + oln_decl_arith_binop_all_but_builtin_float(OpSymbol, OpName) \ + oln_decl_arith_binop_with_builtin_float(OpSymbol, OpName) + + +// ------------------------------------ // +// ``Instantiation'' of the operators. // +// ------------------------------------ // + +namespace oln +{ + +oln_decl_arith_binop_all(+, plus) +oln_decl_arith_binop_all(-, minus) +oln_decl_arith_binop_all(*, times) +oln_decl_arith_binop_all(/, div) +oln_decl_arith_binop_all_but_builtin_float(%, mod) + +} // end of namespace oln + + +# undef oln_decl_arith_binop_vb_vb +# undef oln_decl_arith_binop_vb_ntgval +# undef oln_decl_arith_binop_ntgval_vb +# undef oln_decl_arith_binop_with_ntgval +# undef oln_decl_arith_binop_vb_builtin +# undef oln_decl_arith_binop_builtin_vb +# undef oln_decl_arith_binop_with_builtin +# undef oln_decl_arith_binop_with_builtin_int +# undef oln_decl_arith_binop_with_builtin_float +# undef oln_decl_arith_binop_all_but_builtin_float +# undef oln_decl_arith_binop_all + + + /// Operator <<. template <typename I> std::ostream& operator<<(std::ostream& ostr, const oln::value_box<I>& vb) Index: olena/oln/morpho/lower_completion.hh --- olena/oln/morpho/lower_completion.hh (révision 226) +++ olena/oln/morpho/lower_completion.hh (copie de travail) @@ -54,9 +54,10 @@ input.nbh_get ()); level::fill (processed, false); - typename ch_value_type<I, unsigned>::ret distance(input.size(), + typedef ntg_cumul_type(DestValue) cumul_type; + typename ch_value_type<I, cumul_type>::ret distance(input.size(), input.nbh_get()); - unsigned cur_dist = 1; + cumul_type cur_dist = 1; oln_type_of(I, piter) p(input.size()); for_all_p (p) @@ -114,9 +115,19 @@ input.nbh_get()); for_all_p (p) if (distance[p] == ntg_zero_val(DestValue)) - output[p] = cur_dist * input[p].value(); + output[p] = input[p] * cur_dist; else - output[p] = cur_dist * input[p].value() + distance[p].value() - 1; + /* Careful, the order of the operations matters here. If we had + written is as + + input[p] * cur_dist + distance[p] - 1 + + the compiler would have complained about the expression + « input[p] * cur_dist » not having an Integre property. This + is because the resolution of operator+ would have taken place + inside the ntg namespace, as its first operand would be + an Integre value. */ + output[p] = distance[p] - 1 + input[p] * cur_dist; return output; } Index: olena/oln/core/pw/arith.hh --- olena/oln/core/pw/arith.hh (révision 226) +++ olena/oln/core/pw/arith.hh (copie de travail) @@ -76,8 +76,6 @@ return tmp; } -} // end of namespace oln - oln_pw_decl_binary( plus, + ); oln_pw_decl_binary( minus, - ); @@ -104,4 +102,7 @@ oln_pw_decl_arith_lit(double); +} // end of namespace oln + + #endif // ! OLENA_CORE_PW_ARITH_HH
participants (1)
-
Roland Levillain