https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)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;