
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Have mln::rgb's operators work better. * mln/value/rgb.hh (rgb<n>::operator metal::vec<3, int>): New conversion operator. (operator+(const rgb<n>&, const rgb<n>&)) (operator-(const rgb<n>&, const rgb<n>&)) (operator*(const rgb<n>&, const mln::value::scalar_<S>&)) (operator/(const rgb<n>&, const mln::value::scalar_<S>&)): Use mln::rgb's interop type instead of mln::rgb directly. (operator+(const typename rgb<n>::interop&, const rgb<n>&)) (operator+(const rgb<n>&, const typename rgb<n>::interop&)) (operator-(const typename rgb<n>::interop&, const rgb<n>&)) (operator-(const rgb<n>&, const typename rgb<n>::interop&)) (operator*(const mln::value::scalar_<S>&, const rgb<n>&)): New operators. Remove dead code. * tests/value/rgb8.cc: Exercise more operators. mln/value/rgb.hh | 138 ++++++++++++++++++++++++++++++++++++++-------------- tests/value/rgb8.cc | 22 ++++++-- 2 files changed, 120 insertions(+), 40 deletions(-) Index: mln/value/rgb.hh --- mln/value/rgb.hh (revision 1730) +++ mln/value/rgb.hh (working copy) @@ -184,11 +184,15 @@ rgb<n>(const metal::vec<3, unsigned>& rhs); rgb<n>(const metal::vec<3, int_u<n> >& rhs); + // Conversion to the interoperation type. + operator metal::vec<3, int>() const { return this->v_; } + // Conversion to the sum type. operator metal::vec<3, float>() const { return this->v_; } /// \{ Constructors with literals. rgb<n>(const literal::white_t&); rgb<n>(const literal::black_t&); + rgb<n>(const literal::blue_t&); rgb<n>(const literal::red_t&); rgb<n>(const literal::green_t&); @@ -217,37 +221,70 @@ std::istream& operator>>(std::istream& istr, rgb<n>& c); - // FIXME: Cannot work for i negative; add traits! + /* FIXME: We should not need to define these operators, thanks to + Milena's global operator resolution mechanism based on + mln::Object. See what prevent us to use this mechanism. */ + + /* FIXME: Cannot work for i negative; add traits! (2008-02-16, + Roland: What does this comment mean?) */ /// Addition. + /// { template <unsigned n> - rgb<n> + typename rgb<n>::interop operator+(const rgb<n>& lhs, const rgb<n>& rhs); - /// Substraction. template <unsigned n> - rgb<n> + typename rgb<n>::interop + operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs); + + template <unsigned n> + typename rgb<n>::interop + operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs); + /// \} + + /// Subtraction. + /// \{ + template <unsigned n> + typename rgb<n>::interop operator-(const rgb<n>& lhs, const rgb<n>& rhs); - /// Multiplication. + template <unsigned n> + typename rgb<n>::interop + operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs); + + template <unsigned n> + typename rgb<n>::interop + operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs); + /// \} + + /// Product. + /// \{ template <unsigned n, typename S> inline - rgb<n> + typename rgb<n>::interop operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s); template <unsigned n, typename S> inline - rgb<n> - operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s); + typename rgb<n>::interop + operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs); + /// \} /// Division. + /// \{ template <unsigned n, typename S> inline - rgb<n> + typename rgb<n>::interop operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s); + /// \} # ifndef MLN_INCLUDE_ONLY + /*---------------. + | Construction. | + `---------------*/ + template <unsigned n> inline rgb<n>::rgb() @@ -349,59 +386,90 @@ template <unsigned n> const rgb<n> rgb<n>::zero(0,0,0); + /*------------. + | Operators. | + `------------*/ + + template <unsigned n> + inline + typename rgb<n>::interop + operator+(const rgb<n>& lhs, const rgb<n>& rhs) + { + typename rgb<n>::interop tmp(lhs.to_interop() + rhs.to_interop()); + return tmp; + } + template <unsigned n> inline - rgb<n> + typename rgb<n>::interop + operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs) + { + typename rgb<n>::interop tmp(lhs.to_interop() + rhs); + return tmp; + } + + template <unsigned n> + inline + typename rgb<n>::interop + operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs) + { + typename rgb<n>::interop tmp(lhs + rhs.to_interop()); + return tmp; + } + + template <unsigned n> + inline + typename rgb<n>::interop operator-(const rgb<n>& lhs, const rgb<n>& rhs) { - rgb<n> tmp(lhs.to_equiv() - rhs.to_equiv()); + typename rgb<n>::interop tmp(lhs.to_interop() - rhs.to_interop()); return tmp; } template <unsigned n> inline - rgb<n> - operator+(const rgb<n>& lhs, const rgb<n>& rhs) + typename rgb<n>::interop + operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs) { - rgb<n> tmp(lhs.to_equiv() + rhs.to_equiv()); + typename rgb<n>::interop tmp(lhs.to_interop() - rhs); return tmp; } -// template <unsigned n> -// inline -// rgb<n> -// operator*(const rgb<n>& lhs, int i) -// { -// rgb<n> tmp(lhs.to_equiv() * i); -// return tmp; -// } + template <unsigned n> + inline + typename rgb<n>::interop + operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs) + { + typename rgb<n>::interop tmp(lhs - rhs.to_interop()); + return tmp; + } template <unsigned n, typename S> inline - rgb<n> + typename rgb<n>::interop operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s) { - rgb<n> tmp(lhs.to_equiv() * s.to_equiv()); + typename rgb<n>::interop tmp(lhs.to_interop() * s.to_equiv()); return tmp; } template <unsigned n, typename S> inline - rgb<n> - operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s) + typename rgb<n>::interop + operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs) { - rgb<n> tmp(lhs.to_equiv() / s.to_equiv()); + typename rgb<n>::interop tmp(s.to_equiv() * lhs.to_interop()); return tmp; } -// template <unsigned n> -// inline -// rgb<n> -// operator/(const rgb<n>& lhs, int i) -// { -// rgb<n> tmp(lhs.to_equiv() / i); -// return tmp; -// } + template <unsigned n, typename S> + inline + typename rgb<n>::interop + operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s) + { + typename rgb<n>::interop tmp(lhs.to_interop() / s.to_equiv()); + return tmp; + } template <unsigned n> inline Index: tests/value/rgb8.cc --- tests/value/rgb8.cc (revision 1730) +++ tests/value/rgb8.cc (working copy) @@ -50,16 +50,28 @@ v.blue() = 2; rgb8 c(0, 1, 2); - // FIXME: Does not compile because we lack ops! - // mln_sum_(rgb8) sum; - // sum + c; - // c = c + c; + // Exercise some operators. + rgb8 c1(200,100,0); + rgb8 c2(100,200,50); + c1 + c2; + c1 - c2; + /* FIXME: Doesn't work. Calls an operator* triggering an overflow + error. We have to check where `interop' types should be used + instead of `equiv' types to avoid such a behavior. */ +// 3 * c1; +// c1 * 3; + c1 / 5; + + mln_sum_(rgb8) sum = literal::zero; + sum = sum + c; + c = c + c; std::cout << c << std::endl; std::cout << v << std::endl; + std::cout << sum << std::endl; mln_assertion(c == c); - mln_assertion(c == v); + mln_assertion(c == 2 * v); v.green() = 255; std::cout << v << std::endl;