
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Some more definitions of traits and ops. * tests/arith_plus.cc: New. * tests/literal_zero.cc: Augment. * mln/trait/solve.hh (mln_trait_unary_, mln_trait_binary_): New macros. * mln/literal/ops.hh: Add FIXME. * mln/metal/vec.hh: Fix precondition. * mln/arith/times.hh: New. * mln/arith/plus.hh: Add traits. (operator+, operator+=): New. * mln/arith/includes.hh: New. * mln/arith/all.hh: Sort includes. * mln/value/ops.hh: New traits for Scalar OP Literal. (operator=): New overloads. * mln/value/scalar.hh (operator T): Remove; too dangerous. * mln/value/quat.hh: Update. * mln/value/equiv.hh (mln_value_equiv_): New macro. * mln/value/builtin/ops.hh: Add material for cmp ops. mln/arith/all.hh | 8 + mln/arith/includes.hh | 42 +++++++ mln/arith/plus.hh | 124 ++++++++++++++++----- mln/arith/times.hh | 271 +++++++++++++++++++++++++++++++++++++++++++++++ mln/literal/ops.hh | 2 mln/metal/vec.hh | 3 mln/trait/solve.hh | 2 mln/value/builtin/ops.hh | 75 ++++++++++++- mln/value/equiv.hh | 1 mln/value/ops.hh | 68 +++++++++++ mln/value/quat.hh | 4 mln/value/scalar.hh | 9 - tests/arith_plus.cc | 97 ++++++++++++++++ tests/literal_zero.cc | 4 14 files changed, 660 insertions(+), 50 deletions(-) Index: tests/arith_plus.cc --- tests/arith_plus.cc (revision 0) +++ tests/arith_plus.cc (revision 0) @@ -0,0 +1,97 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/arith_plus.cc + * + * \brief Tests on mln::image2d. + */ + +#include <mln/core/image2d.hh> +#include <mln/core/clone.hh> +#include <mln/value/int_u8.hh> + +#include <mln/arith/plus.hh> +#include <mln/arith/times.hh> +#include <mln/level/compare.hh> + +#include <mln/debug/iota.hh> +#include <mln/debug/println.hh> + + + +int main() +{ + using namespace mln; + + { + image2d<int> ref(3,3); + debug::iota(ref); + + image2d<int> ima_i = clone(ref); + ima_i += ima_i; + mln_assertion(ima_i = 2 * ref); + +// debug::println(ima_i); +// ima_i += 1; +// debug::println(ima_i); + +// debug::iota(ima_f); +// debug::println(ima_i + ima_f); + } + +} + + + +// Bench: + +// { +// unsigned size = 5000; +// image2d<unsigned char> ima_uc(size, size); +// image2d<unsigned> ima_u; +// ima_u = 2u + ima_uc; +// } +// { +// unsigned size = 5000; +// image2d<value::int_u8> ima_uc(size, size); +// image2d<unsigned> ima_u; +// ima_u = 2u + ima_uc; +// } + +// { +// unsigned size = 5000; +// image2d<unsigned char> ima_uc(size, size); +// image2d<unsigned> ima_u; +// ima_u = ima_uc + ima_uc; +// } +// { +// unsigned size = 5000; +// image2d<value::int_u8> ima_u8(size, size); +// image2d<unsigned> ima_u; +// ima_u = ima_u8 + ima_u8; +// } + Index: tests/literal_zero.cc --- tests/literal_zero.cc (revision 1388) +++ tests/literal_zero.cc (working copy) @@ -36,6 +36,7 @@ #include <mln/value/int_u8.hh> + int main() { using namespace mln; @@ -52,5 +53,6 @@ value::int_u8 u(literal::zero), uu; uu = literal::zero; - mln_assertion(u = 0); + + mln_assertion(u = 0 && 0 = u); } Index: mln/trait/solve.hh --- mln/trait/solve.hh (revision 1388) +++ mln/trait/solve.hh (working copy) @@ -49,8 +49,10 @@ # define mln_trait_unary(Name, T) typename mln::trait::solve_unary< Name, T >::ret +# define mln_trait_unary_(Name, T) mln::trait::solve_unary< Name, T >::ret # define mln_trait_binary(Name, T1, T2) typename mln::trait::solve_binary< Name, T1, T2 >::ret +# define mln_trait_binary_(Name, T1, T2) mln::trait::solve_binary< Name, T1, T2 >::ret Index: mln/literal/ops.hh --- mln/literal/ops.hh (revision 1388) +++ mln/literal/ops.hh (working copy) @@ -259,6 +259,8 @@ return mlc_equal(L1, L2)::value; } + // FIXME: Add less, etc. + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/metal/vec.hh --- mln/metal/vec.hh (revision 1388) +++ mln/metal/vec.hh (working copy) @@ -466,7 +466,6 @@ return tmp; } - template <unsigned n, typename T, typename S> vec<n, mln_trait_op_times(T, S)> operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s) @@ -491,7 +490,7 @@ vec<n, mln_trait_op_div(T, S)> operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s) { - mln_precondition(s != 0); + mln_precondition(value::equiv(s) != literal::zero); vec<n, mln_trait_op_div(T, S)> tmp; for (unsigned i = 0; i < n; ++i) tmp[i] = lhs[i] / s.to_equiv(); Index: mln/arith/times.hh --- mln/arith/times.hh (revision 0) +++ mln/arith/times.hh (revision 0) @@ -0,0 +1,271 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_ARITH_TIMES_HH +# define MLN_ARITH_TIMES_HH + +/*! \file mln/arith/times.hh + * + * \brief Point-wise multiplication between images. + * + * \todo Speedup; some versions are not optimal. + */ + +# include <mln/arith/includes.hh> + + +namespace mln +{ + + + namespace trait + { + + template <typename L, typename R> + struct set_binary_< op::times, Image, L, Image, R > + { + typedef mln_trait_op_times(mln_value(L), mln_value(R)) value; + typedef mln_ch_value(L, value) ret; + }; + + template <typename I, typename S> + struct set_binary_< op::times, Image, I, mln::value::Scalar, S > + { + typedef mln_trait_op_times(mln_value(I), S) value; + typedef mln_ch_value(I, value) ret; + }; + + } // end of namespace mln::trait + + + + template <typename L, typename R> + mln_trait_op_times(L,R) + operator*(const Image<L>& lhs, const Image<R>& rhs); + + template <typename L, typename R> + L& + operator*=(Image<L>& lhs, const Image<R>& rhs); + + + template <typename I, typename S> + mln_trait_op_times(I,S) + operator*(const Image<I>& ima, const value::Scalar<S>& s); + + template <typename I, typename S> + I& + operator*=(Image<I>& ima, const value::Scalar<S>& s); + + + + namespace arith + { + + /*! Point-wise addition of images \p lhs and \p rhs. + * + * \param[in] lhs First operand image. + * \param[in] rhs Second operand image. + * \param[out] output The result image. + * + * \pre \p output.domain = \p lhs.domain = \p rhs.domain + */ + template <typename L, typename R, typename O> + void times(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + + + /*! Point-wise addition of the value \p val to image \p input. + * + * \param[in] input The image. + * \param[in] val The value. + * \param[out] output The result image. + * + * \pre \p output.domain = \p input.domain + */ + template <typename I, typename V, typename O> + void times_cst(const Image<I>& input, const V& val, Image<O>& output); + + + /*! Point-wise addition of image \p rhs in image \p lhs. + * + * \param[in] lhs First operand image (subject to addition). + * \param[in,out] rhs Second operand image (to be added to \p lhs). + * + * This addition performs: \n + * for all p of rhs.domain \n + * lhs(p) *= rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void times_inplace(Image<L>& lhs, const Image<R>& rhs); + + + } // end of namespace mln::arith + + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L, typename R> + mln_trait_op_times(L,R) + operator*(const Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_trait_op_times(L,R) tmp; + initialize(tmp, lhs); + arith::times(lhs, rhs, tmp); + return tmp; + } + + template <typename L, typename R> + L& + operator*=(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + arith::times_inplace(lhs, rhs); + return exact(lhs); + } + + + template <typename I, typename S> + mln_trait_op_times(I,S) + operator*(const Image<I>& ima, const value::Scalar<S>& s) + { + mln_precondition(exact(ima).has_data()); + mln_trait_op_times(I,S) tmp; + initialize(tmp, ima); + arith::times_cst(ima, exact(s), tmp); + return tmp; + } + + template <typename I, typename S> + I& + operator*=(Image<I>& ima, const value::Scalar<S>& s) + { + mln_precondition(exact(ima).has_data()); + arith::times_cst(ima, exact(s), ima); + return exact(ima); + } + + + + namespace arith + { + + namespace impl + { + + template <typename L, typename R, typename O> + void times_(trait::image::speed::any, const L& lhs, + trait::image::speed::any, const R& rhs, + trait::image::speed::any, O& output) + { + mln_piter(L) p(lhs.domain()); + for_all(p) + output(p) = lhs(p) * rhs(p); + } + + template <typename L, typename R, typename O> + void times_(trait::image::speed::fastest, const L& lhs, + trait::image::speed::fastest, const R& rhs, + trait::image::speed::fastest, O& output) + { + mln_pixter(const L) lp(lhs); + mln_pixter(const R) rp(rhs); + mln_pixter(O) op(output); + for_all_3(lp, rp, op) + op.val() = lp.val() * rp.val(); + } + + template <typename L, typename R> + void times_inplace_(trait::image::speed::any, L& lhs, + trait::image::speed::any, const R& rhs) + { + mln_piter(R) p(rhs.domain()); + for_all(p) + lhs(p) *= rhs(p); + } + + template <typename L, typename R> + void times_inplace_(trait::image::speed::fastest, L& lhs, + trait::image::speed::fastest, const R& rhs) + { + mln_pixter(L) lp(lhs); + mln_pixter(const R) rp(rhs); + for_all_2(rp, lp) + lp.val() *= rp.val(); + } + + } // end of namespace mln::arith::impl + + + // Facades. + + template <typename L, typename R, typename O> + void times(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::times_(mln_trait_image_speed(L)(), exact(lhs), + mln_trait_image_speed(R)(), exact(rhs), + mln_trait_image_speed(O)(), exact(output)); + } + + template <typename I, typename V, typename O> + void times_cst(const Image<I>& input, const V& val, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + times(input, pw::cst(val) | exact(input).domain(), output); + // Calls the previous version. + } + + template <typename L, typename R> + void times_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::times_inplace_(mln_trait_image_speed(L)(), exact(lhs), + mln_trait_image_speed(R)(), exact(rhs)); + } + + template <typename I, typename V> + void times_cst_inplace(Image<I>& input, const V& val) + { + mln_precondition(exact(input).has_data()); + times_inplace(input, pw::cst(val) | exact(input).domain()); + // Calls the previous version. + } + + } // end of namespace mln::arith + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_ARITH_TIMES_HH Index: mln/arith/plus.hh --- mln/arith/plus.hh (revision 1388) +++ mln/arith/plus.hh (working copy) @@ -32,31 +32,54 @@ * * \brief Point-wise addition between images. * - * \todo Speedup versions with cst. + * \todo Speedup; some versions are not optimal. */ -# include <mln/core/concept/image.hh> - -# include <mln/pw/cst.hh> -# include <mln/pw/image.hh> -# include <mln/trait/op/plus.hh> +# include <mln/arith/includes.hh> namespace mln { -// namespace trait -// { + namespace trait + { + + template <typename L, typename R> + struct set_binary_< op::plus, Image, L, Image, R > + { + typedef mln_trait_op_plus(mln_value(L), mln_value(R)) value; + typedef mln_ch_value(L, value) ret; + }; + + template <typename I, typename S> + struct set_binary_< op::plus, Image, I, mln::value::Scalar, S > + { + typedef mln_trait_op_plus(mln_value(I), S) value; + typedef mln_ch_value(I, value) ret; + }; + + } // end of namespace mln::trait + + + + template <typename L, typename R> + mln_trait_op_plus(L,R) + operator+(const Image<L>& lhs, const Image<R>& rhs); + + template <typename L, typename R> + L& + operator+=(Image<L>& lhs, const Image<R>& rhs); + + + template <typename I, typename S> + mln_trait_op_plus(I,S) + operator+(const Image<I>& ima, const value::Scalar<S>& s); -// template <typename L, typename R> -// struct op_plus< Image,L, Image,R > -// { -// typedef mln_trait_op_plus(mln_value(L), mln_value(R)) value; -// typedef mln_ch_value(L, value) ret; -// }; + template <typename I, typename S> + I& + operator+=(Image<I>& ima, const value::Scalar<S>& s); -// } // end of namespace mln::trait namespace arith @@ -101,8 +124,60 @@ void plus_inplace(Image<L>& lhs, const Image<R>& rhs); + } // end of namespace mln::arith + + + + # ifndef MLN_INCLUDE_ONLY + + template <typename L, typename R> + mln_trait_op_plus(L,R) + operator+(const Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_trait_op_plus(L,R) tmp; + initialize(tmp, lhs); + arith::plus(lhs, rhs, tmp); + return tmp; + } + + template <typename L, typename R> + L& + operator+=(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + arith::plus_inplace(lhs, rhs); + return exact(lhs); + } + + + template <typename I, typename S> + mln_trait_op_plus(I,S) + operator+(const Image<I>& ima, const value::Scalar<S>& s) + { + mln_precondition(exact(ima).has_data()); + mln_trait_op_plus(I,S) tmp; + initialize(tmp, ima); + arith::plus_cst(ima, exact(s), tmp); + return tmp; + } + + template <typename I, typename S> + I& + operator+=(Image<I>& ima, const value::Scalar<S>& s) + { + mln_precondition(exact(ima).has_data()); + arith::plus_cst(ima, exact(s), ima); + return exact(ima); + } + + + + namespace arith + { + namespace impl { @@ -152,7 +227,6 @@ // Facades. - template <typename L, typename R, typename O> void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) { @@ -163,17 +237,6 @@ mln_trait_image_speed(O)(), exact(output)); } - -// template <typename L, typename R> -// mln_trait_op_plus(L, R) -// plus(const Image<L>& lhs, const Image<R>& rhs) -// { -// mln_precondition(exact(rhs).domain() = exact(lhs).domain()); -// mln_precondition(exact(output).domain() = exact(lhs).domain()); -// impl::plus_(exact(lhs), exact(rhs), exact(output)); -// } - - template <typename I, typename V, typename O> void plus_cst(const Image<I>& input, const V& val, Image<O>& output) { @@ -194,15 +257,14 @@ void plus_cst_inplace(Image<I>& input, const V& val) { mln_precondition(exact(input).has_data()); - plus_inplace(mln_trait_image_speed(I)(), exact(input), - trait::image::speed::any(), pw::cst(val) | exact(input).domain()); + plus_inplace(input, pw::cst(val) | exact(input).domain()); // Calls the previous version. } -# endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::arith +# endif // ! MLN_INCLUDE_ONLY + } // end of namespace mln Index: mln/arith/includes.hh --- mln/arith/includes.hh (revision 0) +++ mln/arith/includes.hh (revision 0) @@ -0,0 +1,42 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_ARITH_INCLUDES_HH +# define MLN_ARITH_INCLUDES_HH + +/*! \file mln/arith/includes.hh + * + * \brief File that includes what is required by arith files. + */ + +# include <mln/core/concept/image.hh> +# include <mln/value/ops.hh> +# include <mln/pw/cst.hh> +# include <mln/pw/image.hh> + + +#endif // ! MLN_ARITH_INCLUDES_HH Index: mln/arith/all.hh --- mln/arith/all.hh (revision 1388) +++ mln/arith/all.hh (working copy) @@ -46,9 +46,13 @@ } -# include <mln/arith/min.hh> -# include <mln/arith/minus.hh> + # include <mln/arith/plus.hh> +# include <mln/arith/minus.hh> +# include <mln/arith/times.hh> + +# include <mln/arith/min.hh> # include <mln/arith/revert.hh> + #endif // ! MLN_ARITH_ALL_HH Index: mln/value/ops.hh --- mln/value/ops.hh (revision 1388) +++ mln/value/ops.hh (working copy) @@ -89,6 +89,27 @@ }; + template < template <class, class> class Name, + typename S, typename L > + struct set_binary_< Name, + mln::value::Scalar, S, + mln::Literal, L > + { + typedef mln_value_equiv(S) S_; + typedef mln_trait_binary(Name, S_, S_) ret; + }; + + template < template <class, class> class Name, + typename L, typename S > + struct set_binary_< Name, + mln::Literal, L, + mln::value::Scalar, S > + { + typedef mln_value_equiv(S) S_; + typedef mln_trait_binary(Name, S_, S_) ret; + }; + + // Some binary traits for "scalar(s) OP obj" when OP commutes => "obj OP scalar(s)". template < typename S, typename O > @@ -282,6 +303,53 @@ // ... + + template <typename Sl, typename Sr> + mln_trait_op_eq(Sl, Sr) + operator = (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs) + { + return value::equiv(lhs) = value::equiv(rhs); + } + + + // FIXME: Uncomment when less and leq are handled. + +// template <typename Sl, typename Sr> +// mln_trait_op_less(Sl, Sr) +// operator < (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs) +// { +// return value::equiv(lhs) < value::equiv(rhs); +// } + +// template <typename Sl, typename Sr> +// mln_trait_op_leq(Sl, Sr) +// operator <= (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs) +// { +// return value::equiv(lhs) <= value::equiv(rhs); +// } + + // ... + + + + + template <typename O, typename L> + mln_trait_op_eq(O, O) + operator=(const value::scalar_<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) = mln_value_equiv(O)(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_eq(O, O) + operator=(const Literal<L>& lhs, const value::scalar_<O>& rhs) + { + // mlc_converts_to(L, O)::check(); + return mln_value_equiv(O)(exact(lhs)) = exact(rhs); + } + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/value/scalar.hh --- mln/value/scalar.hh (revision 1388) +++ mln/value/scalar.hh (working copy) @@ -62,9 +62,6 @@ /// Ctor. explicit scalar_(const T& val); - /// Conversion. FIXME: Is-it useful? - operator T() const; - /// Access to the scalar value. T to_equiv() const; @@ -120,12 +117,6 @@ } template <typename T> - scalar_<T>::operator T() const - { - return val_; - } - - template <typename T> T scalar_<T>::to_equiv() const { Index: mln/value/quat.hh --- mln/value/quat.hh (revision 1388) +++ mln/value/quat.hh (working copy) @@ -452,7 +452,7 @@ quat operator*(const quat& lhs, const value::scalar_<S>& rhs) { mlc_converts_to(S, float)::check(); - quat tmp(lhs.to_vec() * float(rhs)); + quat tmp(lhs.to_vec() * rhs.to_equiv()); return tmp; } @@ -460,7 +460,7 @@ quat operator/(const quat& lhs, const value::scalar_<S>& rhs_) { mlc_converts_to(S, float)::check(); - float rhs = float(rhs_); + float rhs = rhs_.to_equiv(); mln_precondition(rhs != 0.f); quat tmp(lhs.to_vec() / rhs); return tmp; Index: mln/value/equiv.hh --- mln/value/equiv.hh (revision 1388) +++ mln/value/equiv.hh (working copy) @@ -37,6 +37,7 @@ # define mln_value_equiv(V) typename mln::value::internal::equiv_<V>::ret +# define mln_value_equiv_(V) mln::value::internal::equiv_<V>::ret Index: mln/value/builtin/ops.hh --- mln/value/builtin/ops.hh (revision 1388) +++ mln/value/builtin/ops.hh (working copy) @@ -112,6 +112,42 @@ +// Comparison. + +# define mln_internal_decl_op_cmp_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Object<O>& lhs, const Builtin & rhs); \ + \ + template <typename O> \ + mln_trait_op_##Name (value::scalar_< Builtin >, O) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + +# define mln_internal_def_op_cmp_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Object<O>& lhs, const Builtin & rhs) \ + { \ + return exact(lhs) Symb value::scalar(rhs); \ + } \ + \ + template <typename O> \ + mln_trait_op_##Name (value::scalar_< Builtin >, O) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs) \ + { \ + return value::scalar(lhs) Symb exact(rhs); \ + } \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + + + # define mln_internal_op_obj_builtins_(De, Symb, Name) \ \ @@ -206,7 +242,7 @@ template <typename O> \ mln_trait_op_##Name (value::scalar_< Builtin >, O) \ operator Symb (const Builtin & lhs, const Object<O>& rhs) \ - { std::cout << "hop" << std::endl; \ + { \ return value::scalar(lhs) / exact(rhs); \ } \ \ @@ -229,6 +265,20 @@ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n +# define mln_internal_op_builtins_cmp_(De, Symb, Name) \ + \ + mln_internal_##De##_op_cmp_(Symb, Name, signed char); \ + mln_internal_##De##_op_cmp_(Symb, Name, unsigned char); \ + mln_internal_##De##_op_cmp_(Symb, Name, signed short); \ + mln_internal_##De##_op_cmp_(Symb, Name, unsigned short); \ + mln_internal_##De##_op_cmp_(Symb, Name, signed int); \ + mln_internal_##De##_op_cmp_(Symb, Name, unsigned int); \ + mln_internal_##De##_op_cmp_(Symb, Name, signed long); \ + mln_internal_##De##_op_cmp_(Symb, Name, unsigned long); \ + mln_internal_##De##_op_cmp_(Symb, Name, float); \ + mln_internal_##De##_op_cmp_(Symb, Name, double); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n // FIXME: What about pointers, arrays, bool, etc. @@ -268,7 +318,7 @@ namespace trait { - // A couple of builtins => promotion. + // A couple of builtins => promotion... mln_internal_set_builtin_trait_is_promotion_(op::plus); mln_internal_set_builtin_trait_is_promotion_(op::minus); @@ -276,7 +326,14 @@ mln_internal_set_builtin_trait_is_promotion_(op::div); mln_internal_set_builtin_trait_is_promotion_(op::mod); - // FIXME: other (such as plus_eq)... + // ...or for comparisons => bool. + + mln_internal_set_builtin_trait_is_bool_(op::eq); + mln_internal_set_builtin_trait_is_bool_(op::neq); + // FIXME: ... + + // FIXME: What about +=, etc. + template< template <class> class Name, @@ -386,6 +443,12 @@ mln_internal_builtins_dvmd_obj_(decl, %, mod); + // Ops "bi CMP obj" and "bi CMP obj" + mln_internal_op_builtins_cmp_(decl, =, eq); + mln_internal_op_builtins_cmp_(decl, !=, neq); + // FIXME: ... + + # ifndef MLN_INCLUDE_ONLY mln_internal_op_obj_builtins_(def, +, plus); @@ -405,6 +468,12 @@ mln_internal_builtins_dvmd_obj_(def, /, div); mln_internal_builtins_dvmd_obj_(def, %, mod); + // Ops "bi CMP obj" and "bi CMP obj" + mln_internal_op_builtins_cmp_(def, =, eq); + mln_internal_op_builtins_cmp_(def, !=, neq); + + // FIXME: Add less, etc. + # endif // ! MLN_INCLUDE_ONLY