
"prototypes" is a new project which will be used to play with small pieces of code. The prototype grow up and if it's a good boy, it becomes a real branch of Olena. And one day, of course, it may be merged inside Olena with honors. The "prop_heredity" is a new prototype coming directly from theo's. See the NEWS file to know more about. svn co https://svn.lrde.epita.fr/svn/oln Index: prototypes/ChangeLog from Simon Odou <simon@lrde.epita.fr> * prop_heredity: New prototype for olena. Index: prototypes/prop_heredity/ChangeLog from Simon Odou <simon@lrde.epita.fr> * configure.ac: New. * bootstrap.sh: New. * src: New. * src/image.hh: New. * src/iter.hh: New. * src/props.hh: New. * src/any.hh: New. * src/dim.hh: New. * src/point.hh: New. * src/size.hh: New. * src/main.cc: New. * src/mlc.hh: New. * src/Makefile.am: New. * src/morpher.hh: New. * src/dim2d.hh: New. * ChangeLog: New. * Makefile.am: New. * NEWS: New. Index: prop_heredity/NEWS --- prop_heredity/NEWS (revision 0) +++ prop_heredity/NEWS (revision 0) @@ -0,0 +1,15 @@ +prop_heredity 1 July 9, 2004 + + * Initial public release. + + * Theo made a new hierarchy based on property heredity. + - Easier to understand. + - Easier to extend (i.e. for morphers). + + * Theo changed the any_with_diamond model which is very time + consuming. The idea is to have the choice : + - memory policy: it's the same than the actual implementation + in Olena. + - speed policy: in this way, you keep for each class an attribute + setting the base class address. So you lose an attribute but you + win 30% of execution time. Index: prop_heredity/configure.ac --- prop_heredity/configure.ac (revision 0) +++ prop_heredity/configure.ac (revision 0) @@ -0,0 +1,14 @@ +AC_INIT([oln_proto__prop_heredity], 0, [olena@lrde.epita.fr], + [oln_proto__prop_heredity]) +AM_INIT_AUTOMAKE([1.7 no-define foreign dist-bzip2]) + +# Ugly. +CXXFLAGS="$CXXFLAGS -finline-limit-1500 -Wall -pedantic" + +AC_PROG_CC +AC_PROG_CXX + +AC_CONFIG_FILES([Makefile + src/Makefile]) + +AC_OUTPUT Index: prop_heredity/bootstrap.sh --- prop_heredity/bootstrap.sh (revision 0) +++ prop_heredity/bootstrap.sh (revision 0) @@ -0,0 +1,4 @@ +#! /bin/sh + +autoreconf -fvi +echo "Reconfiguration done." Property changes on: prop_heredity/bootstrap.sh ___________________________________________________________________ Name: svn:executable + * Property changes on: prop_heredity/src ___________________________________________________________________ Name: svn:ignore + *~ .#* *.swp proto Makefile.in .deps Makefile Index: prop_heredity/src/image.hh --- prop_heredity/src/image.hh (revision 0) +++ prop_heredity/src/image.hh (revision 0) @@ -0,0 +1,202 @@ +#ifndef PROTO_IMAGE_HH +# define PROTO_IMAGE_HH + +# include "dim2d.hh" +# include "size.hh" +# include "point.hh" +# include "mlc.hh" + + +namespace abstract { + + template <typename E> + struct image : public virtual mlc::any__best_speed<E> + { + Image_size_type(E) size() const { + return this->exact().size_impl(); + } + + const Value_type(E) operator[](const Point_type(E)& p) const { + return this->exact().opsqbr_impl(p); + } + Value_type(E)& operator[](const Point_type(E)& p) { + return this->exact().opsqbr_impl(p); + } + + bool hold(const Point_type(E)& p) const { + return this->exact().hold_impl(p); + } + + protected: + typedef mlc::any__best_speed<E> super; + //image(E *const this_) : super(this) {} + image() { std::cout << "hop!" << std::endl; } + + virtual ~image() {} + }; + + + // discriminant is dimension + + template <typename E> + struct image2d : public virtual image<E> + { + coord_t nrows() const { return this->size().nrows(); } + coord_t ncols() const { return this->size().ncols(); } + const Value_type(E) operator()(coord_t row, coord_t col) const { + return this->operator[](Point_type(E)(row, col)); + } + Value_type(E)& operator()(coord_t row, coord_t col) { + return this->operator[](Point_type(E)(row, col)); + } + }; + + + // discriminant is value type tag + + template <typename E> + struct label_image : public virtual image<E> + {}; + + template <typename E> + struct binary_image : public label_image<E> + {}; + + template <typename E> + struct scalar_image : public virtual image<E> + {}; + + template <typename E> + struct vector_image : public virtual image<E> + {}; + + + // a class with TWO properties: + + template <typename E> + struct scalar_image2d : public virtual image<E> + {}; + + + namespace internal { + + + // FIXME: switch over data storage (linear or not) + + + // switch over dimension + + template <typename Dim, typename E> + struct dim_switch; + + template <typename E> + struct dim_switch <dim2d, E> : public image2d<E> + {}; + + // switch over value type tag + + template <unsigned Tag, typename E> + struct value_tag_switch : public image<E> + {}; + + template <typename E> + struct value_tag_switch<label_tag, E> : public label_image<E> + {}; + + template <typename E> + struct value_tag_switch<binary_tag, E> : public binary_image<E> + {}; + + template <typename E> + struct value_tag_switch<scalar_tag, E> : public scalar_image<E> + {}; + + template <typename E> + struct value_tag_switch<vector_tag, E> : public vector_image<E> + {}; + + + } // end of namespace internal + + + + + // entry point of image hierarchy + + template <typename E> + struct image_entry : public virtual internal::dim_switch< Dim_type(E), E>, + public virtual internal::value_tag_switch< props<Value_type(E)>::tag_value, E > + { + protected: + image_entry() : + internal::dim_switch< Dim_type(E), E>(), + internal::value_tag_switch< props<Value_type(E)>::tag_value, E >() + { + mlc::set_this((E*)this); + } + }; + + + +} // end of namespace abstract + + + +// image2d +template <typename T> +struct image2d; + +template <typename T> +struct props < image2d<T> > : public default_props<dim2d> +{ + typedef T value_type; +}; + +template <typename T> +struct image2d : public abstract::image_entry< image2d<T> > +{ + typedef abstract::image_entry< image2d<T> > super; + image2d() {} + + image2d(coord_t nrows_, coord_t ncols_) : + size_(nrows_, ncols_) + { + array_ = new T*[nrows_]; + buffer_ = new T[nrows_ * ncols_]; + T* buf = buffer_; + for (int row = 0; row < nrows_; ++row) + { + array_[row] = buf; + buf += ncols_; + } + } + + image2d_size size_impl() const { + return size_; + } + + const T opsqbr_impl(const point2d& p) const { + assert(this->hold(p)); + return array_[p.row()][p.col()]; + } + T& opsqbr_impl(const point2d& p) { + assert(this->hold(p)); + return array_[p.row()][p.col()]; + } + + bool hold_impl(const point2d& p) const { + return + p.row() >= 0 && p.row() < size_.nrows() + && p.col() >= 0 && p.col() < size_.ncols(); + } + +protected: + image2d_size size_; + T* buffer_; + T** array_; +}; + + + + +#endif // ndef PROTO_IMAGE_HH Index: prop_heredity/src/iter.hh --- prop_heredity/src/iter.hh (revision 0) +++ prop_heredity/src/iter.hh (revision 0) @@ -0,0 +1,77 @@ +#ifndef PROTO_ITER_HH +# define PROTO_ITER_HH + +# include "dim2d.hh" + +# define for_all(P) for(p.begin(); ! p.end(); ++p) + + +namespace abstract { + + template <typename E> + struct iter : public mlc::any__best_memory<E> + { + operator Point_type(E)() const { + return p_; + } + void begin() { + this->exact().begin_impl(); + } + bool end() const { + return this->exact().end_impl(); + } + void operator++() { + return this->exact().inc_impl(); + } + protected: + iter() {} + Point_type(E) p_; + }; + +} // end of namespace abstract + + + +// iter2d + + +struct iter2d; + +template <> +struct props <iter2d> : public default_props<dim2d> +{ + typedef dim2d dim_type; +}; + +struct iter2d : public abstract::iter< iter2d > +{ + iter2d() {} + + iter2d(const image2d_size& size) : + size(size) + {} + void begin_impl() { + p_.row() = p_.col() = 0; + } + bool end() const { + return p_.row() == size.nrows(); + } + + // IDEA: T::op= calls ::assign_impl(T,Trhs) and T::op=(Trhs) is renammed assign + + void inc_impl() { + ++p_.col(); + if (p_.col() == size.ncols()) + { + p_.col() = 0; + ++p_.row(); + } + } +protected: + image2d_size size; +}; + + + + +#endif // ndef PROTO_ITER_HH Index: prop_heredity/src/props.hh --- prop_heredity/src/props.hh (revision 0) +++ prop_heredity/src/props.hh (revision 0) @@ -0,0 +1,37 @@ +#ifndef PROTO_PROPS_HH +# define PROTO_PROPS_HH + + +template <typename E> +struct props; + + +# define Dim_type(E) typename props<E>::dim_type +# define Point_type(E) typename props<E>::point_type +# define Image_size_type(E) typename props<E>::image_size_type +# define Iter_type(E) typename props<E>::iter_type +# define Value_type(E) typename props<E>::value_type + + +template <class Dim> +struct default_props +{ + typedef Dim dim_type; + typedef Point_type(Dim) point_type; + typedef Image_size_type(Dim) image_size_type; + typedef Iter_type(Dim) iter_type; +}; + + +template <class Image> +struct default_props__Image +{ + typedef Dim_type(Image) dim_type; + typedef Point_type(Image) point_type; + typedef Image_size_type(Image) image_size_type; + typedef Iter_type(Image) iter_type; + typedef Value_type(Image) value_type; +}; + + +#endif // ndef PROTO_PROPS_HH Index: prop_heredity/src/any.hh --- prop_heredity/src/any.hh (revision 0) +++ prop_heredity/src/any.hh (revision 0) @@ -0,0 +1,115 @@ +#ifndef PROTO_ANY_HH +# define PROTO_ANY_HH + + +# include <assert.h> + +// abrev +#define any_mem(E) any <E, dispatch_policy::best_memory> + + +// exact stuff + +template <typename T> struct exact_type; + +# define Exact_type(T) typename exact_type<T>::ret + +// 'any' classes + +namespace mlc +{ + + struct dispatch_policy + { + struct best_speed; + struct best_memory; + struct compromise; + }; + + + // any + + template <typename E, + typename Dispatch_Policy = dispatch_policy::best_memory> + struct any; + + + // "best speed" version of 'any' + + template <typename E> + struct any <E, + dispatch_policy::best_speed> + { + E& exact() { + assert(this_ != 0); + return *this_; + } + const E& exact() const { + assert(this_ != 0); + return *this_; + } + E* this_; + protected: + any() : this_(0) {} + virtual ~any() {} + }; + + template <typename E> + struct any__best_speed : public any<E, dispatch_policy::best_speed> + {}; + + template <typename E> + inline void + set_this(E* this_) + { + this_->this_ = this_; + } + + template <typename E> + inline void + set_this(any<E, dispatch_policy::best_memory>* this_) + {} + + // "best memory" version of 'any' + + template <typename E> + struct any <E, + dispatch_policy::best_memory> + { + E& exact() { + return *(E*)((char*)this - exact_offset); + } + const E& exact() const { + return *(const E*)((const char*)this - exact_offset); + } + + static const int exact_offset; + static const E exact_obj; + static const any_mem(E)& ref_exact_obj; + + protected: + virtual ~any() {} + }; + + template <typename E> + struct any__best_memory : public any<E, dispatch_policy::best_memory> + {}; + + template <typename E> const E any_mem(E)::exact_obj = E(); + template <typename E> const any_mem(E)& any_mem(E)::ref_exact_obj = any_mem(E)::exact_obj; + template <typename E> const int any_mem(E)::exact_offset = + (const char*)(&any_mem(E)::ref_exact_obj) + - (const char*)(&any_mem(E)::exact_obj); + + + // "compromise" version of 'any' + + template <typename E> + struct any <E, + dispatch_policy::compromise>; // FIXME: not yet impled + + +} // end of namespace mlc + + +#endif // ndef PROTO_ANY_HH Index: prop_heredity/src/dim.hh --- prop_heredity/src/dim.hh (revision 0) +++ prop_heredity/src/dim.hh (revision 0) @@ -0,0 +1,20 @@ +#ifndef PROTO_DIM_HH +# define PROTO_DIM_HH + +# include "any.hh" +# include "props.hh" + + +namespace abstract { + + template <typename E> + struct dim : public mlc::any__best_memory<E> + { + protected: + dim() {} + }; + +} // end of namespace abstract + + +#endif // ndef PROTO_DIM_HH Index: prop_heredity/src/point.hh --- prop_heredity/src/point.hh (revision 0) +++ prop_heredity/src/point.hh (revision 0) @@ -0,0 +1,68 @@ +#ifndef PROTO_POINT_HH +# define PROTO_POINT_HH + +# include "dim2d.hh" + + +typedef int coord_t; + +//Define_exact_type_2(abstract, point); + +namespace abstract { + + template <typename E> + struct point : public mlc::any__best_memory<E> + { + bool operator==(const point& rhs) const { + return this->exact().opeq_impl(rhs.exact()); + } + protected: + point() {} + }; + +} // end of namespace abstract + + + +// point2d + + +struct point2d; + +template <> +struct props <point2d> +{ + typedef dim2d dim_type; +}; + +struct point2d : public abstract::point< point2d > +{ + point2d() : + row_(0), + col_(0) + {} + point2d(coord_t row_, coord_t col_) : + row_(row_), + col_(col_) + {} + bool opeq_impl(const point2d& rhs) const { + return row_ == rhs.row_ && 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_; } + + // FIXME: + point2d operator+(const point2d& rhs) const { + point2d tmp(row_ + rhs.row_, col_ + rhs.col_); + return tmp; + } +protected: + coord_t row_, col_; +}; + + + + +#endif // ndef PROTO_POINT_HH Index: prop_heredity/src/main.cc --- prop_heredity/src/main.cc (revision 0) +++ prop_heredity/src/main.cc (revision 0) @@ -0,0 +1,63 @@ +#include <iostream> + +#include "mlc.hh" +#include "image.hh" +#include "iter.hh" +#include "morpher.hh" + + + +template <typename I> +std::ostream& operator<<(std::ostream& ostr, + const abstract::image<I>& input) +{ + Iter_type(I) p(input.size()); + for_all(p) + ostr << input[p] << ' '; + return ostr; +} + + +// IDEA: split overloaded versions and a single facade that forces args downcast +// rationale: the client should *not* have to downcast args + + +template <typename I> +void foo_overloaded(abstract::binary_image<I>& input) +{ + Iter_type(I) p(input.size()); + for_all(p) + std::cout << input[p] << '*'; + std::cout << std::endl; +} + + +template <typename I> +void foo_overloaded(abstract::image2d<I>& input) +{ + Value_type(I) i = 0; + + for (int row = 0; row < input.nrows(); ++row) + for (int col = 0; col < input.ncols(); ++col) + input(row, col) = i++; +} + + +template <typename I> +void foo(abstract::image<I>& input) +{ + foo_overloaded(input.exact()); +} + + + +int main() +{ + image2d<unsigned> ima(4, 4); + foo(ima); + std::cout << ima << std::endl; + + image_piece< image2d<unsigned> > pima = piece(ima, point2d(1,1), image2d_size(2,2)); + foo(pima); + std::cout << ima << std::endl; +} Index: prop_heredity/src/size.hh --- prop_heredity/src/size.hh (revision 0) +++ prop_heredity/src/size.hh (revision 0) @@ -0,0 +1,57 @@ +#ifndef PROTO_SIZE_HH +# define PROTO_SIZE_HH + +# include "any.hh" +# include "props.hh" +# include "dim2d.hh" + + +typedef int coord_t; + +namespace abstract { + + template <typename E> + struct image_size : public mlc::any__best_memory<E> + { + bool operator==(const image_size& rhs) const { + return this->exact().opeq_impl(rhs.exact()); + } + protected: + image_size() {} + }; + +} // end of namespace abstract + + + +// image2d_size + + +struct image2d_size; + +template <> +struct props <image2d_size> : public default_props<dim2d> +{ +}; + +struct image2d_size : public abstract::image_size< image2d_size > +{ + image2d_size() {} + + image2d_size(coord_t nrows_, coord_t ncols_) : + nrows_(nrows_), + ncols_(ncols_) + {} + bool opeq_impl(const image2d_size& rhs) const { + return nrows_ == rhs.nrows_ && ncols_ == rhs.ncols_; + } + const coord_t nrows() const { return nrows_; } + const coord_t ncols() const { return ncols_; } + coord_t& nrows() { return nrows_; } + coord_t& ncols() { return ncols_; } +protected: + coord_t nrows_, ncols_; +}; + + +#endif // ndef PROTO_SIZE_HH Index: prop_heredity/src/mlc.hh --- prop_heredity/src/mlc.hh (revision 0) +++ prop_heredity/src/mlc.hh (revision 0) @@ -0,0 +1,28 @@ +#ifndef PROTO_MLC_HH +# define PROTO_MLC_HH + +# include <vector> +# include "props.hh" + + +enum { scalar_tag, binary_tag, vector_tag, label_tag }; + +struct label_type +{ + int i; + label_type() : i(0) {} + label_type(int i) : i(i) {} + operator int() const { return i; } + void operator=(int i) { this->i = i; } +}; + + +template <> struct props <unsigned> { enum { tag_value = scalar_tag }; }; +template <> struct props <bool> { enum { tag_value = binary_tag }; }; +template <> struct props <label_type> { enum { tag_value = label_tag }; }; +template <typename T> struct props < std::vector<T> > { enum { tag_value = vector_tag }; }; + +# define Tag_value(T) props<T>::tag_value + + +#endif // ndef PROTO_MLC_HH Index: prop_heredity/src/Makefile.am --- prop_heredity/src/Makefile.am (revision 0) +++ prop_heredity/src/Makefile.am (revision 0) @@ -0,0 +1,13 @@ +bin_PROGRAMS = proto +proto_SOURCES = \ +any.hh \ +dim.hh \ +dim2d.hh \ +image.hh \ +iter.hh \ +main.cc \ +mlc.hh \ +morpher.hh \ +point.hh \ +props.hh \ +size.hh Index: prop_heredity/src/morpher.hh --- prop_heredity/src/morpher.hh (revision 0) +++ prop_heredity/src/morpher.hh (revision 0) @@ -0,0 +1,63 @@ +#ifndef PROTO_MORPHER_HH +# define PROTO_MORPHER_HH + +# include "image.hh" + + +template <typename I> struct image_piece; + + +template <typename I> +struct props < image_piece<I> > : public default_props__Image<I> +{ +}; + + +template <typename I> +struct image_piece : public abstract::image_entry< image_piece<I> > +{ + typedef image_piece<I> E; + + image_piece(abstract::image<I>& ref_, + Point_type(I) point_, + Image_size_type(I) size_) : + ref_(ref_.exact()), + point_(point_), + size_(size_) + {} + + Image_size_type(E) size_impl() const { + return size_; + } + + const Value_type(E) opsqbr_impl(const Point_type(E)& p) const { +// assert(this->hold(p)); + return ref_[point_ + p]; + } + Value_type(E)& opsqbr_impl(const Point_type(E)& p) { +// assert(this->hold(p)); + return ref_[point_ + p]; + } + + bool hold_impl(const Point_type(E)& p) const { + return true; // FIXME + } + + I& ref_; + Point_type(E) point_; + Image_size_type(E) size_; +}; + + +template <typename I> +image_piece<I> piece(abstract::image<I>& ref_, + Point_type(I) point_, + Image_size_type(I) size_) +{ + image_piece<I> tmp(ref_, point_, size_); + return tmp; +} + + + +#endif // ndef PROTO_MORPHER_HH Index: prop_heredity/src/dim2d.hh --- prop_heredity/src/dim2d.hh (revision 0) +++ prop_heredity/src/dim2d.hh (revision 0) @@ -0,0 +1,32 @@ +#ifndef PROTO_DIM2D_HH +# define PROTO_DIM2D_HH + +# include "dim.hh" + + +// fwd decls: +struct dim2d; +struct point2d; +struct iter2d; +struct image2d_size; +// FIXME: to be continued + + + +template <> +struct props <dim2d> { + enum { dim_value = 2 }; + typedef dim2d dim_type; + + typedef point2d point_type; + typedef image2d_size image_size_type; + typedef iter2d iter_type; + // FIXME: to be continued +}; + +struct dim2d : public abstract::dim< dim2d > +{ +}; + + +#endif // ndef PROTO_DIM2D_HH Index: prop_heredity/Makefile.am --- prop_heredity/Makefile.am (revision 0) +++ prop_heredity/Makefile.am (revision 0) @@ -0,0 +1 @@ +SUBDIRS = src -- Simon Odou simon@lrde.epita.fr