Thomas Moulard <thomas.moulard@lrde.epita.fr> writes:
URL: https://svn.lrde.epita.fr/svn/oln/trunk/static
ChangeLog: 2007-01-26 Thomas Moulard <thomas.moulard@lrde.epita.fr>
Add mini-oln. * samples/mini-oln/README: Add mini-oln. New. * samples/mini-oln/mini-oln.cc: Idem. New. * samples/mini-oln: Idem. New. * samples: Idem. New.
README | 1 mini-oln.cc | 539 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 540 insertions(+)
Index: samples/mini-oln/mini-oln.cc =================================================================== --- samples/mini-oln/mini-oln.cc (revision 0) +++ samples/mini-oln/mini-oln.cc (revision 0) @@ -0,0 +1,539 @@ +// 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. + +#include <vector> + +#include <mlc/case.hh> +#include <stc/any.hh> +#include <stc/scoop.hh> + + +// Helper macros. +#define oln_type_of_(FromType, Alias) \ + oln::find_vtype<FromType, oln::typedef_:: Alias##_type>::ret + +#define oln_type_of(FromType, Alias) \ + typename oln_type_of_(FromType, Alias) + +// Add equipment +stc_scoop_equipment_for_namespace(oln); +mlc_case_equipment_for_namespace(oln); + +
+// Point +template <typename E> +struct Point : public stc::any<E> +{ +}; + +struct point2d : public Point<point2d> +{ + int row; + int col; +}; + +struct point3d : public Point<point2d> +{ + int row; + int col; + int sli; +};
Point is an abstraction, whereas point2d and point3d are concrete classes. The former is located in the upper area of the class diagram (above `entry'), the latter are located in the lower area of the class diagram (below `entry). I think its better to group abstractions on the one hand, and concrete classes on the other hand.
+// Iterator +template <typename E> +struct Iterator; + +namespace oln +{ + mlc_decl_typedef(point_type); + + template <typename E> + struct vtypes<Iterator<E> > + { + typedef mlc::undefined point_type; + }; +};
Prefer `stc::abstract' to `mlc::undefined', since it enforces the virtual type checking.
+template <typename E> +struct Iterator : public stc::any<E> +{ + typedef oln_type_of(Iterator, point) point_t; + + void start() + { + this->exact().start(); + } + + void next() + { + this->exact().next(); + } + + bool is_valid() const + { + this->exact().is_valid(); + }; + + // auto + operator point_t() + { + return this->exact().operator point_t(); + } +};
Both the class and it vtypes should be members of `oln::'. This holds for the rest of the file.
+// Image +template <typename E> +struct Image; + +namespace oln +{ + mlc_decl_typedef(iter_type); + mlc_decl_typedef(value_type); + + template <typename E> + struct vtypes<Image<E> > + { + typedef mlc::undefined point_type; + typedef mlc::undefined iter_type; + typedef mlc::undefined value_type; + }; +}; + +template <typename E> +struct Image : public stc::any<E> +{ + typedef oln_type_of(Image, point) point_t; + typedef oln_type_of(Image, iter) iter_t; + typedef oln_type_of(Image, value) value_t; + + value_t& operator ()(point_t& p) + { + return this->exact().operator ()(p); + } + + bool has(const point_t& p) const + { + this->exact().has(p); + } + +}; + +namespace oln +{ + struct Image2d; + + template<> + struct set_super_type<Image2d> + { + typedef Image<Image2d> ret; + }; +}; + +struct Image2d : public Image<Image2d> +{ + typedef oln_type_of_(Image2d, point) point_t; + typedef oln_type_of_(Image2d, iter) iter_t; + typedef oln_type_of_(Image2d, value) value_t; + + value_t& operator ()(point_t& p) + { + return this->exact().operator ()(p); + } + + int nrows_get() const + { + this->exact().nrows_get(); + } + + int ncols_get() const + { + this->exact().ncols_get(); + } +};
There are several mistakes here : - Image2d should be templated with the exact type of the image, and propagate it to its super class, i.e.: namespace oln { template<typename Exact> struct Image2d : public Image<Exact> { // ... }; } - don't specialize `set_super_type' for abstractions, as the virtual type look-up mechanism is performed on the lower part of the class diagram (bottom-up until `entry' is reached); - everything should be in `oln::'; - there should no semicolon at the end of the namespace. :)
+namespace oln +{ + struct Image3d; + + template<> + struct set_super_type<Image3d> + { + typedef Image<Image3d> ret; + }; +}; + +struct Image3d : public Image<Image3d> +{ + typedef oln_type_of_(Image3d, point) point_t; + typedef oln_type_of_(Image3d, iter) iter_t; + typedef oln_type_of_(Image3d, value) value_t; + + value_t& operator ()(point_t& p) + { + return this->exact().operator ()(p); + } + + int nrows_get() const + { + this->exact().nrows_get(); + } + + int ncols_get() const + { + this->exact().ncols_get(); + } + + int nslis_get() const + { + this->exact().nslis_get(); + } +};
Likewise for Image3d...
+// Image with neighborhood +struct image_with_nbh; + +namespace oln +{ + mlc_decl_typedef(niter_type); + mlc_decl_typedef(nbh_type); + + template<> + struct set_super_type<image_with_nbh> + { + typedef Image<image_with_nbh> ret; + }; + + template <> + struct vtypes<image_with_nbh> + { + typedef mlc::undefined niter_type; + typedef mlc::undefined nbh_type; + }; +}; + +struct image_with_nbh : public Image<image_with_nbh> +{ + typedef oln_type_of_(image_with_nbh, niter) niter_t; + typedef oln_type_of_(image_with_nbh, nbh) nbh_t; + + nbh_t nbh() const + { + //FIXME + } +};
...and image_with_nbh. And I suggest sticking to the convention stating that capitalized class names are reserved for abstractions, which is the case for image_with_nbh. [...]
+// Iterator 2d +struct iterator2d; + +template <typename T> +struct image2d; + +namespace oln +{ + template<> + struct set_super_type<iterator2d> + { + typedef Iterator<iterator2d> ret; + };
This specialization of set_super_type is useless (an abstraction should not appear explicitly as a base class of an implementation class). [...]
+// image2d +template <typename T> +struct image2d; + +namespace oln +{ + template<typename T> + struct set_super_type<image2d<T> > + { + typedef image_base<image2d<T> > ret; + }; + + template <typename T> + struct vtypes<image2d<T> > + { + typedef point2d point_t; + typedef iterator2d iter_t; + typedef T value_t; + }; +};
s/point_t/point_type/ s/iter_t/iter_type/ s/value_t/value_type/ Currently, virtual type names must end with `_type', and are retrieved without that suffix (this might change in a near future). [...]
+// image_morpher +template <typename E> +struct image_morpher; + +namespace oln +{ + template<typename E> + struct set_super_type<image_morpher<E> > + { + typedef image_base<image_morpher<E> > ret; + }; + + template <typename E> + struct vtypes<image_morpher<E> > + { + typedef mlc::undefined delegatee_t; + }; +};
s/delegatee_t/delegatee_type/ [...]
Index: samples/mini-oln/README =================================================================== --- samples/mini-oln/README (revision 0) +++ samples/mini-oln/README (revision 0) @@ -0,0 +1 @@ +FIXME \ No newline at end of file
Source files, like text files, should always end with a newline character! Thanks for your work, it was especially useful to start writing samples/concept-c++/mini-oln.cc. I've fixed most of the changes while I was writing this concept-aided version of mini-oln, but some of them remain.