proto-1.0 21: Add point arithmetic and change coord_t.

Index: olena/oln/fancy/print.hh =================================================================== --- olena/oln/fancy/print.hh (revision 20) +++ olena/oln/fancy/print.hh (working copy) @@ -8,9 +8,7 @@ # include <ntg/real/int_u8.hh> // FIXME: no coupling like that! -# include <oln/core/1d/image1d.hh> -# include <oln/core/2d/image2d.hh> -# include <oln/core/3d/image3d.hh> +# include <oln/core/abstract/image_dimension.hh> namespace oln { Index: olena/oln/fancy/iota.hh =================================================================== --- olena/oln/fancy/iota.hh (revision 20) +++ olena/oln/fancy/iota.hh (working copy) @@ -1,79 +1,28 @@ #ifndef OLENA_FANCY_IOTA_HH # define OLENA_FANCY_IOTA_HH -# include <oln/core/1d/image1d.hh> -# include <oln/core/2d/image2d.hh> -# include <oln/core/3d/image3d.hh> +# include <oln/core/macros.hh> +# include <oln/core/abstract/image.hh> namespace oln { namespace fancy { - namespace impl { - template <typename T> - void iota(abstract::image1d<T>& inout); - template <typename T> - void iota(abstract::image2d<T>& inout); - template <typename T> - void iota(abstract::image3d<T>& inout); - } // end of namespace impl + // facade == impl - - - // facade - template <typename I> void iota(abstract::image<I>& inout) { - impl::iota(inout.exact()); + unsigned counter = 0; + oln_piter_type(I) p(inout.size()); + for_all(p) + inout[p] = ++counter; } + } // end of namespace oln::fancy - // impl - - namespace impl { - - // FIXME: must be generic, of course ! But for now, we have not yet - // iterators and we just want to test. - - template <typename T> - void iota(abstract::image2d<T>& inout) - { - unsigned counter = 0; - // FIXME: lacks cleaning - for (coord_t row = 0; row < inout.size().nrows(); ++row) - for (coord_t col = 0; col < inout.size().ncols(); ++col) - inout[point2d(row,col)] = ++counter; - } - - template <typename T> - void iota(abstract::image1d<T>& inout) - { - unsigned counter = 0; - // FIXME: lacks cleaning - for (coord_t index = 0; index < inout.size().nindices(); ++index) - inout[point1d(index)] = ++counter; - } - - template <typename T> - void iota(abstract::image3d<T>& inout) - { - unsigned counter = 0; - // FIXME: lacks cleaning - for (coord_t slice = 0; slice < inout.size().nslices(); ++slice) - for (coord_t row = 0; row < inout.size().nrows(); ++row) - for (coord_t col = 0; col < inout.size().ncols(); ++col) - inout[point3d(slice,row,col)] = ++counter; - } - - } // end of namespace impl - - - } // end of namespace fancy - - } // end of namespace oln Index: olena/oln/config/pconf.hh =================================================================== --- olena/oln/config/pconf.hh (revision 0) +++ olena/oln/config/pconf.hh (revision 0) @@ -0,0 +1,11 @@ +/*! Define to the address where bug reports for this package should be sent. */ +#define OLN_PACKAGE_BUGREPORT "olena-bugs@lrde.epita.fr" + +/*! Define to the full name of this package. */ +#define OLN_PACKAGE_NAME "Olena" + +/*! Define to the full name and version of this package. */ +#define OLN_PACKAGE_STRING "Olena 0.10" + +/*! Define to the version of this package. */ +#define OLN_PACKAGE_VERSION "0.10" Index: olena/oln/core/macros.hh =================================================================== --- olena/oln/core/macros.hh (revision 20) +++ olena/oln/core/macros.hh (working copy) @@ -28,6 +28,7 @@ # define oln_size_type(T) typename oln::props<oln_category_type(T),T>::size_type # define oln_point_type(T) typename oln::props<oln_category_type(T),T>::point_type +# define oln_dpoint_type(T) typename oln::props<oln_category_type(T),T>::dpoint_type # define oln_value_type(T) typename oln::props<oln_category_type(T),T>::value_type # define oln_iter_type(T) typename oln::props<oln_category_type(T),T>::iter_type Index: olena/oln/core/abstract/piter.hh =================================================================== --- olena/oln/core/abstract/piter.hh (revision 20) +++ olena/oln/core/abstract/piter.hh (working copy) @@ -11,6 +11,10 @@ # include <oln/core/macros.hh> + +# define for_all(P) for(p.start(); p.is_valid(); p.next()) + + namespace oln { namespace abstract { @@ -48,25 +52,25 @@ void next() { - precondition(this->is_ok()); + precondition(this->is_valid()); this->exact().impl_next(); } - bool is_ok() const + bool is_valid() const { - return this->exact().impl_is_ok(); + return this->exact().impl_is_valid(); } operator point_type() const { - precondition(this->is_ok()); + precondition(this->is_valid()); return this->p_; } void invalidate() { this->exact().impl_invalidate(); - postcondition(not this->is_ok()); + postcondition(not this->is_valid()); } protected: @@ -75,7 +79,6 @@ s_(s), p_() { - this->invalidate(); } const size_type s_; Index: olena/oln/core/abstract/point.hh =================================================================== --- olena/oln/core/abstract/point.hh (revision 20) +++ olena/oln/core/abstract/point.hh (working copy) @@ -3,29 +3,86 @@ # include <mlc/any.hh> +# include <oln/core/cats.hh> +# include <oln/core/props.hh> +# include <oln/core/macros.hh> + + +/*! \namespace oln +** \brief oln namespace. +*/ namespace oln { + + /// fwd decl namespace abstract { + template <typename E> struct point; + } + + /*! \class default_props< cat::point > + ** + ** Default properties for points. Specialization of + ** default_props<category>. + */ + template <> + struct default_props < cat::point > + { + typedef mlc::undefined_type dpoint_type; + }; + + + /*! \namespace oln::abstract + ** \brief oln::abstract namespace. + */ + namespace abstract { + + /*! \class abstract::point<E> + ** + ** The abstract::point class is the base class from whom derives + ** every concrete point. + ** + ** Parameter E is the exact type of point. + */ template <typename E> struct point : public mlc::any__best_memory<E> { + + /*! \brief Test equality of two points. Nota bene: this method + ** is abstract-like. + ** + ** \return True if both points are the same, false otherwise. + */ bool operator==(const point& rhs) const { return this->exact().impl_eq(rhs.exact()); } + /*! \brief Test difference of two points. Nota bene: this method + ** is concrete (and based on abstract::point::operator==). + ** + ** \return True if both points are different, false otherwise. + */ bool operator!=(const point& rhs) const { return not this->operator==(rhs); } - bool operator<(const point& rhs) const + typedef oln_dpoint_type(E) dpoint_type; + + // FIXME: doc + const point operator+(const dpoint_type& dp) const { - return this->exact().impl_less(rhs.exact()); + return this->exact().impl_plus(dp); } + const dpoint_type operator-(const point& rhs) const + { + return this->exact().impl_minus(rhs); + } + protected: + point() {} }; @@ -35,4 +92,4 @@ -#endif // ndef PROTO_OLN_CORE_ABSTRACT_POINT_HH +#endif // ! PROTO_OLN_CORE_ABSTRACT_POINT_HH Index: olena/oln/core/abstract/dpoint.hh =================================================================== --- olena/oln/core/abstract/dpoint.hh (revision 0) +++ olena/oln/core/abstract/dpoint.hh (revision 0) @@ -0,0 +1,52 @@ +#ifndef PROTO_OLN_CORE_ABSTRACT_DPOINT_HH +# define PROTO_OLN_CORE_ABSTRACT_DPOINT_HH + +# include <mlc/any.hh> + +/*! \namespace oln +** \brief oln namespace. +*/ +namespace oln { + + /*! \namespace oln::abstract + ** \brief oln::abstract namespace. + */ + namespace abstract { + + /*! \class abstract::dpoint<E> + ** + ** The abstract::dpoint class is the base class from whom derives + ** every concrete dpoint. A dpoint is a difference between a couple + ** of points. + ** + ** Parameter E is the exact type of dpoint. + */ + template <typename E> + struct dpoint : public mlc::any__best_memory<E> + { + + /// Test equality of two dpoints. + // FIXME: doc... + bool operator==(const dpoint& rhs) const + { + return this->exact().impl_eq(rhs.exact()); + } + + /// Test difference between two dpoints. + bool operator!=(const dpoint& rhs) const + { + return not this->operator==(rhs); + } + + protected: + + dpoint() {} + }; + + } // end of namespace abstract + +} // end of namespace oln + + + +#endif // ! PROTO_OLN_CORE_ABSTRACT_DPOINT_HH Index: olena/oln/core/coord.hh =================================================================== --- olena/oln/core/coord.hh (revision 20) +++ olena/oln/core/coord.hh (working copy) @@ -1,16 +1,151 @@ #ifndef OLENA_CORE_COORD_HH # define OLENA_CORE_COORD_HH +# include <iostream> +# include <limits.h> +# include <mlc/contract.hh> + +// FIXME: doc + + namespace oln { - typedef int coord_t; // FIXME: define a struct to get stronger typing + class coord_t + { + public: + + typedef int value_type; + + coord_t() : + value_(undef_()) + { + } + + coord_t(value_type value) : + value_(value) + { + } + + coord_t& operator=(value_type rhs) + { + this->value_ = rhs; + return *this; + } + + operator value_type() const + { + precondition(this->is_defined()); + return value_; + } + + bool operator==(value_type rhs) const + { + precondition(this->is_defined()); + return value_ == rhs; + } + + bool operator!=(value_type rhs) const + { + precondition(this->is_defined()); + return value_ != rhs; + } + + const coord_t operator+(value_type rhs) const + { + precondition(this->is_defined()); + coord_t tmp(value_ + rhs); return tmp; + } + + coord_t& operator++() + { + precondition(this->is_defined()); + ++value_; + return *this; + } + + const coord_t operator++(int) + { + precondition(this->is_defined()); + coord_t tmp = *this; + ++value_; + return tmp; + } + + const coord_t operator-(value_type rhs) const + { + precondition(this->is_defined()); + coord_t tmp(value_ - rhs); + return tmp; + } + + const coord_t operator-() const + { + precondition(this->is_defined()); + coord_t tmp(-value_); return tmp; + } + + coord_t& operator--() + { + precondition(this->is_defined()); + --value_; + return *this; + } + + const coord_t operator--(int) + { + precondition(this->is_defined()); + coord_t tmp = *this; + --value_; + return tmp; + } + + bool is_defined() const + { + return value_ != undef_(); + } + + bool is_undefined() const + { + return value_ == undef_(); + } + + static const coord_t& infty() + { + static coord_t infty_ = INT_MAX; + return infty_; + } + + static const coord_t& _infty() + { + static coord_t _infty_ = INT_MIN + 1; + return _infty_; + } + + // FIXME: to be continued + + private: + + value_type value_; + + static const value_type undef_() + { + return INT_MIN; + } + + }; + + } // end of namespace oln -// CHANGE: specialization internal::default_less is removed -// what was the point? and why was it an 'internal' feature?! + +std::ostream& operator<<(std::ostream& ostr, const oln::coord_t& c) +{ + precondition(c.is_defined()); + return ostr << oln::coord_t::value_type(c); +} #endif // ! OLENA_CORE_COORD_HH Index: olena/oln/core/1d/dpoint1d.hh =================================================================== --- olena/oln/core/1d/dpoint1d.hh (revision 0) +++ olena/oln/core/1d/dpoint1d.hh (revision 0) @@ -0,0 +1,87 @@ +#ifndef OLENA_CORE_1D_DPOINT1D_HH +# define OLENA_CORE_1D_DPOINT1D_HH + +# include <ostream> + +# include <oln/core/coord.hh> +# include <oln/core/1d/point1d.hh> + +// FIXME: there's an assumption here: we do not need inheritance for +// dpoints. so abstract::dpoint does not exist... + +// FIXME: doc! + +// FIXME: test that coords are defined + + +namespace oln { + + struct dpoint1d + { + dpoint1d() + { + } + + dpoint1d(coord_t index_) : + index_(index_) + { + } + + dpoint1d(const dpoint1d& rhs) : + index_(rhs.index_) + { + } + + dpoint1d& operator=(const dpoint1d& rhs) + { + if (&rhs == this) + return *this; + this->index_ = rhs.index_; + return *this; + } + + bool operator==(const dpoint1d& rhs) const + { + return this->index_ == rhs.index_; + } + + bool operator!=(const dpoint1d& rhs) const + { + return this->index_ != rhs.index_; + } + + const dpoint1d operator+(const dpoint1d& rhs) const + { + dpoint1d tmp(this->index() + rhs.index()); + return tmp; + } + + const point1d operator+(const point1d& rhs) const + { + point1d tmp(this->index() + rhs.index()); + return tmp; + } + + const dpoint1d operator-() const + { + dpoint1d tmp(-this->index()); + return tmp; + } + + const coord_t index() const { return index_; } + coord_t& index() { return index_; } + + protected: + coord_t index_; + }; + +} // end of namespace oln + + +std::ostream& operator<<(std::ostream& ostr, const oln::dpoint1d& dp) +{ + return ostr << '(' << dp.index() << ')'; +} + + +#endif // ! OLENA_CORE_1D_DPOINT1D_HH Index: olena/oln/core/1d/fwd_piter1d.hh =================================================================== --- olena/oln/core/1d/fwd_piter1d.hh (revision 0) +++ olena/oln/core/1d/fwd_piter1d.hh (revision 0) @@ -0,0 +1,74 @@ +#ifndef PROTO_OLN_CORE_1D_FWD_PITER1D_HH +# define PROTO_OLN_CORE_1D_FWD_PITER1D_HH + +# include <mlc/contract.hh> + +# include <oln/core/abstract/piter.hh> +# include <oln/core/1d/point1d.hh> +# include <oln/core/1d/size1d.hh> +# include <oln/core/props.hh> + + +namespace oln { + + struct fwd_piter1d; + + template <> struct category_type< fwd_piter1d > { typedef cat::piter ret; }; + + template <> + struct props < cat::piter, fwd_piter1d > : public default_props< cat::piter > + { + typedef point1d point_type; + typedef size1d size_type; + }; + + struct fwd_piter1d : public abstract::piter< fwd_piter1d > + { + + typedef abstract::piter<fwd_piter1d> super_type; + + fwd_piter1d(const size1d& size) : + super_type(size) + { + this->exact_ptr = this; + this->invalidate(); + } + +# if defined __GNUC__ && __GNUC__ >= 3 + friend class abstract::piter< fwd_piter1d >; + protected: +# endif + + void impl_start() + { + this->p_.index() = 0; + postcondition(this->p_.index().is_defined()); + } + + bool impl_is_valid() const + { + precondition(this->p_.index().is_defined()); + return this->p_.index() < this->s_.nindices(); + } + + void impl_next() + { + precondition(this->p_.index().is_defined()); + precondition(this->p_.index() >= 0 and this->p_.index() <= this->s_.nindices()); + if (this->p_.index() == this->s_.nindices()) + return; + ++this->p_.index(); + postcondition(this->p_.index().is_defined()); + } + + void impl_invalidate() + { + this->p_.index() = this->s_.nindices(); + postcondition(this->p_.index().is_defined()); + } + + }; +} + + +#endif // ndef PROTO_OLN_CORE_1D_FWD_PITER1D_HH Index: olena/oln/core/1d/point1d.hh =================================================================== --- olena/oln/core/1d/point1d.hh (revision 20) +++ olena/oln/core/1d/point1d.hh (working copy) @@ -5,13 +5,30 @@ # include <oln/core/abstract/point.hh> # include <oln/core/coord.hh> +# include <oln/core/cats.hh> +# include <oln/core/props.hh> +// FIXME: doc + +// FIXME: test that coords are defined + namespace oln { + struct point1d; + struct dpoint1d; + + template <> + struct category_type< point1d > { typedef cat::point ret; }; + + template <> + struct props < cat::point, point1d > + { + typedef dpoint1d dpoint_type; + }; + struct point1d : public abstract::point< point1d > { - point1d() : - index_(0) + point1d() { } @@ -33,16 +50,25 @@ return *this; } + const coord_t index() const { return index_; } + coord_t& index() { return index_; } + +# if defined __GNUC__ && __GNUC__ >= 3 + friend class abstract::point< point1d >; + protected: +# endif + + const point1d impl_plus(const dpoint1d& rhs) const; + + const dpoint1d impl_minus(const point1d& rhs) const; + bool impl_eq(const point1d& rhs) const { return this->index_ == rhs.index_; } - const coord_t index() const { return index_; } - - coord_t& index() { return index_; } - protected: + coord_t index_; }; @@ -55,4 +81,25 @@ } +# include <oln/core/1d/dpoint1d.hh> + + +namespace oln { + + const point1d point1d::impl_plus(const dpoint1d& rhs) const + { + point1d tmp(this->index() + rhs.index()); + return tmp; + } + + const dpoint1d point1d::impl_minus(const point1d& rhs) const + { + dpoint1d tmp(this->index() - rhs.index()); + return tmp; + } + +} // end of namespace oln + + + #endif // ! OLENA_CORE_1D_POINT1D_HH Index: olena/oln/core/1d/size1d.hh =================================================================== --- olena/oln/core/1d/size1d.hh (revision 20) +++ olena/oln/core/1d/size1d.hh (working copy) @@ -11,9 +11,7 @@ struct size1d : public abstract::size< size1d > { - size1d() : - nindices_(0), - border_(0) + size1d() {} size1d(coord_t nindices_) : Index: olena/oln/core/2d/dpoint2d.hh =================================================================== --- olena/oln/core/2d/dpoint2d.hh (revision 0) +++ olena/oln/core/2d/dpoint2d.hh (revision 0) @@ -0,0 +1,90 @@ +#ifndef OLENA_CORE_2D_DPOINT2D_HH +# define OLENA_CORE_2D_DPOINT2D_HH + +# include <ostream> + +# include <oln/core/coord.hh> +# include <oln/core/2d/point2d.hh> + +// FIXME: there's an assumption here: we do not need inheritance for +// dpoints. so abstract::dpoint does not exist... + +// FIXME: doc! + +namespace oln { + + struct dpoint2d + { + dpoint2d() + { + } + + dpoint2d(coord_t row_, coord_t col_) : + row_(row_), + col_(col_) + { + } + + dpoint2d(const dpoint2d& rhs) : + row_(rhs.row_), + col_(rhs.col_) + { + } + + dpoint2d& operator=(const dpoint2d& rhs) + { + if (&rhs == this) + return *this; + this->row_ = rhs.row_; + this->col_ = rhs.col_; + return *this; + } + + bool operator==(const dpoint2d& rhs) const + { + return this->row_ == rhs.row_ and this->col_ == rhs.col_; + } + + bool operator!=(const dpoint2d& rhs) const + { + return not this->operator==(rhs); + } + + const dpoint2d operator+(const dpoint2d& rhs) const + { + dpoint2d tmp(this->row() + rhs.row(), this->col() + rhs.col()); + return tmp; + } + + const point2d operator+(const point2d& rhs) const + { + point2d tmp(this->row() + rhs.row(), this->col() + rhs.col()); + return tmp; + } + + const dpoint2d operator-() const + { + dpoint2d tmp(-this->row(), -this->col()); + return tmp; + } + + const coord_t row() const { return row_; } + const coord_t col() const { return col_; } + + coord_t& row() { return row_; } + coord_t& col() { return col_; } + + protected: + coord_t row_, col_; + }; + +} // end of namespace oln + + +std::ostream& operator<<(std::ostream& ostr, const oln::dpoint2d& dp) +{ + return ostr << '(' << dp.row() << ',' << dp.col() << ')'; +} + + +#endif // ! OLENA_CORE_2D_DPOINT2D_HH Index: olena/oln/core/2d/array2d.hh =================================================================== --- olena/oln/core/2d/array2d.hh (revision 20) +++ olena/oln/core/2d/array2d.hh (working copy) @@ -174,9 +174,9 @@ or (buffer_ == 0 and array_ == 0 and - size_.nrows() == 0 and - size_.ncols() == 0 and - size_.border() == 0)); + size_.nrows().is_undefined() and + size_.ncols().is_undefined() and + size_.border().is_undefined())); } }; Index: olena/oln/core/2d/fwd_piter2d.hh =================================================================== --- olena/oln/core/2d/fwd_piter2d.hh (revision 20) +++ olena/oln/core/2d/fwd_piter2d.hh (working copy) @@ -27,38 +27,51 @@ typedef abstract::piter<fwd_piter2d> super_type; - friend class abstract::piter<fwd_piter2d>; - fwd_piter2d(const size2d& size) : super_type(size) { this->exact_ptr = this; + this->invalidate(); } +# if defined __GNUC__ && __GNUC__ >= 3 + friend class abstract::piter< fwd_piter2d >; + protected: +# endif + void impl_start() { this->p_.row() = 0; this->p_.col() = 0; + postcondition(this->p_.row().is_defined() and this->p_.col().is_defined()); } - bool impl_is_ok() const + bool impl_is_valid() const { + precondition(this->p_.row().is_defined() and this->p_.col().is_defined()); return this->p_.row() < this->s_.nrows(); } void impl_next() { + precondition(this->p_.row().is_defined() and this->p_.col().is_defined()); + precondition(this->p_.row() >= 0 and this->p_.row() <= this->s_.nrows() + and + this->p_.col() >= 0 and this->p_.col() <= this->s_.ncols()); ++this->p_.col(); if (this->p_.col() != this->s_.ncols()) return; this->p_.col() = 0; + precondition(this->p_.row() != this->s_.nrows()); ++this->p_.row(); + postcondition(this->p_.row().is_defined() and this->p_.col().is_defined()); } void impl_invalidate() { this->p_.row() = this->s_.nrows(); this->p_.col() = this->s_.ncols(); + postcondition(this->p_.row().is_defined() and this->p_.col().is_defined()); } }; Index: olena/oln/core/2d/point2d.hh =================================================================== --- olena/oln/core/2d/point2d.hh (revision 20) +++ olena/oln/core/2d/point2d.hh (working copy) @@ -5,14 +5,28 @@ # include <oln/core/abstract/point.hh> # include <oln/core/coord.hh> +# include <oln/core/cats.hh> +# include <oln/core/props.hh> +// FIXME: doc! + namespace oln { + struct point2d; + struct dpoint2d; + + template <> + struct category_type< point2d > { typedef cat::point ret; }; + + template <> + struct props < cat::point, point2d > + { + typedef dpoint2d dpoint_type; + }; + struct point2d : public abstract::point< point2d > { - point2d() : - row_(0), - col_(0) + point2d() { } @@ -37,18 +51,28 @@ return *this; } - bool impl_eq(const point2d& rhs) const - { - return this->row_ == rhs.row_ and this->col_ == rhs.col_; - } - const coord_t row() const { return row_; } const coord_t col() const { return col_; } coord_t& row() { return row_; } coord_t& col() { return col_; } +# if defined __GNUC__ && __GNUC__ >= 3 + friend class abstract::point< point2d >; protected: +# endif + + const point2d impl_plus(const dpoint2d& rhs) const; + + const dpoint2d impl_minus(const point2d& rhs) const; + + bool impl_eq(const point2d& rhs) const + { + return this->row_ == rhs.row_ and this->col_ == rhs.col_; + } + + protected: + coord_t row_, col_; }; @@ -61,4 +85,24 @@ } +# include <oln/core/2d/dpoint2d.hh> + + +namespace oln { + + const point2d point2d::impl_plus(const dpoint2d& rhs) const + { + point2d tmp(this->row() + rhs.row(), this->col() + rhs.col()); + return tmp; + } + + const dpoint2d point2d::impl_minus(const point2d& rhs) const + { + dpoint2d tmp(this->row() - rhs.row(), this->col() - rhs.col()); + return tmp; + } + +} // end of namespace oln + + #endif // ! OLENA_CORE_2D_POINT2D_HH Index: olena/oln/core/2d/size2d.hh =================================================================== --- olena/oln/core/2d/size2d.hh (revision 20) +++ olena/oln/core/2d/size2d.hh (working copy) @@ -11,10 +11,7 @@ struct size2d : public abstract::size< size2d > { - size2d() : - nrows_(0), - ncols_(0), - border_(0) + size2d() {} size2d(coord_t nrows_, coord_t ncols_) :
participants (1)
-
Thierry GERAUD