1304: Update some classes with literals and precise int_u equiv.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update some classes with literals and precise int_u equiv. * mln/literal/ops.hh: New. * mln/literal/one.hh: New. * mln/literal/all.hh: New. * mln/value/int_u.hh: Update so that the equivalent type really is 'unsigned'. * mln/debug/all.hh: Clean-up. * mln/core/point.hh, * mln/core/window.hh, * mln/core/neighb.hh, * mln/core/dpoint.hh: New ctor overloads for coordinates. * mln/core/ops.hh (operator+, operator*): New overloads for unsigned. (operator++, operator--): New FIXMEs. * mln/core/concept/function.hh: New categories for sub-concepts of Function. * mln/core/concept/window.hh, * mln/metal/vec.hh, * mln/value/cast.hh, * mln/value/internal/value_like.hh, * mln/make/w_window.hh, * mln/test/positive.hh, * mln/convert/to_image.hh, * mln/convert/to_std_set.hh, * mln/convert/to_window.hh, * mln/convert/to_dpoint.hh, * mln/convert/to_w_window.hh, * mln/geom/bbox.hh, * mln/geom/shift.hh, * mln/fun/v2v/saturate.hh, * mln/win/octagon2d.hh, * mln/morpho/hit_or_miss.hh, * mln/norm/infty.hh, * mln/norm/l2.hh, * tests/window1d.cc, * tests/morpho_dilation_max_h.cc, * tests/morpho_erosion_min_h.cc, * tests/dpoint2d.cc, * tests/literal_zero.cc, * tests/labeling_foreground.cc, * tests/point1d.cc, * tests/window2d.cc, * tests/labeling_estimate.cc, * tests/dpoint1d.cc, * tests/dpoint3d.cc, * tests/value_int_u8.cc, * tests/point2d.cc: Update. * TODO: Clear. TODO | 9 +-- mln/convert/to_dpoint.hh | 2 mln/convert/to_image.hh | 4 - mln/convert/to_std_set.hh | 4 - mln/convert/to_w_window.hh | 2 mln/convert/to_window.hh | 12 ++--- mln/core/concept/function.hh | 41 +++++++++++++++++ mln/core/concept/window.hh | 4 - mln/core/dpoint.hh | 65 +++++++++++++++++++++++----- mln/core/neighb.hh | 44 ++++++++++++++++++- mln/core/ops.hh | 20 ++++++++ mln/core/point.hh | 37 ++++++++++++++-- mln/core/window.hh | 42 ++++++++++++++++++ mln/debug/all.hh | 6 +- mln/fun/v2v/saturate.hh | 12 +++-- mln/geom/bbox.hh | 2 mln/geom/shift.hh | 2 mln/literal/all.hh | 58 +++++++++++++++++++++++++ mln/literal/one.hh | 76 +++++++++++++++++++++++++++++++++ mln/literal/ops.hh | 89 +++++++++++++++++++++++++++++++++++++++ mln/make/w_window.hh | 4 - mln/metal/vec.hh | 17 +++++-- mln/morpho/hit_or_miss.hh | 3 + mln/norm/infty.hh | 27 +++++++++-- mln/norm/l2.hh | 3 + mln/test/positive.hh | 7 ++- mln/value/cast.hh | 2 mln/value/int_u.hh | 70 ++++++++++++++++++++++++++++-- mln/value/internal/value_like.hh | 2 mln/win/octagon2d.hh | 33 +++++++------- tests/dpoint1d.cc | 4 - tests/dpoint2d.cc | 4 - tests/dpoint3d.cc | 4 - tests/labeling_estimate.cc | 3 - tests/labeling_foreground.cc | 2 tests/literal_zero.cc | 11 ++++ tests/morpho_dilation_max_h.cc | 2 tests/morpho_erosion_min_h.cc | 2 tests/point1d.cc | 3 + tests/point2d.cc | 7 +++ tests/value_int_u8.cc | 7 ++- tests/window1d.cc | 6 +- tests/window2d.cc | 4 - 43 files changed, 661 insertions(+), 97 deletions(-) Index: tests/window1d.cc --- tests/window1d.cc (revision 1303) +++ tests/window1d.cc (working copy) @@ -46,8 +46,10 @@ mln_assertion(w.is_centered() = false); mln_assertion(w.is_symmetric() = true); - w.insert(make::dpoint1d(-1)); - w.insert(make::dpoint1d( 1)); + // w.insert(-1,0); // Do not compile as expected. + + w.insert(-1); + w.insert( 1); image1d<bool> ima = convert::to_image(w); debug::println(ima); Index: tests/morpho_dilation_max_h.cc --- tests/morpho_dilation_max_h.cc (revision 1303) +++ tests/morpho_dilation_max_h.cc (working copy) @@ -55,7 +55,7 @@ image2d<int_u8> lena = io::pgm::load("../img/lena.pgm"); { - vec_p<point2d> vec = convert::to_vec_p(rec, point2d::zero); + vec_p<point2d> vec = convert::to_vec_p(rec, point2d::origin); window2d win = convert::to_window(vec); image2d<int_u8> out(lena.domain()); Index: tests/morpho_erosion_min_h.cc --- tests/morpho_erosion_min_h.cc (revision 1303) +++ tests/morpho_erosion_min_h.cc (working copy) @@ -55,7 +55,7 @@ image2d<int_u8> lena = io::pgm::load("../img/lena.pgm"); { - vec_p<point2d> vec = convert::to_vec_p(rec, point2d::zero); + vec_p<point2d> vec = convert::to_vec_p(rec, point2d::origin); window2d win = convert::to_window(vec); image2d<int_u8> out(lena.domain()); Index: tests/dpoint2d.cc --- tests/dpoint2d.cc (revision 1303) +++ tests/dpoint2d.cc (working copy) @@ -48,8 +48,8 @@ mln_assertion(dp = q - p); mln_assertion(q = p + dp); - const int (&vec)[2] = dp.to_vec(); - mln_assertion(vec[0] = 3); + metal::vec<2, float> v = dp; + mln_assertion(v[0] / 2 = 1.5); p += dp; mln_assertion(q = p); Index: tests/literal_zero.cc --- tests/literal_zero.cc (revision 1303) +++ tests/literal_zero.cc (working copy) @@ -31,6 +31,9 @@ */ #include <mln/literal/zero.hh> +#include <mln/literal/one.hh> +#include <mln/literal/ops.hh> +#include <mln/value/int_u8.hh> int main() @@ -39,7 +42,15 @@ unsigned char c; c = literal::zero; + mln_assertion(c = 0); double d; d = literal::zero; + mln_assertion(d = 0); + + mln_assertion(literal::zero != literal::one); + + value::int_u8 u(literal::zero), uu; + uu = literal::zero; + mln_assertion(u = 0); } Index: tests/labeling_foreground.cc --- tests/labeling_foreground.cc (revision 1303) +++ tests/labeling_foreground.cc (working copy) @@ -50,7 +50,7 @@ out(lena.domain()); unsigned n; - labeling::foreground((pw::value(lena) > pw::cst(127)) | lena.domain(), + labeling::foreground((pw::value(lena) > pw::cst(127u)) | lena.domain(), c4(), out, n); io::pgm::save(out, "out.pgm"); mln_assertion(n = 14); Index: tests/point1d.cc --- tests/point1d.cc (revision 1303) +++ tests/point1d.cc (working copy) @@ -43,6 +43,9 @@ // assignment p[0] = 4; + metal::vec<1,int> v = p; + std::cout << v << std::endl; + p.ind() += 1; mln_assertion(p.ind() = 5 && p[0] = 5); Index: tests/window2d.cc --- tests/window2d.cc (revision 1303) +++ tests/window2d.cc (working copy) @@ -46,8 +46,8 @@ mln_assertion(w.is_centered() = false); mln_assertion(w.is_symmetric() = true); - w.insert(make::dpoint2d(-1,-1)); - w.insert(make::dpoint2d( 1, 1)); + w .insert(-1,-1) + .insert( 1, 1); image2d<bool> ima = convert::to_image(w); debug::println(ima); Index: tests/labeling_estimate.cc --- tests/labeling_estimate.cc (revision 1303) +++ tests/labeling_estimate.cc (working copy) @@ -49,8 +49,9 @@ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm"), out(lena.domain()); + // FIXME: Below, 127u (instead of 127) is mandatory to avoid a warning... unsigned n; - labeling::foreground((pw::value(lena) > pw::cst(127)) | lena.domain(), + labeling::foreground((pw::value(lena) > pw::cst(127u)) | lena.domain(), c4(), out, n); mln_assertion(n = 14); Index: tests/dpoint1d.cc --- tests/dpoint1d.cc (revision 1303) +++ tests/dpoint1d.cc (working copy) @@ -48,6 +48,6 @@ mln_assertion(dp = q - p); mln_assertion(q = p + dp); - const int (&vec)[1] = dp.to_vec(); - mln_assertion(vec[0] = 3); + metal::vec<1, float> v = dp; + mln_assertion(v[0] = 3); } Index: tests/dpoint3d.cc --- tests/dpoint3d.cc (revision 1303) +++ tests/dpoint3d.cc (working copy) @@ -48,6 +48,6 @@ mln_assertion(dp = q - p); mln_assertion(q = p + dp); - const int (&vec)[3] = dp.to_vec(); - mln_assertion(vec[1] = 6); + metal::vec<3, float> v = dp; + mln_assertion(v[1] = 6); } Index: tests/value_int_u8.cc --- tests/value_int_u8.cc (revision 1303) +++ tests/value_int_u8.cc (working copy) @@ -154,7 +154,12 @@ --i; mln_assertion(i = 234); - mln_assertion(-i = -234); + std::cout << (-i) << " FIXME Matthieu: add .f to literals " << i << std::endl; + mln_assertion(-i = -234); // FIXME: old version + mln_assertion(-i = -234.f); // FIXME: new better version + + mln_assertion(i * -2 != 0.f); + std::cout << (i) << " " << (i * -2) << " " << (-2 * int(i)) << std::endl; } // Multiplication Index: tests/point2d.cc --- tests/point2d.cc (revision 1303) +++ tests/point2d.cc (working copy) @@ -32,6 +32,7 @@ #include <iostream> #include <mln/core/point2d.hh> +#include <mln/literal/all.hh> @@ -62,6 +63,12 @@ point2d q_(5, 1); mln_assertion(q_ = q); } + { + point2d O(0,0); + point2d O_ = literal::zero; + mln_assertion(O_ = O); + mln_assertion(O = literal::zero); + } q.set_all(0); for (unsigned i = 0; i < p.dim; ++i) Index: TODO --- TODO (revision 1303) +++ TODO (working copy) @@ -55,14 +55,11 @@ *** type -value::proxy to dispatch read/write + the corresponding image type -a mean_value object { sum; count } and operator+ +... *** other -in Fast_Image: memcpy and memset-like methods (?) -.offset() into GenPixel -built-in op objects -> reverse lhs/rhs +... ** rename @@ -70,7 +67,7 @@ ** clean-up -select_function in fun::internal::selector_p2? etc. +... ** processing routines Index: mln/debug/all.hh --- mln/debug/all.hh (revision 1303) +++ mln/debug/all.hh (working copy) @@ -37,14 +37,16 @@ namespace mln { - /*! Namespace of routines that help to debug. - */ + /// Namespace of routines that help to debug. namespace debug {} } +# include <mln/debug/format.hh> +# include <mln/debug/iota.hh> # include <mln/debug/println.hh> +# include <mln/debug/println_with_border.hh> #endif // ! MLN_DEBUG_ALL_HH Index: mln/core/point.hh --- mln/core/point.hh (revision 1303) +++ mln/core/point.hh (working copy) @@ -39,14 +39,20 @@ # include <mln/metal/bool.hh> # include <mln/metal/vec.hh> +# include <mln/metal/converts_to.hh> # include <mln/core/h_vec.hh> namespace mln { - // fwd decl + /// \{ Fwd decls. template <typename M, typename C> struct dpoint_; + namespace literal { + struct zero_t; + struct one_t; + } + /// \} namespace internal @@ -102,13 +108,18 @@ /// Constructor without argument. point_(); - /// \{ Constructors with different numbers of argument w.r.t. the - /// dimension. + /// \{ Constructors with different numbers of arguments + /// (coordinates) w.r.t. the dimension. point_(C ind); point_(C row, C col); point_(C sli, C row, C col); /// \} + /// \{ Constructors with literals. + point_(const literal::zero_t&); + point_(const literal::one_t&); // Works only in 1D. + /// \} + /// Constructor; coordinates are set by function \p f. template <typename F> point_(const Function_i2v<F>& f); @@ -117,7 +128,7 @@ void set_all(C c); /// Origin point (all coordinates are 0). - static const point_<M,C> zero; + static const point_<M,C> origin; /// Shifting by \p dp. point_<M,C>& operator+=(const dpoint& dp); @@ -156,6 +167,8 @@ return this->coord_[i]; } + // Constructors. + template <typename M, typename C> point_<M,C>::point_() { @@ -189,19 +202,33 @@ template <typename F> point_<M,C>::point_(const Function_i2v<F>& f_) { + mlc_converts_to(mln_result(F), C)::check(); const F& f = exact(f_); for (unsigned i = 0; i < dim; ++i) coord_[i] = f(i); } template <typename M, typename C> + point_<M,C>::point_(const literal::zero_t&) + { + coord_.set_all(0); + } + + template <typename M, typename C> + point_<M,C>::point_(const literal::one_t&) + { + metal::bool_<(dim = 1)>::check(); + coord_[0] = 1; + } + + template <typename M, typename C> void point_<M,C>::set_all(C c) { coord_.set_all(c); } template <typename M, typename C> - const point_<M,C> point_<M,C>::zero = all(0); + const point_<M,C> point_<M,C>::origin = all(0); template <typename M, typename C> point_<M,C>& Index: mln/core/window.hh --- mln/core/window.hh (revision 1303) +++ mln/core/window.hh (working copy) @@ -31,6 +31,9 @@ /*! \file mln/core/window.hh * * \brief Definition of the generic window class mln::window. + * + * \todo Make naming coherent: we have window (without '_') but + * point_, neighb_, etc. */ # include <mln/core/concept/window.hh> @@ -89,6 +92,18 @@ /// Insert a delta-point \p dp. window<D>& insert(const D& dp); + /// \{ Insertion of a delta-point with different numbers of + /// arguments (coordinates) w.r.t. the dimension. + window<D>& insert(const mln_coord(D)& dind); // For 1D. + + window<D>& insert(const mln_coord(D)& drow, + const mln_coord(D)& dcol); // For 2D. + + window<D>& insert(const mln_coord(D)& dsli, + const mln_coord(D)& drow, + const mln_coord(D)& dcol); // For 3D. + /// \} + /// Apply a central symmetry to the target window. window<D>& sym(); @@ -137,6 +152,33 @@ template <typename D> window<D>& + window<D>::insert(const mln_coord(D)& dind) + { + D dp(dind); + mln_precondition(! has(dp)); + return this->insert(dp); + } + + template <typename D> + window<D>& + window<D>::insert(const mln_coord(D)& drow, const mln_coord(D)& dcol) + { + D dp(drow, dcol); + mln_precondition(! has(dp)); + return this->insert(dp); + } + + template <typename D> + window<D>& + window<D>::insert(const mln_coord(D)& dsli, const mln_coord(D)& drow, const mln_coord(D)& dcol) + { + D dp(dsli, drow, dcol); + mln_precondition(! has(dp)); + return this->insert(dp); + } + + template <typename D> + window<D>& window<D>::sym() { window<D> tmp; Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 1303) +++ mln/core/neighb.hh (working copy) @@ -91,7 +91,19 @@ * in the neighborhood definition; thus the client has not to * ensure the symmetry property; that is automatic. */ - void insert(const D& dp); + neighb_<D>& insert(const D& dp); + + /// \{ Insertion of a delta-point with different numbers of + /// arguments (coordinates) w.r.t. the dimension. + neighb_<D>& insert(const mln_coord(D)& dind); // For 1D. + + neighb_<D>& insert(const mln_coord(D)& drow, + const mln_coord(D)& dcol); // For 2D. + + neighb_<D>& insert(const mln_coord(D)& dsli, + const mln_coord(D)& drow, + const mln_coord(D)& dcol); // For 3D. + /// \} }; @@ -103,14 +115,42 @@ } template <typename D> - void + neighb_<D>& neighb_<D>::insert(const D& dp) { + mln_precondition(! has(dp)); typedef internal::set_of_<D> super; this->super::insert( dp); this->super::insert(-dp); + return *this; + } + + template <typename D> + neighb_<D>& + neighb_<D>::insert(const mln_coord(D)& dind) + { + D dp(dind); + mln_precondition(! has(dp)); + return this->insert(dp); + } + + template <typename D> + neighb_<D>& + neighb_<D>::insert(const mln_coord(D)& drow, const mln_coord(D)& dcol) + { + D dp(drow, dcol); + mln_precondition(! has(dp)); + return this->insert(dp); } + template <typename D> + neighb_<D>& + neighb_<D>::insert(const mln_coord(D)& dsli, const mln_coord(D)& drow, const mln_coord(D)& dcol) + { + D dp(dsli, drow, dcol); + mln_precondition(! has(dp)); + return this->insert(dp); + } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/ops.hh --- mln/core/ops.hh (revision 1303) +++ mln/core/ops.hh (working copy) @@ -41,6 +41,7 @@ namespace mln { + /*! \brief General definition of the "not equal to" operator. * * The "not equal to" operator is here defined for every milena @@ -135,6 +136,14 @@ // FIXME: Doc! template <typename O> + mln_trait_op_plus(O, unsigned) + operator+(unsigned lhs, const Object<O>& rhs) + { + return exact(rhs) + lhs; + } + + // FIXME: Doc! + template <typename O> mln_trait_op_plus(O, float) operator+(float lhs, const Object<O>& rhs) { @@ -154,6 +163,14 @@ // FIXME: Doc! template <typename O> + mln_trait_op_times(O, unsigned) + operator*(unsigned lhs, const Object<O>& rhs) + { + return exact(rhs) * lhs; + } + + // FIXME: Doc! + template <typename O> mln_trait_op_times(O, int) operator*(int lhs, const Object<O>& rhs) { @@ -177,6 +194,7 @@ } + # ifndef MLN_INCLUDE_ONLY template <typename O> @@ -184,6 +202,7 @@ { O tmp(exact(rhs)); // Copy. ++exact(rhs); // Pre-inc. + // FIXME: Activate: mln_postcondition(exact(rhs) = tmp + literal::one); return tmp; } @@ -192,6 +211,7 @@ { O tmp(exact(rhs)); // Copy. --exact(rhs); // Pre-dec. + // FIXME: Activate: mln_postcondition(exact(rhs) = tmp - literal::one); return tmp; } Index: mln/core/dpoint.hh --- mln/core/dpoint.hh (revision 1303) +++ mln/core/dpoint.hh (working copy) @@ -36,13 +36,20 @@ # include <mln/core/concept/dpoint.hh> # include <mln/core/internal/coord_impl.hh> # include <mln/fun/i2v/all.hh> +# include <mln/metal/vec.hh> +# include <mln/metal/converts_to.hh> namespace mln { - // fwd decl + /// \{ Fwd decls. template <typename M, typename C> struct point_; + namespace literal { + struct zero_t; + struct one_t; + } + /// \} /*! \brief Generic delta-point class. @@ -84,13 +91,18 @@ /// Constructor without argument. dpoint_(); - /// \{ Constructors with different numbers of argument w.r.t. the - /// dimension. + /// \{ Constructors with different numbers of arguments + /// (coordinates) w.r.t. the dimension. dpoint_(C ind); dpoint_(C row, C col); dpoint_(C sli, C row, C col); /// \} + /// \{ Constructors with literals. + dpoint_(const literal::zero_t&); + dpoint_(const literal::one_t&); // Works only in 1D. + /// \} + /// Constructor; coordinates are set by function \p f. template <typename F> dpoint_(const Function_i2v<F>& f); @@ -98,19 +110,18 @@ /// Set all coordinates to the value \p c. void set_all(C c); - /// Null delta-point (all coordinates are 0). + /// Zero delta-point. static const dpoint_<M,C> zero; - const C* coords_() const { return coord_; } - - /// Type of the array of coordinates. - typedef const C (&vec_t)[dim]; + /// Conversion towards a metal::vec. + template <typename Q> + operator metal::vec<M::dim, Q>() const; - /// Hook to coordinates. - vec_t to_vec() const { return coord_; } + /// Explicit conversion. + metal::vec<M::dim, C> to_vec() const; protected: - C coord_[dim]; + metal::vec<M::dim, C> coord_; }; @@ -160,9 +171,23 @@ } template <typename M, typename C> + dpoint_<M,C>::dpoint_(const literal::zero_t&) + { + coord_.set_all(0); + } + + template <typename M, typename C> + dpoint_<M,C>::dpoint_(const literal::one_t&) + { + metal::bool_<(dim = 1)>::check(); + coord_[0] = 1; + } + + template <typename M, typename C> template <typename F> dpoint_<M,C>::dpoint_(const Function_i2v<F>& f_) { + mlc_converts_to(mln_result(F), C)::check(); const F& f = exact(f_); for (unsigned i = 0; i < dim; ++i) coord_[i] = f(i); @@ -176,7 +201,23 @@ } template <typename M, typename C> - const dpoint_<M,C> dpoint_<M,C>::zero = all(0); + const dpoint_<M,C> + dpoint_<M,C>::zero = all(0); + + template <typename M, typename C> + template <typename Q> + dpoint_<M,C>::operator metal::vec<M::dim, Q> () const + { + return coord_; + } + + template <typename M, typename C> + metal::vec<M::dim, C> + dpoint_<M,C>::to_vec() const + { + return coord_; + } + # endif // ! MLN_INCLUDE_ONLY Index: mln/core/concept/function.hh --- mln/core/concept/function.hh (revision 1303) +++ mln/core/concept/function.hh (working copy) @@ -39,8 +39,19 @@ namespace mln { - // Fwd decl. + /// \{ + /// Fwd decls. template <typename E> struct Function; + template <typename E> struct Function_v2v; + template <typename E> struct Function_i2v; + template <typename E> struct Function_p2v; + template <typename E> struct Function_v2b; + template <typename E> struct Function_p2b; + template <typename E> struct Function_p2p; + template <typename E> struct Function_x2x; + /// \} + + // Function category flag type. template <> @@ -71,11 +82,15 @@ // Value -> Value. + template <> + struct Function_v2v<void> { typedef Function<void> super; }; + /// Base class for implementation of function-objects from value to /// value. template <typename E> struct Function_v2v : public Function<E> { + typedef Function_v2v<void> category; protected: Function_v2v(); Function_v2v(const Function_v2v&); @@ -84,11 +99,15 @@ // Index -> Value. + template <> + struct Function_i2v<void> { typedef Function_v2v<void> super; }; + /// Base class for implementation of function-objects from index to /// value. template <typename E> struct Function_i2v : public Function_v2v<E> { + typedef Function_i2v<void> category; protected: Function_i2v(); Function_i2v(const Function_i2v&); @@ -97,11 +116,15 @@ // Point -> Value. + template <> + struct Function_p2v<void> { typedef Function_v2v<void> super; }; + /// Base class for implementation of function-objects from point to /// value. template <typename E> struct Function_p2v : public virtual Function_v2v<E> { + typedef Function_p2v<void> category; protected: Function_p2v(); Function_p2v(const Function_p2v&); @@ -110,11 +133,15 @@ // Value -> bool. + template <> + struct Function_v2b<void> { typedef Function_v2v<void> super; }; + /// Base class for implementation of function-objects from value to /// bool. template <typename E> struct Function_v2b : public virtual Function_v2v<E> { + typedef Function_v2b<void> category; typedef bool result; protected: Function_v2b(); @@ -124,12 +151,16 @@ // Point -> bool. + template <> + struct Function_p2b<void> { typedef Function_p2v<void> super; }; // FIXME + /// Base class for implementation of function-objects from point to /// bool. template <typename E> struct Function_p2b : public Function_p2v<E>, public Function_v2b<E> { + typedef Function_p2b<void> category; typedef bool result; protected: Function_p2b(); @@ -139,11 +170,15 @@ // Point -> Point. + template <> + struct Function_p2p<void> { typedef Function_p2v<void> super; }; // FIXME + /// Base class for implementation of function-objects from point to /// point. template <typename E> struct Function_p2p : public Function_p2v<E> { + typedef Function_p2p<void> category; protected: Function_p2p(); Function_p2p(const Function_p2p&); @@ -152,11 +187,15 @@ // Vector -> Vector. + template <> + struct Function_x2x<void> { typedef Function_v2v<void> super; }; // FIXME + /// Base class for implementation of function-objects from vector to /// vector. template <typename E> struct Function_x2x : public Function_v2v<E> { + typedef Function_x2x<void> category; protected: Function_x2x(); Function_x2x(const Function_x2x&); Index: mln/core/concept/window.hh --- mln/core/concept/window.hh (revision 1303) +++ mln/core/concept/window.hh (working copy) @@ -123,8 +123,8 @@ // FIXME: Same grid! typedef mln_point(Wl) P; - mln_fwd_qiter(Wl) ql(exact(lhs), P::zero); - mln_fwd_qiter(Wr) qr(exact(rhs), P::zero); + mln_fwd_qiter(Wl) ql(exact(lhs), P::origin); + mln_fwd_qiter(Wr) qr(exact(rhs), P::origin); for (ql.start(), qr.start(); ql.is_valid() && qr.is_valid(); Index: mln/literal/ops.hh --- mln/literal/ops.hh (revision 0) +++ mln/literal/ops.hh (revision 0) @@ -0,0 +1,89 @@ +// 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_LITERAL_OPS_HH +# define MLN_LITERAL_OPS_HH + +/*! \file mln/literal/ops.hh + * \brief Definitions of some operators. + */ + +# include <mln/core/concept/literal.hh> + + + +namespace mln +{ + + template <typename O, typename L> + bool operator=(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + bool operator=(const Literal<L>& lhs, const Object<O>& rhs); + + template <typename L1, typename L2> + bool operator=(const Literal<L1>& lhs, const Literal<L2>& rhs); + + template <typename L> + bool operator=(const Literal<L>& lhs, const Literal<L>& rhs); + + // FIXME: Add other operators... + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename O, typename L> + bool operator=(const Object<O>& lhs, const Literal<L>& rhs) + { + return exact(lhs) = O(exact(rhs)); + } + + template <typename L, typename O> + bool operator=(const Literal<L>& lhs, const Object<O>& rhs) + { + return rhs = lhs; + } + + template <typename L1, typename L2> + bool operator=(const Literal<L1>&, const Literal<L2>&) + { + return false; + } + + template <typename L> + bool operator=(const Literal<L>&, const Literal<L>&) + { + return true; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_LITERAL_OPS_HH Index: mln/literal/one.hh --- mln/literal/one.hh (revision 0) +++ mln/literal/one.hh (revision 0) @@ -0,0 +1,76 @@ +// 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_LITERAL_ONE_HH +# define MLN_LITERAL_ONE_HH + +/*! \file mln/literal/one.hh + * + * \brief Definition of the literal of mln::one. + */ + +# include <mln/core/concept/literal.hh> +# include <mln/metal/converts_to.hh> + + +namespace mln +{ + + namespace literal + { + + /// Type of literal one. + struct one_t : public Literal<one_t> + { + // FIXME: Cf. comments in literal/zero.hh. + + template <typename T> + operator T () const; + }; + + + /// Literal one. + static one_t one = one_t(); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename T> + one_t::operator T () const + { + mlc_converts_to(int, T)::check(); + return 1; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::literal + +} // end of namespace mln + + +#endif // ! MLN_LITERAL_ONE_HH Index: mln/literal/all.hh --- mln/literal/all.hh (revision 0) +++ mln/literal/all.hh (revision 0) @@ -0,0 +1,58 @@ +// 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_LITERAL_ALL_HH +# define MLN_LITERAL_ALL_HH + +/*! \file mln/literal/all.hh + * + * \brief File that includes all literals. + */ + +namespace mln +{ + + /// Namespace of literals. + namespace literal {} + +} + + +# include <mln/literal/zero.hh> +# include <mln/literal/one.hh> + +// FIXME: Add: +// # include <mln/literal/white.hh> +// # include <mln/literal/black.hh> + +// # include <mln/literal/grays.hh> +// # include <mln/literal/colors.hh> + +# include <mln/literal/ops.hh> + + +#endif // ! MLN_LITERAL_ALL_HH Index: mln/metal/vec.hh --- mln/metal/vec.hh (revision 1303) +++ mln/metal/vec.hh (working copy) @@ -35,7 +35,6 @@ # include <mln/trait/all.hh> # include <mln/value/props.hh> # include <mln/fun/i2v/all.hh> -# include <mln/literal/zero.hh> # include <mln/value/concept/all.hh> @@ -45,6 +44,10 @@ namespace mln { + // Fwd decl. + namespace literal { struct zero_t; } + + namespace metal { @@ -139,7 +142,7 @@ vec(); - vec(mln::literal::zero_t); + vec(const literal::zero_t&); vec(const vec<n, T>& rhs); @@ -167,6 +170,9 @@ /// Zero value. static const vec<n, T> zero; + + /// Origin value. + static const vec<n, T> origin; }; } // end of namespace mln::metal @@ -323,9 +329,9 @@ } template <unsigned n, typename T> - vec<n,T>::vec(mln::literal::zero_t) + vec<n,T>::vec(const literal::zero_t&) { - this->set_all( mln::literal::zero ); + this->set_all(0); } template <unsigned n, typename T> @@ -416,6 +422,9 @@ template <unsigned n, typename T> const vec<n, T> vec<n, T>::zero = all(0); + template <unsigned n, typename T> + const vec<n, T> vec<n, T>::origin = all(0); + // eq Index: mln/value/cast.hh --- mln/value/cast.hh (revision 1303) +++ mln/value/cast.hh (working copy) @@ -61,7 +61,7 @@ } template <typename T, typename S> - typename S::equiv + typename S::equiv // FIXME: Is-that equiv here? cast_(const T&, const Value<S>& src) { return exact(src); Index: mln/value/int_u.hh --- mln/value/int_u.hh (revision 1303) +++ mln/value/int_u.hh (working copy) @@ -46,8 +46,10 @@ namespace mln { - // Fwd decl. + /// \{ Fwd decls. namespace value { template <unsigned n> struct int_u; } + namespace literal { struct zero_t; struct one_t; } + /// \} namespace trait @@ -68,6 +70,18 @@ }; template <unsigned n> + struct set_precise_binary_< promote, mln::value::int_u<n>, unsigned > + { + typedef unsigned ret; + }; + + template <unsigned n> + struct set_precise_binary_< promote, unsigned, mln::value::int_u<n> > + { + typedef unsigned ret; + }; + + template <unsigned n> struct set_precise_binary_< promote, mln::value::int_u<n>, float > { typedef float ret; @@ -119,8 +133,18 @@ /// Constructor from an integer. int_u(int i); - /// Conversion to an integer. - operator int() const; + /// \{ Constructors/assignments with literals. + int_u(const literal::zero_t&); + int_u& operator=(const literal::zero_t&); + int_u(const literal::one_t&); + int_u& operator=(const literal::one_t&); + /// \} + + /// Conversion to an unsigned integer. + operator unsigned() const; + + /// Unary operator minus. + int operator-() const; /// Assignment from an integer. int_u<n>& operator=(int i); @@ -181,12 +205,47 @@ } template <unsigned n> - int_u<n>::operator int() const + int_u<n>::int_u(const literal::zero_t&) + { + this->v_ = 0; + } + + template <unsigned n> + int_u<n>& + int_u<n>::operator=(const literal::zero_t&) + { + this->v_ = 0; + return *this; + } + + template <unsigned n> + int_u<n>::int_u(const literal::one_t&) + { + this->v_ = 1; + } + + template <unsigned n> + int_u<n>& + int_u<n>::operator=(const literal::one_t&) + { + this->v_ = 1; + return *this; + } + + template <unsigned n> + int_u<n>::operator unsigned() const { return this->v_; } template <unsigned n> + int + int_u<n>::operator-() const + { + return - int(this->v_); + } + + template <unsigned n> int_u<n>& int_u<n>::operator=(int i) { @@ -205,7 +264,8 @@ template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i) { - return ostr << debug::format(i.to_equiv()); + // FIXME: This code could be factored for almost every Value<*>... + return ostr << debug::format(i.to_equiv()); // FIXME: is to_equiv OK? } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/internal/value_like.hh --- mln/value/internal/value_like.hh (revision 1303) +++ mln/value/internal/value_like.hh (working copy) @@ -123,7 +123,7 @@ N value_like_<V,C,N,E>::to_interop() const { - return mln::internal::force_exact<E>(*this).operator N(); + return static_cast<N>(mln::internal::force_exact<E>(*this)); } template <typename V, typename C, typename N, typename E> Index: mln/make/w_window.hh --- mln/make/w_window.hh (revision 1303) +++ mln/make/w_window.hh (working copy) @@ -69,9 +69,9 @@ typedef mln_dpoint(W) D; typedef mln_point(D) P; mln::w_window<D, mln_result(F)> w_win; - mln_qiter(W) q(win, P::zero); + mln_qiter(W) q(win, P::origin); for_all(q) - w_win.insert(wei(q), q - P::zero); + w_win.insert(wei(q), q - P::origin); return w_win; } Index: mln/test/positive.hh --- mln/test/positive.hh (revision 1303) +++ mln/test/positive.hh (working copy) @@ -36,6 +36,7 @@ # include <mln/test/predicate.hh> # include <mln/pw/all.hh> # include <mln/fun/v2v/id.hh> +# include <mln/literal/zero.hh> namespace mln @@ -56,8 +57,12 @@ { const I& input = exact(input_); mln_precondition(input.has_data()); + // FIXME: Below the '>=' op should properly work with signed/unsigned without + // FIXME: warnings; so we really need to overload ops for functions when literals + // FIXME: are involved. + mln_value(I) zero_ = literal::zero; return test::predicate(input.domain(), - pw::value(input) >= pw::cst(0)); + pw::value(input) >= pw::cst(zero_)); // FIXME: test the version below. // return test::predicate(input, // fun::v2v::id<mln_value(I)>() >= pw::cst(0)); Index: mln/convert/to_image.hh --- mln/convert/to_image.hh (revision 1303) +++ mln/convert/to_image.hh (working copy) @@ -147,7 +147,7 @@ box_<P> b = geom::bbox(win); mln_image_from(W, bool) ima(b); level::fill(ima, false); - mln_qiter(W) q(win, P::zero); + mln_qiter(W) q(win, P::origin); for_all(q) ima(q) = true; return ima; @@ -168,7 +168,7 @@ typedef mln_point(W) P; box_<P> b = geom::bbox(w_win); mln_image_from(W, mln_weight(W)) ima(b); - mln_qiter(W) q(w_win, P::zero); + mln_qiter(W) q(w_win, P::origin); for_all(q) ima(q) = q.w(); return ima; Index: mln/convert/to_std_set.hh --- mln/convert/to_std_set.hh (revision 1303) +++ mln/convert/to_std_set.hh (working copy) @@ -59,9 +59,9 @@ typedef mln_dpoint(W) D; typedef mln_point(D) P; std::set<D> s; - mln_qiter(W) q(exact(win), P::zero); + mln_qiter(W) q(exact(win), P::origin); for_all(q) - s.insert(q - P::zero); + s.insert(q - P::origin); return s; } Index: mln/convert/to_window.hh --- mln/convert/to_window.hh (revision 1303) +++ mln/convert/to_window.hh (working copy) @@ -79,9 +79,9 @@ typedef mln_dpoint(N) D; typedef mln_point(D) P; window<D> win; - mln_niter(N) n(nbh, P::zero); + mln_niter(N) n(nbh, P::origin); for_all(n) - win.insert(n - P::zero); + win.insert(n - P::origin); return win; } @@ -92,10 +92,10 @@ typedef mln_dpoint(N) D; typedef mln_point(D) P; window<D> win; - mln_niter(N) n(nbh, P::zero); + mln_niter(N) n(nbh, P::origin); for_all(n) - if (n > P::zero) - win.insert(n - P::zero); + if (n > P::origin) + win.insert(n - P::origin); return win; } @@ -111,7 +111,7 @@ mln_piter(I) p(ima.domain()); for_all(p) if (ima(p)) - win.insert(p - P::zero); + win.insert(p - P::origin); return win; } Index: mln/convert/to_dpoint.hh --- mln/convert/to_dpoint.hh (revision 1303) +++ mln/convert/to_dpoint.hh (working copy) @@ -57,7 +57,7 @@ for (unsigned i = 0; i < P::dim; ++i) dp[i] = p[i]; typedef mln_point(P) P_; - mln_postcondition(dp = p - P_::zero); + mln_postcondition(dp = p - P_::origin); return dp; } Index: mln/convert/to_w_window.hh --- mln/convert/to_w_window.hh (revision 1303) +++ mln/convert/to_w_window.hh (working copy) @@ -62,7 +62,7 @@ mln_piter(I) p(input.domain()); for_all(p) if (input(p) != 0) - w_win.insert(input(p), p - P::zero); + w_win.insert(input(p), p - P::origin); return w_win; } Index: mln/geom/bbox.hh --- mln/geom/bbox.hh (revision 1303) +++ mln/geom/bbox.hh (working copy) @@ -80,7 +80,7 @@ mln_precondition(! win.is_empty()); typedef mln_point(W) P; - mln_qiter(W) q(win, P::zero); + mln_qiter(W) q(win, P::origin); std::pair<P, P> pp = geom::pmin_pmax(q); box_<P> tmp(pp.first, pp.second); Index: mln/geom/shift.hh --- mln/geom/shift.hh (revision 1303) +++ mln/geom/shift.hh (working copy) @@ -57,7 +57,7 @@ { typedef mln_point(W) P; window<mln_dpoint(W)> tmp; - mln_qiter(W) q(win, P::zero); + mln_qiter(W) q(win, P::origin); for_all(q) tmp.insert(convert::to_dpoint(q) + dp); return tmp; Index: mln/fun/v2v/saturate.hh --- mln/fun/v2v/saturate.hh (revision 1303) +++ mln/fun/v2v/saturate.hh (working copy) @@ -34,6 +34,7 @@ */ # include <mln/core/concept/function.hh> +# include <mln/metal/converts_to.hh> # include <mln/value/props.hh> @@ -86,11 +87,16 @@ V saturate<V>::operator()(const W& w) const { - if (w < min_) + // FIXME: Below we need something more powerful that mlc_converts_to + // FIXME: for instance, with W=int_s<10u> and V=int_u<8u>, it does not + // FIXME: works cause the cast is not obvious... + // mlc_converts_to(W, V)::check(); + V w_ = mln::value::cast<V>(w); + if (w_ < min_) return min_; - if (w > max_) + if (w_ > max_) return max_; - return mln::value::cast<V>(w); + return w_; } # endif // ! MLN_INCLUDE_ONLY Index: mln/win/octagon2d.hh --- mln/win/octagon2d.hh (revision 1303) +++ mln/win/octagon2d.hh (working copy) @@ -48,8 +48,9 @@ /*! \brief Octagon window defined on the 2D square grid. * * An octagon2d is centered and symmetrical. - * The length l of the octagon is such as l = 6*x + 1 - * where 0 <= x. + * + * The length L of the octagon is such as L = 6 * l + 1 + * where l >= 0. * * For instance: \n * o o o \n @@ -59,7 +60,7 @@ * o o o o o o o \n * o o o o o \n * o o o \n - * is defined with length = 7 (x = 0). + * is defined with L = 7 (l = 1). */ struct octagon2d : public Window< octagon2d >, public internal::dpoints_base_< dpoint2d, octagon2d > @@ -144,26 +145,26 @@ const int y = length / 6; const int x = y * 2; const int z = y + x; - insert(dpoint2d::zero); + insert(dpoint2d(0, 0)); for (int a = 1; a <= x; ++a) for (int b = 0; b <= x; ++b) { - insert(make::dpoint2d(a, b)); - insert(make::dpoint2d(-b, a)); - insert(make::dpoint2d(b, -a)); - insert(make::dpoint2d(-a, -b)); + insert(dpoint2d(a, b)); + insert(dpoint2d(-b, a)); + insert(dpoint2d(b, -a)); + insert(dpoint2d(-a, -b)); } for (int a = x + 1; a <= z; ++a) for (int b = -2 * x + a; b <= 2 * x - a; ++b) { - insert(make::dpoint2d(a, b)); - insert(make::dpoint2d(a, -b)); - insert(make::dpoint2d(-a, b)); - insert(make::dpoint2d(-a, -b)); - insert(make::dpoint2d(b, a)); - insert(make::dpoint2d(b, -a)); - insert(make::dpoint2d(-b, a)); - insert(make::dpoint2d(-b, -a)); + insert(dpoint2d(a, b)); + insert(dpoint2d(a, -b)); + insert(dpoint2d(-a, b)); + insert(dpoint2d(-a, -b)); + insert(dpoint2d(b, a)); + insert(dpoint2d(b, -a)); + insert(dpoint2d(-b, a)); + insert(dpoint2d(-b, -a)); } } Index: mln/morpho/hit_or_miss.hh --- mln/morpho/hit_or_miss.hh (revision 1303) +++ mln/morpho/hit_or_miss.hh (working copy) @@ -154,6 +154,9 @@ && pw::value(dil_bg) < pw::value(input), pw::value(input) - pw::value(dil_bg), pw::cst(V::zero))); + + // FIXME: Replace 'pw::cst(V::zero)' by 'pw::cst(V(literal::zero))' + // FIXME: and then by 'literal::zero'! } else if (exact(win_miss).is_centered()) { Index: mln/norm/infty.hh --- mln/norm/infty.hh (revision 1303) +++ mln/norm/infty.hh (working copy) @@ -34,6 +34,7 @@ */ # include <cmath> +# include <mln/metal/vec.hh> namespace mln @@ -42,9 +43,14 @@ namespace norm { - /// Infinity-norm of a vector \p vec. + /// Infinity-norm of a vector \p v (being a C static array). template <unsigned n, typename C> - C infty(const C (&vec)[n]); + C infty(const C (&v)[n]); + + /// Infinity-norm of a vector \p v (being a metal::vec). + template <unsigned n, typename C> + C infty(const metal::vec<n,C>& v); + /// Infinity-norm distance between vectors \p v1 and \p v2. template <unsigned n, typename C> @@ -54,12 +60,23 @@ # ifndef MLN_INCLUDE_ONLY template <unsigned n, typename C> - C infty(const C (&vec)[n]) + C infty(const C (&v)[n]) + { + C c = 0; + for (unsigned i = 0; i < n; ++i) + if (std::abs(v[i]) > c) + c = std::abs(v[i]); + return c; + } + + template <unsigned n, typename C> + C infty(const metal::vec<n,C>& v) { + // FIXME: Add a ctor to metal::vec... C c = 0; for (unsigned i = 0; i < n; ++i) - if (std::abs(vec[i]) > c) - c = std::abs(vec[i]); + if (std::abs(v[i]) > c) + c = std::abs(v[i]); return c; } Index: mln/norm/l2.hh --- mln/norm/l2.hh (revision 1303) +++ mln/norm/l2.hh (working copy) @@ -57,6 +57,9 @@ template <unsigned n, typename C> float l2_distance(const metal::vec<n,C>& vec1, const metal::vec<n,C>& vec2); + // FIXME: Replace float by mln_value_sum(C)... + + # ifndef MLN_INCLUDE_ONLY template <unsigned n, typename C>
participants (1)
-
Thierry Geraud