Subject: oln/prototypes 1: initial commit.
From: Simon Odou <[email-masked]>
Date: 09 Jul 2004 21:08:16 +0200
Newsgroups: lrde.olena;,lrde.olena.patches

"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  <[email-masked]>

	* prop_heredity: New prototype for olena.

Index: prototypes/prop_heredity/ChangeLog
from  Simon Odou  <[email-masked]>

	* 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, [[email-masked]],
+	[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
[email-masked]