
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add line2d, bresenham, the safe_image morpher, and underlying types. * oln/core/2d/line2d.hh, * oln/core/gen/safe_image.hh, * oln/core/internal/pset_adaptor.hh, * oln/draw, * oln/draw/bresenham.hh: New. * TODO: Augment. * oln/core/concept/image.hh (read_, write_): New. * oln/core/concept/image_identity.hh: Update. * oln/core/concept/generalised_point.hh (include): Fix. * oln/core/concept/point_set.hh (~Point_Set): New. * oln/core/concept/value.hh: Cosmetic changes. * oln/core/1d/array1d.hh (operator()): Remove. (array1d_): Fix. * oln/core/1d/image1d.hh, * oln/core/1d/image1d_b.hh: Update. * oln/core/1d/box1d.hh, * oln/core/1d/point1d.hh, * oln/core/2d/box2d.hh, * oln/core/2d/point2d.hh, * oln/core/gen/box.hh: Clean up. * oln/core/2d/image2d.hh, * oln/core/2d/image2d_b.hh (impl_write): New. * oln/core/gen/pset_compare.hh (op_leq_): New. * oln/core/gen/fbbox.hh (fbbox_): Fix. (box_t): New. (include): Add point_set_base. * oln/core/gen/single_value_image.hh, * oln/core/internal/box.hh: Cosmetic changes. * oln/core/internal/point_set_base.hh (f_box_from_point_): New. * oln/core/internal/op_image_restricted_to_pset.hh (impl_owns_): New. * oln/core/internal/point_set_std_based.hh (box): New in vtypes. (pset_std_based_fwd_piter_): Change inheritance to internal::iterator_on_points_base. Make the constructor argument type more general. (pset_std_based_bkd_piter_): Likewise. * oln/core/internal/image_base.hh (operator |): Add non-const versions. * oln/core/internal/iterator_on_points_base.hh: Add a FIXME. * oln/value/builtin.hh: Fix. TODO | 7 oln/core/1d/array1d.hh | 33 +--- oln/core/1d/box1d.hh | 6 oln/core/1d/image1d.hh | 17 +- oln/core/1d/image1d_b.hh | 13 + oln/core/1d/point1d.hh | 4 oln/core/2d/box2d.hh | 6 oln/core/2d/image2d.hh | 9 + oln/core/2d/image2d_b.hh | 9 + oln/core/2d/line2d.hh | 161 +++++++++++++++++++ oln/core/2d/point2d.hh | 6 oln/core/concept/generalised_point.hh | 3 oln/core/concept/image.hh | 20 ++ oln/core/concept/image_identity.hh | 18 +- oln/core/concept/point_set.hh | 8 oln/core/concept/value.hh | 2 oln/core/gen/box.hh | 11 - oln/core/gen/fbbox.hh | 19 +- oln/core/gen/pset_compare.hh | 25 ++- oln/core/gen/safe_image.hh | 187 +++++++++++++++++++++++ oln/core/gen/single_value_image.hh | 2 oln/core/internal/box.hh | 6 oln/core/internal/image_base.hh | 21 ++ oln/core/internal/iterator_on_points_base.hh | 2 oln/core/internal/op_image_restricted_to_pset.hh | 10 + oln/core/internal/point_set_base.hh | 22 ++ oln/core/internal/point_set_std_based.hh | 31 ++- oln/core/internal/pset_adaptor.hh | 135 ++++++++++++++++ oln/draw/bresenham.hh | 87 ++++++++++ oln/value/builtin.hh | 16 + 30 files changed, 804 insertions(+), 92 deletions(-) Index: TODO --- TODO (revision 918) +++ TODO (working copy) @@ -12,7 +12,7 @@ function, an accessor, a projection, etc.) basics important routines: fill, assign, clone, unmorph (undress?), -convert, ... +convert, ... + add 'with' to disambiguate torus and mask types, and the proper niter type deductions (with or without virtual border) @@ -30,7 +30,10 @@ meta-window type; for instance, ball, segment, etc. -const promotions for op_<L,O,R> types +const promotions for op_<L,O,R> types + result is Mutable only +if the underlying type is not 'const' + +in image_identity.hh use 'current' * Tiny improvements Index: oln/core/concept/image.hh --- oln/core/concept/image.hh (revision 918) +++ oln/core/concept/image.hh (working copy) @@ -133,6 +133,7 @@ bool owns_(const psite& p) const; rvalue operator()(const psite& p) const; + rvalue read_(const psite& p) const; const pset& points() const; @@ -183,10 +184,12 @@ public automatic::get_impl<Mutable_Image, Exact> { stc_using_from(Image, psite); + stc_using_from(Image, value); using Image<Exact>::operator(); stc_typename(lvalue); lvalue operator()(const psite& p); + void write_(const psite& p, const value& v); protected: Mutable_Image(); @@ -438,6 +441,14 @@ } template <typename Exact> + typename Image<Exact>::rvalue + Image<Exact>::read_(const typename Image<Exact>::psite& p) const + { + precondition(this->owns_(p)); + return exact(this)->impl_read(p); + } + + template <typename Exact> const typename Image<Exact>::box& Image<Exact>::bbox() const { @@ -502,6 +513,15 @@ } template <typename Exact> + void + Mutable_Image<Exact>::write_(const typename Mutable_Image<Exact>::psite& p, + const typename Mutable_Image<Exact>::value& v) + { + precondition(this->owns_(p)); + exact(this)->impl_write(p, v); + } + + template <typename Exact> Mutable_Image<Exact>::Mutable_Image() { } Index: oln/core/concept/image_identity.hh --- oln/core/concept/image_identity.hh (revision 918) +++ oln/core/concept/image_identity.hh (working copy) @@ -85,7 +85,9 @@ { stc_typename(psite); stc_typename(lvalue); + stc_typename(value); lvalue impl_read_write(const psite& p); + void impl_write(const psite& p, const value& v); }; @@ -228,13 +230,25 @@ /// Concept-class "Mutable_Image". +# define current set_impl< Mutable_Image, behavior::identity, Exact > + template <typename Exact> - typename set_impl< Mutable_Image, behavior::identity, Exact >::lvalue - set_impl< Mutable_Image, behavior::identity, Exact >::impl_read_write(const typename set_impl< Mutable_Image, behavior::identity, Exact >::psite& p) + typename current::lvalue + current::impl_read_write(const typename current::psite& p) { return exact(this)->image().operator()(p); } + template <typename Exact> + void + current::impl_write(const typename current::psite& p, + const typename current::value& v) + { + return exact(this)->image().write_(p, v); + } + +# undef current + /// Concept-class "Fast_Image". Index: oln/core/concept/generalised_point.hh --- oln/core/concept/generalised_point.hh (revision 918) +++ oln/core/concept/generalised_point.hh (working copy) @@ -28,6 +28,9 @@ #ifndef OLN_CORE_CONCEPT_GENERALISED_POINTS_HH # define OLN_CORE_CONCEPT_GENERALISED_POINTS_HH +# include <oln/core/equipment.hh> + + namespace oln { Index: oln/core/concept/point_set.hh --- oln/core/concept/point_set.hh (revision 918) +++ oln/core/concept/point_set.hh (working copy) @@ -59,6 +59,7 @@ protected: Point_Set(); + ~Point_Set(); }; // end of oln::Point_Set<Exact> @@ -117,6 +118,13 @@ } template <typename Exact> + Point_Set<Exact>::~Point_Set() + { + // FIXME: check method impls. + // unsigned (Exact::*m)() const = & Exact::impl_npoints; + } + + template <typename Exact> Box<Exact>::Box() { } Index: oln/core/concept/value.hh --- oln/core/concept/value.hh (revision 918) +++ oln/core/concept/value.hh (working copy) @@ -70,7 +70,7 @@ { } -# endif +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/1d/array1d.hh --- oln/core/1d/array1d.hh (revision 918) +++ oln/core/1d/array1d.hh (working copy) @@ -59,11 +59,8 @@ /// Dtor. ~array1d_(); - const T& operator()(C i) const; - T& operator()(C i); - - const T& operator[](std::size_t ind) const; - T& operator[](std::size_t ind); + const T& operator[](C i) const; + T& operator[](C i); bool has(C i) const; @@ -119,36 +116,22 @@ } template <typename T, typename C> - const T& array1d_<T, C>::operator()(C i) const + const T& array1d_<T, C>::operator[](C i) const { + precondition(buffer_ != 0); precondition(has(i)); return buffer_[i]; } template <typename T, typename C> - T& array1d_<T, C>::operator()(C i) + T& array1d_<T, C>::operator[](C i) { + precondition(buffer_ != 0); precondition(has(i)); return buffer_[i]; } template <typename T, typename C> - const T& array1d_<T, C>::operator[](std::size_t ind) const - { - precondition(buffer_ != 0); - precondition(ind < len_); - return buffer_[ind]; - } - - template <typename T, typename C> - T& array1d_<T, C>::operator[](std::size_t ind) - { - precondition(buffer_ != 0); - precondition(ind < len_); - return buffer_[ind]; - } - - template <typename T, typename C> bool array1d_<T, C>::has(C i) const { return i >= imin_ and i <= imax_; @@ -195,17 +178,19 @@ void array1d_<T, C>::allocate_() { buffer_ = new T[len_]; + buffer_ -= imin_; } template <typename T, typename C> void array1d_<T, C>::deallocate_() { precondition(buffer_ != 0); + buffer_ += imin_; delete[] buffer_; buffer_ = 0; // safety } -# endif +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/1d/image1d.hh --- oln/core/1d/image1d.hh (revision 918) +++ oln/core/1d/image1d.hh (working copy) @@ -95,6 +95,8 @@ T& impl_read_write(const point1d& p); T& impl_index_read_write(unsigned i); + void impl_write(const point1d& p, const T& v); + std::size_t impl_npoints() const; const box1d& impl_points() const; @@ -135,7 +137,7 @@ const T& image1d<T>::impl_read(const point1d& p) const { assert(this->has_data()); - return this->data_->first.operator()(p.ind()); + return this->data_->first[p.ind()]; } template <typename T> @@ -143,14 +145,14 @@ { assert(this->has_data()); assert(i < this->npoints()); - return this->data_->first.operator[](i); + return this->data_->first[i]; } template <typename T> T& image1d<T>::impl_read_write(const point1d& p) { assert(this->has_data()); - return this->data_->first.operator()(p.ind()); + return this->data_->first[p.ind()]; } template <typename T> @@ -158,7 +160,14 @@ { assert(this->has_data()); assert(i < this->npoints()); - return this->data_->first.operator[](i); + return this->data_->first[i]; + } + + template <typename T> + void image1d<T>::impl_write(const point1d& p, const T& v) + { + assert(this->has_data()); + this->data_->first[p.ind()] = v; } template <typename T> Index: oln/core/1d/image1d_b.hh --- oln/core/1d/image1d_b.hh (revision 918) +++ oln/core/1d/image1d_b.hh (working copy) @@ -103,6 +103,8 @@ T& impl_read_write(const point1d& p); T& impl_index_read_write(unsigned i); + void impl_write(const point1d& p, const T& v); + std::size_t impl_npoints() const; const box1d& impl_points() const; @@ -149,7 +151,7 @@ const T& image1d_b<T>::impl_read(const point1d& p) const { assert(this->has_data()); - return this->data_->first(p.ind()); + return this->data_->first[p.ind()]; } template <typename T> @@ -164,7 +166,7 @@ T& image1d_b<T>::impl_read_write(const point1d& p) { assert(this->has_data()); - return this->data_->first(p.ind()); + return this->data_->first[p.ind()]; } template <typename T> @@ -176,6 +178,13 @@ } template <typename T> + void image1d_b<T>::impl_write(const point1d& p, const T& v) + { + assert(this->has_data()); + this->data_->first[p.ind()] = v; + } + + template <typename T> const box1d& image1d_b<T>::impl_points() const { assert(this->has_data()); Index: oln/core/1d/box1d.hh --- oln/core/1d/box1d.hh (revision 918) +++ oln/core/1d/box1d.hh (working copy) @@ -35,14 +35,13 @@ namespace oln { - // Forward declarations - struct box1d; + // Fwd decl. + class box1d; // Super type template <> struct super_trait_< box1d > { - typedef box1d current; typedef internal::box_<box1d> ret; }; @@ -57,7 +56,6 @@ // Class box1d class box1d : public internal::box_< box1d > { - typedef box1d current; typedef internal::box_< box1d > super; public: // Note: we can't use stc_using because box1d isn't a templated class Index: oln/core/1d/point1d.hh --- oln/core/1d/point1d.hh (revision 918) +++ oln/core/1d/point1d.hh (working copy) @@ -37,8 +37,8 @@ { - struct point1d; - struct dpoint1d; + class point1d; + class dpoint1d; /// Super type. Index: oln/core/2d/image2d.hh --- oln/core/2d/image2d.hh (revision 918) +++ oln/core/2d/image2d.hh (working copy) @@ -99,6 +99,8 @@ T& impl_index_read_write(unsigned i); T& impl_at(int row, int col); + void impl_write(const point2d& p, const T& v); + std::size_t impl_npoints() const; const box2d& impl_points() const; @@ -192,6 +194,13 @@ } template <typename T> + void image2d<T>::impl_write(const point2d& p, const T& v) + { + assert(this->has_data()); + this->data_->first(p.row(), p.col()) = v; + } + + template <typename T> std::size_t image2d<T>::impl_npoints() const { // faster than the default code given by primitive_image_ Index: oln/core/2d/image2d_b.hh --- oln/core/2d/image2d_b.hh (revision 918) +++ oln/core/2d/image2d_b.hh (working copy) @@ -104,6 +104,8 @@ T& impl_index_read_write(unsigned i); T& impl_at(int row, int col); + void impl_write(const point2d& p, const T& v); + std::size_t impl_npoints() const; const box2d& impl_points() const; @@ -210,6 +212,13 @@ } template <typename T> + void image2d_b<T>::impl_write(const point2d& p, const T& v) + { + assert(this->has_data()); + this->data_->first(p.row(), p.col()) = v; + } + + template <typename T> const box2d& image2d_b<T>::impl_points() const { assert(this->has_data()); Index: oln/core/2d/line2d.hh --- oln/core/2d/line2d.hh (revision 0) +++ oln/core/2d/line2d.hh (revision 0) @@ -0,0 +1,161 @@ +// 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 OLN_CORE_2D_LINE2D_HH +# define OLN_CORE_2D_LINE2D_HH + +# include <oln/core/2d/box2d.hh> +# include <oln/core/internal/pset_adaptor.hh> +# include <oln/core/gen/pvec.hh> + + +namespace oln +{ + + // FIXME: Move it! + namespace util + { + template <typename T> + int sign(const T& t) + { + if (t != 0) + return t > 0 ? 1 : -1; + else + return 0; + } + + } // end of namespace oln::util + + + + // Fwd decl. + class line2d; + + + // Super type. + template <> + struct super_trait_< line2d > + { + typedef internal::pset_adaptor_<line2d> ret; + }; + + + // Virtual types. + template <> + struct vtypes< line2d > + { + typedef pvec_<point2d> adapted; + }; + + class line2d : public internal::pset_adaptor_<line2d> + { + public: + + line2d(const point2d& begin, const point2d& end); + const point2d& begin_point() const; + const point2d& end_point() const; + + const pvec_<point2d>& pvec() const; + const std::vector<point2d>& con() const { return this->ps_.con(); } + + protected: + point2d beg_, end_; + void compute_(); // FIXME: we also need a semi_open_line (without the end point)... + }; + + +# ifndef OLN_INCLUDE_ONLY + + line2d::line2d(const point2d& begin, + const point2d& end) + : beg_(begin), + end_(end) + { + this->compute_(); + } + + const point2d& + line2d::begin_point() const + { + return this->beg_; + } + + const point2d& + line2d::end_point() const + { + return this->end_; + } + + void + line2d::compute_() + { + dpoint2d dp = this->end_ - this->beg_; + int + srow = util::sign(dp.row()), drow = std::abs(dp.row()), ddrow = 2 * drow, + scol = util::sign(dp.col()), dcol = std::abs(dp.col()), ddcol = 2 * dcol, + row = this->beg_.row(), + col = this->beg_.row(); + + if ( dcol > drow ) + { + int e = ddrow - dcol; + for (int i = 0; i < dcol; ++i) + { + this->ps_.append(point2d(row, col)); + while (e >= 0) + { + row += srow; + e -= ddcol; + } + col += scol; + e += ddrow; + } + } + else + { + int e = ddcol - drow; + for (int i = 0; i < drow; ++i) + { + this->ps_.append(point2d(row, col)); + while (e >= 0) + { + col += scol; + e -= ddrow; + } + row += srow; + e += ddcol; + } + } + this->ps_.append(point2d(row, col)); + } + +# endif // ! OLN_INCLUDE_ONLY + + +} // end of namespace oln + +#endif // ! OLN_CORE_2D_LINE2D_HH Index: oln/core/2d/box2d.hh --- oln/core/2d/box2d.hh (revision 918) +++ oln/core/2d/box2d.hh (working copy) @@ -36,14 +36,13 @@ namespace oln { - // Forward declarations - struct box2d; + // Fwd decl. + class box2d; // Super type template <> struct super_trait_< box2d > { - typedef box2d current; typedef internal::box_<box2d> ret; }; @@ -58,7 +57,6 @@ // Class box2d class box2d : public internal::box_< box2d > { - typedef box2d current; typedef internal::box_< box2d > super; public: // Note: we can't use stc_using because box2d isn't a templated class Index: oln/core/2d/point2d.hh --- oln/core/2d/point2d.hh (revision 918) +++ oln/core/2d/point2d.hh (working copy) @@ -37,8 +37,8 @@ { - struct point2d; - struct dpoint2d; + class point2d; + class dpoint2d; /// Super type. @@ -93,7 +93,7 @@ this->col() = dat->second.value; } -# endif // OLN_INCLUDE_ONLY +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/gen/pset_compare.hh --- oln/core/gen/pset_compare.hh (revision 918) +++ oln/core/gen/pset_compare.hh (working copy) @@ -90,18 +90,14 @@ } - // Point_Set L < Point_Set R - // ----------------------------- - - // Generic version. + // Point_Set L <= Point_Set R template <typename L, typename R> - bool op_less_(const Point_Set<L>& lhs, const Point_Set<R>& rhs) + bool op_leq_(const Point_Set<L>& lhs, const Point_Set<R>& rhs) { - if (lhs.npoints() >= rhs.npoints()) // quick test + if (lhs.npoints() > rhs.npoints()) // quick test return false; - // we have lhs.npoints() < rhs.npoints() - // so we shall now test that all points of lhs are IN rhs + // all points of lhs are IN rhs? oln_piter(R) p_rhs(rhs); p_rhs.start(); oln_piter(L) p_lhs(lhs); @@ -116,6 +112,19 @@ } + // Point_Set L < Point_Set R + + template <typename L, typename R> + bool op_less_(const Point_Set<L>& lhs, const Point_Set<R>& rhs) + { + return op_leq_(lhs, rhs) and lhs.npoints() < rhs.npoints(); + } + + + + + + // Box L <= Box R. Index: oln/core/gen/box.hh --- oln/core/gen/box.hh (revision 918) +++ oln/core/gen/box.hh (working copy) @@ -38,11 +38,11 @@ { - // Forward declarations. + // Fwd decl. template <typename P> class gen_box; - // Super type declaration. + // Super type. template <typename P> struct super_trait_< gen_box<P> > { @@ -51,7 +51,7 @@ }; - /// Virtual types associated to oln::gen_box<P>. + /// Virtual types. template <typename P> struct vtypes< gen_box<P> > { @@ -88,10 +88,6 @@ # ifndef OLN_INCLUDE_ONLY - - // -------------------- gen_box<P> - - template <typename P> gen_box<P>::gen_box() { @@ -118,7 +114,6 @@ # endif // !OLN_INCLUDE_ONLY - } // end of namespace oln Index: oln/core/gen/fbbox.hh --- oln/core/gen/fbbox.hh (revision 918) +++ oln/core/gen/fbbox.hh (working copy) @@ -31,6 +31,7 @@ # include <oln/core/gen/box.hh> # include <oln/core/concept/point.hh> +# include <oln/core/internal/point_set_base.hh> namespace oln @@ -48,17 +49,19 @@ public: + typedef typename f_box_from_point_<P>::ret box_t; + fbbox_(); - operator gen_box<P>() const; + operator box_t() const; bool is_valid() const; void flush(); fbbox_<P>& take(const P& p); - const gen_box<P>& box() const; + const box_t& box() const; private: bool is_valid_; - gen_box<P> b_; + box_t b_; }; // end of class oln::fbbox_<P> @@ -73,7 +76,7 @@ } template <typename P> - fbbox_<P>::operator gen_box<P>() const + fbbox_<P>::operator typename fbbox_<P>::box_t() const { precondition(this->is_valid_); return this->b_; @@ -92,7 +95,8 @@ } template <typename P> - fbbox_<P>& fbbox_<P>::take(const P& p) + fbbox_<P>& + fbbox_<P>::take(const P& p) { if (not this->is_valid_) { @@ -112,13 +116,14 @@ } template <typename P> - const gen_box<P>& fbbox_<P>::box() const + const typename fbbox_<P>::box_t& + fbbox_<P>::box() const { precondition(this->is_valid_); return this->b_; } -# endif +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/gen/single_value_image.hh --- oln/core/gen/single_value_image.hh (revision 918) +++ oln/core/gen/single_value_image.hh (working copy) @@ -146,7 +146,7 @@ this->data_->second = new_value; } -# endif // OLN_INCLUDE_ONLY +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/gen/safe_image.hh --- oln/core/gen/safe_image.hh (revision 0) +++ oln/core/gen/safe_image.hh (revision 0) @@ -0,0 +1,187 @@ +// 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 OLN_CORE_GEN_SAFE_IMAGE_HH +# define OLN_CORE_GEN_SAFE_IMAGE_HH + +# include <oln/core/internal/image_base.hh> + + +namespace oln +{ + + + // Fwd decl. + template <typename I> class safe_image; + + + /// Virtual types. + template <typename I> + struct vtypes< safe_image<I> > + { + typedef I delegatee; + typedef behavior::identity behavior; + + typedef internal::singleton<I> data; + + typedef safe_image< oln_plain(I) > plain; + typedef safe_image< pl::rec<I> > skeleton; + }; + + + /// Super type. + template <typename I> + struct super_trait_< safe_image<I> > + { + typedef safe_image<I> current; + typedef internal::single_image_morpher_<current> ret; + }; + + + /// Class for images defined by a point set and a single value. + + template <typename I> + class safe_image : public internal::single_image_morpher_< safe_image<I> > + { + typedef safe_image<I> current; + typedef internal::single_image_morpher_<current> super; + public: + + stc_using(point); + stc_using(rvalue); + stc_using(lvalue); + stc_using(value); + stc_using(data); + stc_using(delegatee); + + safe_image(); + safe_image(Mutable_Image<I>& ima); + + bool impl_owns_(const point& p) const; + + rvalue impl_read(const point& p) const; + lvalue impl_read_write(const point& p); + void impl_write(const point& p, const value& v); + + delegatee& impl_image(); + const delegatee& impl_image() const; + + }; // end of safe_image<I> + + + + template <typename I> + safe_image<I> safe(Mutable_Image<I>& ima) + { + safe_image<I> tmp(ima); + return tmp; + } + + + +# ifndef OLN_INCLUDE_ONLY + + template <typename I> + safe_image<I>::safe_image() + { + } + + template <typename I> + safe_image<I>::safe_image(Mutable_Image<I>& ima) + { + precondition(exact(ima).has_data()); + this->data_ = new data(exact(ima)); + } + + template <typename I> + bool + safe_image<I>::impl_owns_(const typename safe_image<I>::point&) const + { + assert(this->has_data()); + return true; // always! + } + + template <typename I> + typename safe_image<I>::rvalue + safe_image<I>::impl_read(const typename safe_image<I>::point& p) const + { + assert(this->has_data()); + assert(this->image().has_data()); + static oln_value(I) tmp; + if (this->image().owns_(p)) + return this->image()(p); + else + return tmp; + } + + template <typename I> + typename safe_image<I>::lvalue + safe_image<I>::impl_read_write(const typename safe_image<I>::point& p) + { + assert(this->has_data()); + assert(this->image().has_data()); + static oln_value(I) tmp; + if (this->image().owns_(p)) + return this->image()(p); + else + return tmp; + } + + template <typename I> + void + safe_image<I>::impl_write(const typename safe_image<I>::point& p, + const typename safe_image<I>::value& v) + { + assert(this->has_data()); + assert(this->image().has_data()); + static oln_value(I) tmp; + if (this->image().owns_(p)) + this->image().write_(p, v); + } + + template <typename I> + typename safe_image<I>::delegatee& + safe_image<I>::impl_image() + { + assert(this->has_data()); + return this->data_->value; + } + + template <typename I> + const typename safe_image<I>::delegatee& + safe_image<I>::impl_image() const + { + assert(this->has_data()); + return this->data_->value; + } + +# endif // ! OLN_INCLUDE_ONLY + +} // end of namespace oln + + +#endif // ! OLN_CORE_GEN_SAFE_IMAGE_HH Index: oln/core/internal/box.hh --- oln/core/internal/box.hh (revision 918) +++ oln/core/internal/box.hh (working copy) @@ -61,7 +61,9 @@ namespace internal { - /// Generic box class based on a point class. + + /// Base implementation class for box types. + template <typename Exact> class box_ : public point_set_base_< Exact > { @@ -71,7 +73,6 @@ stc_using(point); stc_using(box); - typedef internal::initializer_< internal::pair< internal::from_t<point>, internal::to_t<point> > > from_to_t; @@ -82,7 +83,6 @@ public: enum { n = mlc_value(dim__) }; - unsigned impl_npoints() const; bool impl_has(const point& p) const; const Exact& impl_bbox() const; Index: oln/core/internal/point_set_base.hh --- oln/core/internal/point_set_base.hh (revision 918) +++ oln/core/internal/point_set_base.hh (working copy) @@ -34,6 +34,28 @@ namespace oln { + // function : point -> box + + template <typename P> class gen_box; + + template <typename P> + struct f_box_from_point_ { typedef gen_box<P> ret; }; + + class point1d; + class box1d; + + template <> + struct f_box_from_point_< point1d > { typedef box1d ret; }; + + class point2d; + class box2d; + + template <> + struct f_box_from_point_< point2d > { typedef box2d ret; }; + + // FIXME: Move the code above elsewhere. + + namespace internal { Index: oln/core/internal/op_image_restricted_to_pset.hh --- oln/core/internal/op_image_restricted_to_pset.hh (revision 918) +++ oln/core/internal/op_image_restricted_to_pset.hh (working copy) @@ -79,12 +79,14 @@ public: stc_using(pset); stc_using(box); + stc_using(psite); stc_using(data); stc_using(delegatee); delegatee& impl_image(); const delegatee& impl_image() const; + bool impl_owns_(const psite& p) const; const pset& impl_points() const; protected: @@ -134,6 +136,14 @@ } template <typename I, typename S> + bool + current::impl_owns_(const typename current::psite& p) const + { + assert(this->has_data()); + return this->has(p); + } + + template <typename I, typename S> typename current::delegatee& current::impl_image() { Index: oln/core/internal/point_set_std_based.hh --- oln/core/internal/point_set_std_based.hh (revision 918) +++ oln/core/internal/point_set_std_based.hh (working copy) @@ -32,7 +32,7 @@ # include <algorithm> # include <oln/core/internal/point_set_base.hh> -# include <oln/core/concept/iterator_on_points.hh> +# include <oln/core/internal/iterator_on_points_base.hh> # include <oln/core/gen/fbbox.hh> @@ -61,9 +61,12 @@ typedef stc::abstract std_container; typedef stc_deferred(std_container) std_container__; - typedef stc::final< typename std_container__::value_type > point; + typedef typename std_container__::value_type point__; + + typedef stc::final< point__ > point; typedef stc::final< pset_std_based_fwd_piter_<std_container__> > fwd_piter; typedef stc::final< pset_std_based_bkd_piter_<std_container__> > bkd_piter; + typedef stc::final< typename f_box_from_point_<point__>::ret > box; }; @@ -173,14 +176,14 @@ struct super_trait_< pset_std_based_fwd_piter_<C> > { typedef pset_std_based_fwd_piter_<C> current__; - typedef Iterator_on_Points<current__> ret; + typedef internal::iterator_on_points_base<current__> ret; }; template <typename C> struct super_trait_< pset_std_based_bkd_piter_<C> > { typedef pset_std_based_bkd_piter_<C> current__; - typedef Iterator_on_Points<current__> ret; + typedef internal::iterator_on_points_base<current__> ret; }; @@ -203,16 +206,16 @@ // Class pset_std_based_fwd_piter_<C>. template <typename C> - class pset_std_based_fwd_piter_ : public Iterator_on_Points< pset_std_based_fwd_piter_<C> > + class pset_std_based_fwd_piter_ : public internal::iterator_on_points_base< pset_std_based_fwd_piter_<C> > { typedef pset_std_based_fwd_piter_<C> current; - typedef Iterator_on_Points<current> super; + typedef internal::iterator_on_points_base<current> super; public: stc_using(point); template <typename Ps> - pset_std_based_fwd_piter_(const internal::point_set_std_based_<Ps>& con); + pset_std_based_fwd_piter_(const Point_Set<Ps>& pset); void impl_start(); void impl_next(); @@ -232,16 +235,16 @@ // Class pset_std_based_bkd_piter_<C>. template <typename C> - class pset_std_based_bkd_piter_ : public Iterator_on_Points< pset_std_based_bkd_piter_<C> > + class pset_std_based_bkd_piter_ : public internal::iterator_on_points_base< pset_std_based_bkd_piter_<C> > { typedef pset_std_based_bkd_piter_<C> current; - typedef Iterator_on_Points<current> super; + typedef internal::iterator_on_points_base<current> super; public: stc_using(point); template <typename Ps> - pset_std_based_bkd_piter_(const internal::point_set_std_based_<Ps>& pts); + pset_std_based_bkd_piter_(const Point_Set<Ps>& pts); void impl_start(); void impl_next(); @@ -268,8 +271,8 @@ template <typename C> template <typename Ps> - pset_std_based_fwd_piter_<C>::pset_std_based_fwd_piter_(const internal::point_set_std_based_<Ps>& pts) - : con_(pts.con()) + pset_std_based_fwd_piter_<C>::pset_std_based_fwd_piter_(const Point_Set<Ps>& pts) + : con_(exact(pts).con()) { this->it_ = this->con_.end(); } @@ -325,8 +328,8 @@ template <typename C> template <typename Ps> - pset_std_based_bkd_piter_<C>::pset_std_based_bkd_piter_(const internal::point_set_std_based_<Ps>& pts) - : con_(pts.con()) + pset_std_based_bkd_piter_<C>::pset_std_based_bkd_piter_(const Point_Set<Ps>& pts) + : con_(exact(pts).con()) { this->it_ = this->con_.rend(); } Index: oln/core/internal/image_base.hh --- oln/core/internal/image_base.hh (revision 918) +++ oln/core/internal/image_base.hh (working copy) @@ -506,6 +506,17 @@ return tmp; } + template <typename I, typename B, typename P> + op_<I, such_as, const fun_p2b_<B (*)(P)> > + operator | (Image<I>& ima, B (*f)(P)) + { + typedef oln_strip_(P) P_; + mlc::assert_< mlc_is_a(P_, Point) >::check(); // FIXME: Add err msg. + mlc::assert_equal_< P_, oln_point(I) >::check(); + op_<I, such_as, const fun_p2b_<B (*)(P)> > tmp(exact(ima), f); + return tmp; + } + // Specialization "Image such_as ima : P -> B". @@ -519,6 +530,16 @@ return tmp; } + template <typename I, typename J> + op_<I, such_as, const fun_p2b_< Binary_Image<J> > > + operator | (Image<I>& ima, const Binary_Image<J>& f_ima_b) + { + precondition(f_ima_b.points() >= ima.points()); + mlc::assert_equal_< oln_point(I), oln_point(J) >::check(); + op_<I, such_as, const fun_p2b_< Binary_Image<J> > > tmp(exact(ima), f_ima_b); + return tmp; + } + // FIXME: What about Mutable_Image so that "ima | something" can be left-value? Index: oln/core/internal/pset_adaptor.hh --- oln/core/internal/pset_adaptor.hh (revision 0) +++ oln/core/internal/pset_adaptor.hh (revision 0) @@ -0,0 +1,135 @@ +// 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 OLN_CORE_INTERNAL_PSET_ADAPTOR_HH +# define OLN_CORE_INTERNAL_PSET_ADAPTOR_HH + +# include <oln/core/internal/point_set_base.hh> + + +namespace oln +{ + + + // Fwd decl. + namespace internal { template <typename Exact> class pset_adaptor_; } + + + // Super type. + template <typename Exact> + struct super_trait_< internal::pset_adaptor_<Exact> > + { + typedef internal::point_set_base_<Exact> ret; + }; + + + // Virtual types. + template <typename Exact> + struct vtypes< internal::pset_adaptor_<Exact> > + { + typedef stc::abstract adapted; + + typedef stc_deferred(adapted) adapted__; + typedef stc::final< oln_point(adapted__) > point; + typedef stc::final< oln_fwd_piter(adapted__) > fwd_piter; + typedef stc::final< oln_bkd_piter(adapted__) > bkd_piter; + typedef stc::final< oln_box(adapted__) > box; + }; + + + namespace internal + { + + // Base implementation class for types of iterator on points + // defined over other types of iterator on points. + + template <typename Exact> + class pset_adaptor_ : public internal::point_set_base_<Exact> + { + typedef internal::point_set_base_<Exact> super; + public: + stc_typename(adapted); + + stc_using(point); + stc_using(box); + + unsigned impl_npoints() const; + bool impl_has(const point& p) const; + const box& impl_bbox() const; + + protected: + adapted ps_; + pset_adaptor_(); + pset_adaptor_(const adapted& ps); + + }; // end of class oln::internal::pset_adaptor_<Exact> + + + +# ifndef OLN_INCLUDE_ONLY + + template <typename Exact> + pset_adaptor_<Exact>::pset_adaptor_() + : ps_() + { + } + + template <typename Exact> + pset_adaptor_<Exact>::pset_adaptor_(const adapted& ps) + : ps_(ps) + { + } + + template <typename Exact> + unsigned + pset_adaptor_<Exact>::impl_npoints() const + { + return this->ps_.npoints(); + } + + template <typename Exact> + bool + pset_adaptor_<Exact>::impl_has(const typename pset_adaptor_<Exact>::point& p) const + { + return this->ps_.has(p); + } + + template <typename Exact> + const typename pset_adaptor_<Exact>::box& + pset_adaptor_<Exact>::impl_bbox() const + { + return this->ps_.bbox(); + } + +# endif // ! OLN_INCLUDE_ONLY + + } // end of namespace oln::internal + +} // end of namespace oln + + +#endif // ! OLN_CORE_INTERNAL_PSET_ADAPTOR_HH Index: oln/core/internal/iterator_on_points_base.hh --- oln/core/internal/iterator_on_points_base.hh (revision 918) +++ oln/core/internal/iterator_on_points_base.hh (working copy) @@ -40,7 +40,7 @@ namespace internal { template <typename Exact> - struct iterator_on_points_base; + struct iterator_on_points_base; // FIXME: End with '_'! } // Super type Index: oln/draw/bresenham.hh --- oln/draw/bresenham.hh (revision 0) +++ oln/draw/bresenham.hh (revision 0) @@ -0,0 +1,87 @@ +// 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 OLN_DRAW_BRESENHAM_HH +# define OLN_DRAW_BRESENHAM_HH + +# include <oln/core/concept/image.hh> +# include <oln/core/gen/safe_image.hh> +# include <oln/core/2d/line2d.hh> + + + +namespace oln +{ + + namespace draw + { + + // Fwd decl. + + template <typename I> + void bresenham(Mutable_Image<I>& input, + const oln_point(I)& begin, const oln_point(I)& end, + const oln_value(I)& value); + + +# ifndef OLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I> + void bresenham_(Mutable_Image<I>& input, + const oln_point(I)& begin, const oln_point(I)& end, + const oln_value(I)& value) + { + line2d l(begin, end); + safe_image<I> input_(input); + typename line2d::piter p(l); // FIXME: Generalize with an 'assign' routine... + for_all(p) + input_(p) = value; + } + + } // end of namespace oln::draw::impl + + // Facade. + + template <typename I> + void bresenham(Mutable_Image<I>& input, + const oln_point(I)& begin, const oln_point(I)& end, + const oln_value(I)& value) + { + impl::bresenham_(exact(input), begin, end, value); + } + +# endif // ! OLN_INCLUDE_ONLY + + } // end of namespace oln::draw + +} // end of namespace oln + + +#endif // ! OLN_DRAW_BRESENHAM_HH Index: oln/value/builtin.hh --- oln/value/builtin.hh (revision 918) +++ oln/value/builtin.hh (working copy) @@ -44,7 +44,7 @@ template <typename Exact> struct vtypes< internal::builtin_base<Exact> > { - typedef stc::final< stc:is<Value> > category; + typedef stc::final< stc::is<Value> > category; }; @@ -59,11 +59,21 @@ builtin_base(); }; + +# ifndef OLN_INCLUDE_ONLY + + template <typename Exact> + builtin_base<Exact>::builtin_base() + { + } + +# endif // ! OLN_INCLUDE_ONLY + } // end of namespace oln::internal - // int + // int, float, ... template <> struct super_trait_< int > @@ -90,6 +100,8 @@ typedef float ret; }; + // FIXME: To be continued... + } // end of namespace oln