889: Fix mini-oln, add mutable image type and rgb value.

Index: ChangeLog from Alexandre Abraham <abraham@lrde.epita.fr> Fix mini-oln, add mutable image type and rgb value. * samples/mini-oln/mini-oln.cc, samples/mini-oln/concept-c++/mini-oln.cc : code for image3d tests, new lvalue_t and rvalue_t vtypes for mutable images. * samples/mini-oln/mini-oln.cc, (oln::Image::rvalue_t) : New typedef. (oln::Image) : operator() now return a rvalue_t as it is a read only Image by default (oln::Image2d), (oln::Image3d) : operator() is now inherited from oln::Image. (oln::Mutable_Image) : New. (oln::Mutable_Image::lvalue) : New typedef. (oln::switch_image_base_mutable) : New. (oln::image2d) : split impl_op_parens into two versions returning rvalue_t and lvalue_t. (oln::rgb) : new type. (oln::Iterator3d) : New. (oln::niter3d) : New. (oln::Image3d) : New. * samples/mini-oln/concept-c++/mini-oln.cc: (oln::concepts::Image::rvalue_t) : New typedef. (oln::concetps::Image) : operator() now return a rvalue_t as it is a read only Image by default (oln::concepts::Mutable_Image) : New. (oln::concetps::Mutable_Image::lvalue) : New typedef. (oln::image_mutability_switch) : New. (oln::image2d) : split impl_op_parens into two versions returning rvalue_t and lvalue_t. (oln::Iterator3d) : New. (oln::niter3d) : New. (oln::Image3d) : New. concept-c++/mini-oln.cc | 292 +++++++++++++++++++++++++++++++++-------- mini-oln.cc | 339 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 538 insertions(+), 93 deletions(-) Index: samples/mini-oln/mini-oln.cc --- samples/mini-oln/mini-oln.cc (revision 888) +++ samples/mini-oln/mini-oln.cc (working copy) @@ -33,7 +33,7 @@ #include <mlc/case.hh> #include <stc/any.hh> #include <stc/scoop.hh> - +#include <iostream> /*-------------. | Equipement. | @@ -47,7 +47,7 @@ typename oln_type_of_(FromType, Alias) // Add equipment -stc_scoop_equipment_for_namespace(oln); +stc_scoop_equipment_for_namespace(oln) mlc_case_equipment_for_namespace(oln); // Virtual types declaration. @@ -56,6 +56,8 @@ mlc_decl_typedef(point_type); mlc_decl_typedef(iter_type); mlc_decl_typedef(value_type); + mlc_decl_typedef(rvalue_type); + mlc_decl_typedef(lvalue_type); mlc_decl_typedef(nbh_type); mlc_decl_typedef(niter_type); @@ -118,9 +120,9 @@ struct Image : public stc::any<E> { typedef oln_type_of(E, point) point_t; - typedef oln_type_of(E, value) value_t; + typedef oln_type_of(E, rvalue) rvalue_t; - value_t& operator ()(point_t& p) + rvalue_t operator ()(point_t& p) const { return this->exact().impl_op_parens(p); } @@ -137,16 +139,18 @@ // --------- // template <typename E> - struct Image2d : public Image<E> + struct Image2d : public virtual Image<E> { typedef oln_type_of(E, point) point_t; - typedef oln_type_of(E, value) value_t; - // FIXME: delete? - value_t& operator ()(point_t& p) - { - return this->exact().impl_op_parens(p); - } + // inherited from Image + + // typedef oln_type_of(E, rvalue) rvalue_t; + + // rvalue_t& operator ()(point_t& p) + // { + // return this->exact().impl_op_parens(p); + // } int nrows_get() const { @@ -165,16 +169,18 @@ // --------- // template <typename E> - struct Image3d : public Image<E> + struct Image3d : public virtual Image<E> { typedef oln_type_of(E, point) point_t; - typedef oln_type_of(E, value) value_t; - // FIXME: delete? - value_t& operator ()(point_t& p) - { - return this->exact().impl_op_parens(p); - } + // inherited from Image + + // typedef oln_type_of(E, rvalue) rvalue_t; + + // rvalue_t& operator ()(point_t& p) + // { + // return this->exact().impl_op_parens(p); + // } int nrows_get() const { @@ -193,12 +199,29 @@ }; + // ------------- // + // Mutable_Image // + // ------------- // + + template <typename E> + struct Mutable_Image : public virtual Image<E> + { + typedef oln_type_of(E, point) point_t; + typedef oln_type_of(E, lvalue) lvalue_t; + + lvalue_t operator ()(point_t& p) + { + return this->exact().impl_op_parens(p); + } + }; + + // ------------------------- // // Image_with_neighborhood. // // ------------------------- // template <typename E> - struct Image_with_neighborhood : public Image<E> + struct Image_with_neighborhood : public virtual Image<E> { typedef oln_type_of(E, nbh) nbh_t; typedef oln_type_of(E, niter) niter_t; @@ -249,6 +272,25 @@ typedef Image<E> ret; }; + // ----------------- // + // Mutability Switch // + // ----------------- // + + // Tag. + struct switch_image_base_mutable; + + template <typename E> + struct case_<switch_image_base_mutable, E, 1> : + public mlc::where_ < mlc::is_found_< stc_vtype(oln, E, lvalue) > > + { + typedef Mutable_Image<E> ret; + }; + + template <typename E> + struct default_case_<switch_image_base_mutable, E> + { + typedef Image<E> ret; + }; // ------------ // // Image base. // @@ -269,13 +311,16 @@ typedef stc::abstract point_type; typedef stc::abstract iter_type; typedef stc::abstract value_type; + typedef stc::abstract rvalue_type; + typedef stc::abstract lvalue_type; typedef mlc::none niter_type; typedef mlc::none nbh_type; }; template <typename E> - struct image_base : public switch_<switch_image_base, E>::ret + struct image_base : public virtual switch_<switch_image_base, E>::ret, + public virtual switch_<switch_image_base_mutable, E>::ret { image_base() { @@ -362,7 +407,7 @@ return p.row < nrows; } - point_t& impl_op_point_type() + point_t impl_op_point_type() const { return p; } @@ -393,6 +438,8 @@ typedef point2d point_type; typedef iterator2d iter_type; typedef T value_type; + typedef value_type rvalue_type; + typedef value_type& lvalue_type; }; template <typename T> @@ -402,18 +449,24 @@ typedef oln_type_of(self_t, point) point_t; typedef oln_type_of(self_t, iter) iter_t; typedef oln_type_of(self_t, value) value_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, lvalue) lvalue_t; image2d(int nrows, int ncols) : - data (0), nrows (nrows), - ncols (ncols) + ncols (ncols), + data (nrows * ncols) { - data = new std::vector<value_t>; } - value_t& impl_op_parens(const point_t& p) + rvalue_t impl_op_parens(const point_t& p) const { - return this->data[p.row * nrows + p.col]; + return this->data[p.row * ncols + p.col]; + } + + lvalue_t impl_op_parens(const point_t& p) + { + return this->data[p.row * ncols + p.col]; } int impl_nrows_get() const @@ -433,12 +486,11 @@ } protected: - std::vector<value_t>* data; int nrows; int ncols; + std::vector<value_t> data; }; - // ----------------- // // Neighborhood 2d. // // ----------------- // @@ -451,6 +503,172 @@ }; + // ------------- // + // Iterator 3d. // + // ------------- // + + // Forward declarations. + struct iterator3d; + template <typename T> struct image3d; + + template<> + struct set_super_type<iterator3d> + { + typedef mlc::none ret; + }; + + template <> + struct vtypes<iterator3d> + { + typedef point3d point_type; + }; + + struct iterator3d : public Iterator<iterator3d> + { + typedef oln_type_of_(iterator3d, point) point_t; + + template <typename T> + iterator3d(image3d<T>& ima) : + nrows (ima.nrows_get()), + ncols (ima.ncols_get()), + nslis (ima.nslis_get()) + { + } + + void impl_start() + { + p.row = 0; + p.col = 0; + p.sli = 0; + } + + void impl_next() + { + p.sli = p.sli + 1; + + if (p.sli == nslis) + { + p.sli = 0; + p.col = p.col + 1; + } + + if (p.col == ncols) + { + p.col = 0; + p.row = p.row + 1; + } + } + + bool impl_is_valid() const + { + return p.row < nrows; + } + + point_t impl_op_point_type() const + { + return p; + } + + protected: + int nrows; + int ncols; + int nslis; + point_t p; + }; + + // ---------- // + // Image 3d. // + // ---------- // + + // Forward declaration. + template <typename T> struct image3d; + + template<typename T> + struct set_super_type< image3d<T> > + { + typedef image_base< image3d<T> > ret; + }; + + template <typename T> + struct vtypes< image3d<T> > + { + typedef point3d point_type; + typedef iterator3d iter_type; + typedef T value_type; + typedef value_type rvalue_type; + typedef value_type& lvalue_type; + }; + + template <typename T> + struct image3d : public image_base< image3d<T> > + { + typedef image3d<T> self_t; + typedef oln_type_of(self_t, point) point_t; + typedef oln_type_of(self_t, iter) iter_t; + typedef oln_type_of(self_t, value) value_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, lvalue) lvalue_t; + + image3d(int nrows, int ncols, int nslis) : + nrows (nrows), + ncols (ncols), + nslis (nslis), + data (nrows * ncols * nslis) + { + } + + rvalue_t impl_op_parens(const point_t& p) const + { + return this->data[p.row * ncols * nslis + p.col * nslis + p.sli]; + } + + lvalue_t impl_op_parens(const point_t& p) + { + return this->data[p.row * ncols * nslis + p.col * nslis + p.sli]; + } + + int impl_nrows_get() const + { + return nrows; + } + + int impl_ncols_get() const + { + return ncols; + } + + int nslis_get() const + { + return nslis; + } + + bool impl_has(point_t& p) const + { + assert(!!data); + return p.row >= 0 && p.row < nrows && p.col >= 0 && p.col < ncols + && p.sli >= 0 && p.sli < nslis; + } + + protected: + int nrows; + int ncols; + int nslis; + std::vector<value_t> data; + }; + + + // ----------------- // + // Neighborhood 3d. // + // ----------------- // + + struct niter3d {}; + + struct neighborhood3d + { + typedef niter3d niter_type; + }; + + // --------------- // // Image morpher. // // --------------- // @@ -542,8 +760,32 @@ return res; } + template <typename T> + struct rgb + { + public: + rgb () : data_(3) {} + T& r_get() { return data_[0]; } + T& g_get() { return data_[1]; } + T& b_get() { return data_[2]; } + T r_get() const { return data_[0]; } + T g_get() const { return data_[1]; } + T b_get() const { return data_[2]; } + T& operator[] (int i) { assert(i >= 0 && i < 3); return data_[i]; } + T operator[] (int i) const { assert(i >= 0 && i < 3); return data_[i]; } + + private: + std::vector<T> data_; + }; + } // End of namespace oln. +/*-----------------. +| Useful Typedefs | +`-----------------*/ + +//template <typename T> +//typedef image2d< rgb<T> > image2d_rgb<T>; /*--------------. | Client code. | @@ -554,24 +796,47 @@ using namespace oln; point2d p; - typedef image2d<int> ima_t; - ima_t ima1(10, 10); + typedef image2d<int> ima_2D_t; + ima_2D_t ima1(10, 10); - iterator2d it(ima1); + iterator2d it_2D(ima1); - typedef neighborhood2d nbh_t; + typedef neighborhood2d nbh_2D_t; // A type of image with neighborhood2d. - typedef plus<ima_t, nbh_t> ima_wih_nbh_t; - neighborhood2d nbh; - ima_wih_nbh_t ima2(ima1, nbh); + typedef plus<ima_2D_t, nbh_2D_t> ima_wih_nbh_2D_t; + neighborhood2d nbh_2D; + ima_wih_nbh_2D_t ima2(ima1, nbh_2D); // Another way to build an image with neigborhood. - ima_wih_nbh_t ima3 = ima1 + nbh; + ima_wih_nbh_2D_t ima3 = ima1 + nbh_2D; - // FIXME: Same with 3d. + // Same with 3d. point3d q; + typedef image3d<int> ima_3D_t; + ima_3D_t ima1_3D(2, 2, 2); + + iterator3d it_3D(ima1_3D); + + typedef neighborhood3d nbh_3D_t; + + // A type of image with neighborhood3d. + typedef plus<ima_3D_t, nbh_3D_t> ima_wih_nbh_3D_t; + neighborhood3d nbh_3D; + ima_wih_nbh_3D_t ima2_3D(ima1_3D, nbh_3D); + // Another way to build an image with neigborhood. + ima_wih_nbh_3D_t ima3_3D = ima1_3D + nbh_3D; + + std::cout << "Show a 3D Image" << std::endl; + for (it_3D.start(); it_3D.is_valid(); it_3D.next()) + { + point3d runner = it_3D; + std::cout << "[" << runner.row << ", " << runner.col << ", " << runner.sli << "] " << ima1_3D(runner) << std::endl; + } // ... + + rgb<int> tst; + std::cout << tst.r_get(); } Index: samples/mini-oln/concept-c++/mini-oln.cc --- samples/mini-oln/concept-c++/mini-oln.cc (revision 888) +++ samples/mini-oln/concept-c++/mini-oln.cc (working copy) @@ -49,7 +49,7 @@ typename oln_type_of_(FromType, Alias) // Add equipment -stc_scoop_equipment_for_namespace(oln); +stc_scoop_equipment_for_namespace(oln) mlc_case_equipment_for_namespace(oln); // Virtual types declaration. @@ -58,6 +58,8 @@ mlc_decl_typedef(point_type); mlc_decl_typedef(iter_type); mlc_decl_typedef(value_type); + mlc_decl_typedef(rvalue_type); + mlc_decl_typedef(lvalue_type); mlc_decl_typedef(nbh_type); mlc_decl_typedef(niter_type); @@ -73,37 +75,20 @@ namespace concepts { - // These concepts are not automatic (i.e., prefixed with `auto'), - // since we cannot rely on type signatures for them. For instance, - // using only structural conformance, oln::point3d could be a model - // of concepts::Point2d! - concept Point2d<typename P> + auto concept Point<typename I> { typename coord_type; - // For simplicity purpose, the canonical model of - // concepts::Point2d -- oln::point2d -- does not expose its - // interface through methods (that's bad OO software engineering - // practice, but hey, we're just prototyping here). Therefore we - // cannot express sigatures on row and col accesses, since C++0x - // concepts forbid attribute (member) signatures. - }; - - concept Point3d<typename P> - { - typename coord_type; - // Same remark as above for concepts::Point2d regarding member - // signatures. }; auto concept Image<typename I> { typename point_t; typename iter_t; - typename value_t; + typename rvalue_t; // ConceptGCC doesn't support operator signatures yet. #if 0 - value_t& I::operator ()(point_t&); + rvalue_t I::operator ()(point_t&) const; #endif bool I::has(const point_t&) const; }; @@ -121,6 +106,16 @@ int I::nslis_get() const; }; + auto concept Mutable_Image<typename I> : Image<I> + { + typename lvalue_t; + + // ConceptGCC doesn't support operator signatures yet. +#if 0 + lvalue_t I::operator ()(point_t&); +#endif + }; + } // End of namespace oln::concepts. } // End of namespace oln. @@ -182,9 +177,9 @@ struct Image : public stc::any<E> { typedef oln_type_of(E, point) point_t; - typedef oln_type_of(E, value) value_t; + typedef oln_type_of(E, rvalue) rvalue_t; - value_t& operator ()(point_t& p) + rvalue_t operator ()(point_t& p) const { return this->exact().impl_op_parens(p); } @@ -204,13 +199,6 @@ struct Image2d : public Image<E> { typedef oln_type_of(E, point) point_t; - typedef oln_type_of(E, value) value_t; - - // FIXME: delete? - value_t& operator ()(point_t& p) - { - return this->exact().impl_op_parens(p); - } int nrows_get() const { @@ -234,12 +222,6 @@ typedef oln_type_of(E, point) point_t; typedef oln_type_of(E, value) value_t; - // FIXME: delete? - value_t& operator ()(point_t& p) - { - return this->exact().impl_op_parens(p); - } - int nrows_get() const { return this->exact().impl_nrows_get(); @@ -273,6 +255,22 @@ } }; + // ------------- // + // Mutable_Image // + // ------------- // + + template <typename E> + struct Mutable_image : public Image<E> + { + typedef oln_type_of(E, lvalue) lvalue_t; + typedef oln_type_of(E, point) point_t; + + lvalue_t operator ()(point_t& p) + { + return this->exact().impl_op_parens(p); + } + }; + } // End of namespace oln. @@ -301,7 +299,7 @@ // Concept-based overloading for Image2d. template <typename E> - requires concepts::Point2d< oln_type_of(E, point) > + requires concepts::Point< oln_type_of(E, point) > struct image_dimension_switch<E> : public oln::Image2d<E> { public: @@ -315,7 +313,7 @@ // Concept-based overloading for Image3d. template <typename E> - requires concepts::Point3d< oln_type_of(E, point) > + requires concepts::Point< oln_type_of(E, point) > struct image_dimension_switch<E> : public oln::Image3d<E> { public: @@ -327,6 +325,26 @@ } }; + // ----------------- // + // Mutability Switch // + // ----------------- // + + // Forward Declaration + template <typename E> struct image_mutability_switch; + + template <typename E> + requires concepts::Mutable_Image<E> + struct image_mutability_switch : public oln::Mutable_Image<E> + { + public: + image_dimension_switch() + { + std::cout << "image_mutability_switch<E> " + << "requires oln::concepts::Mutable_Image<E>" + << std::endl; + } + }; + // ------------ // // Image base. // @@ -388,21 +406,6 @@ coord_type sli; }; - // Explicitly map point2d and point3d to their concepts. - namespace concepts - { - concept_map Point2d<oln::point2d> - { - typedef oln::point2d::coord_type coord_type; - }; - - concept_map Point3d<oln::point3d> - { - typedef oln::point2d::coord_type coord_type; - }; - - } // End of namespace oln::concepts - // ------------- // // Iterator 2d. // @@ -488,6 +491,8 @@ typedef point2d point_type; typedef iterator2d iter_type; typedef T value_type; + typedef T rvalue_type; + typedef T& lvalue_type; }; template <typename T> @@ -497,16 +502,23 @@ typedef oln_type_of(self_t, point) point_t; typedef oln_type_of(self_t, iter) iter_t; typedef oln_type_of(self_t, value) value_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, lvalue) lvalue_t; image2d(int nrows, int ncols) : data (0), nrows (nrows), ncols (ncols) { - data = new std::vector<value_t>; + data = new value_t[nrows * ncols]; } - value_t& impl_op_parens(const point_t& p) + rvalue_t impl_op_parens(const point_t& p) const + { + return this->data[p.row * nrows + p.col]; + } + + lvalue_t impl_op_parens(const point_t& p) { return this->data[p.row * nrows + p.col]; } @@ -528,7 +540,7 @@ } protected: - std::vector<value_t>* data; + value_t* data; int nrows; int ncols; }; @@ -546,6 +558,174 @@ }; + // ------------- // + // Iterator 3d. // + // ------------- // + + // Forward declarations. + struct iterator3d; + template <typename T> struct image3d; + + template<> + struct set_super_type<iterator3d> + { + typedef mlc::none ret; + }; + + template <> + struct vtypes<iterator3d> + { + typedef point3d point_type; + }; + + struct iterator3d : public Iterator<iterator3d> + { + typedef oln_type_of_(iterator2d, point) point_t; + + template <typename T> + iterator3d(image3d<T>& ima) : + nrows (ima.nrows_get()), + ncols (ima.ncols_get()). + nslis (ima.nslis_get()) + { + } + + void impl_start() + { + p.row = 0; + p.col = 0; + p.sli = 0; + } + + void impl_next() + { + p.sli = p.sli + 1; + + if (p.sli == nslis) + { + p.sli = 0; + p.col = p.col + 1; + } + + if (p.col == ncols) + { + p.col = 0; + p.row = p.row + 1; + } + } + + bool impl_is_valid() const + { + return p.row < nrows; + } + + point_t& impl_op_point_type() + { + return p; + } + + protected: + int nrows; + int ncols; + int nslis; + point_t p; + }; + + + // ---------- // + // Image 3d. // + // ---------- // + + // Forward declaration. + template <typename T> struct image3d; + + template<typename T> + struct set_super_type< image3d<T> > + { + typedef image_base< image3d<T> > ret; + }; + + template <typename T> + struct vtypes< image3d<T> > + { + typedef point3d point_type; + typedef iterator3d iter_type; + typedef T value_type; + typedef T rvalue_type; + typedef T& lvalue_type; + }; + + template <typename T> + struct image3d : public image_base< image3d<T> > + { + typedef image2d<T> self_t; + typedef oln_type_of(self_t, point) point_t; + typedef oln_type_of(self_t, iter) iter_t; + typedef oln_type_of(self_t, value) value_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, lvalue) lvalue_t; + + image3d(int nrows, int ncols, int nslis) : + data (0), + nrows (nrows), + ncols (ncols), + nslis (nslis) + { + data = new value_t[nrows * ncols * nslis]; + } + + rvalue_t impl_op_parens(const point_t& p) const + { + return this->data[p.row * ncols * nslis + p.col * nslis + p.sli]; + } + + lvalue_t impl_op_parens(const point_t& p) + { + return this->data[p.row * ncols * nslis + p.col * nslis + p.sli]; + } + + int impl_nrows_get() const + { + return nrows; + } + + int impl_ncols_get() const + { + return ncols; + } + + int impl_nslis_get() const + { + return nslis; + } + + bool impl_has(point_t& p) const + { + assert(!!data); + return p.row >= 0 && p.row < nrows && p.col >= 0 && p.col < ncols + && p.sli >= 0 && p.sli < nslis; + } + + protected: + value_t* data; + int nrows; + int ncols; + int nslis; + }; + + + // ----------------- // + // Neighborhood 3d. // + // ----------------- // + + struct niter3d {}; + + struct neighborhood3d + { + typedef niter3d niter_type; + }; + + // --------------- // // Image morpher. // // --------------- //
participants (1)
-
Alexandre Abraham