2006-09-05 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
Test on abstract::pset alternative code for static inheritance.
* oln/core/abstract/entry.hh: New proposition for entry class in
static hierarchies. This is a test file that should be removed
after stc update.
* oln/core/typedefs.hh (fixed_type, ra_type, bbox_type): New
typedef declarations.
* oln/core/abstract/bbox.hh (fwd_piter_, bkd_piter_): Remove
these forward declarations.
(ext_vtype): Remove.
(vtypes): New.
(ra_type, fixed_type, bbox_type): New associated types.
(bbox): Change inheritance from abstract::pset to an entry class.
(bbox): Remove all methods except print from this class; the
methods are dispatched into abstract::bboxed_pset and
gen::bbox_<P>.
(bbox): Likewise for attributes.
(print): Reject code to subclasses.
(impl_bbox): New method.
* oln/core/abstract/pset.hh: Include entry.hh.
(fwd_piter_type, bkd_piter_type): New associated types.
(bbox_type, ra_type, fixed_type): Likewise
(pset): Add virtual to inheritance.
(~pset): Extend check code.
(fixed_pset, ra_pset, bboxed_pset): New sub-abstractions.
(pset_fixed_hierarchy, pset_ra_hierarchy, pset_bboxed_hierarchy):
New hierarchy tags.
* oln/core/gen/bbox.hh: Update.
(operator=): New.
Index: oln/core/typedefs.hh
===================================================================
--- oln/core/typedefs.hh (revision 521)
+++ oln/core/typedefs.hh (working copy)
@@ -109,6 +109,14 @@
// --------------------------------------------------------------------
+ /*-----------------.
+ | category::pset. |
+ `------------------*/
+
+ mlc_decl_typedef(fixed_type);
+ mlc_decl_typedef(ra_type);
+
+
/*------------------.
| category::image. |
`------------------*/
@@ -137,6 +145,7 @@
mlc_decl_typedef(delegated_type);
mlc_decl_typedef(size_type);
+ mlc_decl_typedef(bbox_type);
// --------------------------------------------------------------------
// FIXME: To be enabled later.
// --------------------------------------------------------------------
Index: oln/core/abstract/bbox.hh
===================================================================
--- oln/core/abstract/bbox.hh (revision 521)
+++ oln/core/abstract/bbox.hh (working copy)
@@ -40,8 +40,6 @@
// Forward declaration.
namespace abstract { template <typename E> class bbox; }
- template <typename point> class fwd_piter_;
- template <typename point> class bkd_piter_;
// Super type declaration.
@@ -52,150 +50,32 @@
};
-
+ /// Virtual types associated to oln::abstract::bbox<E>.
template <typename E>
- struct ext_vtype< abstract::bbox<E>, typedef_::fwd_piter_type >
+ struct vtypes< abstract::bbox<E> >
{
- private:
- typedef oln_type_of(E, point) P;
- public:
- typedef fwd_piter_<P> ret;
+ typedef mlc::true_ ra_type;
+ typedef mlc::true_ fixed_type;
+ typedef E bbox_type;
};
- template <typename E>
- struct ext_vtype< abstract::bbox<E>, typedef_::bkd_piter_type >
- {
- private:
- typedef oln_type_of(E, point) P;
- public:
- typedef bkd_piter_<P> ret;
- };
-
namespace abstract
{
/// Abstract bbox (bounding box) class.
template <typename E>
- class bbox : public abstract::pset<E>
+ class bbox : public entry< abstract::pset, E> // NEW! former was:
abstract::pset<E>
{
- typedef E exact_t;
typedef oln_type_of(E, point) point_t;
- typedef oln_type_of(E, coord) coord_t;
- typedef oln_type_of(point_t, dim) dim;
- enum { n = mlc_value(dim) };
-
public:
-
- unsigned npoints() const
- {
- unsigned count = 1;
- for (unsigned i = 0; i < n; ++i)
- count *= size(i);
- return count;
- }
- const point_t& pmin() const
- {
- precondition(is_valid_);
- return pmin_;
- }
-
- coord_t pmin(unsigned i) const
- {
- precondition(is_valid_ and i < n);
- return pmin_[i];
- }
-
- const point_t& pmax() const
- {
- precondition(is_valid_);
- return pmax_;
- }
-
- coord_t pmax(unsigned i) const
- {
- precondition(is_valid_ and i < n);
- return pmax_[i];
- }
-
- unsigned size(unsigned i) const
- {
- precondition(is_valid_ and i < n);
- return pmax_[i] - pmin_[i] + 1;
- }
-
- void flush()
- {
- is_valid_ = false;
- }
-
- void init_with(const point_t& p)
- {
- precondition(not is_valid_);
- pmin_ = p;
- pmax_ = p;
- is_valid_ = true;
- }
-
- void update_with(const point_t& p)
- {
- precondition(is_valid_);
- for (unsigned i = 0; i < n; ++i)
- if (p[i] < pmin_[i])
- pmin_[i] = p[i];
- else if (p[i] > pmax_[i])
- pmax_[i] = p[i];
- }
-
- void take(const point_t& p)
- {
- if (not is_valid_)
- {
- init_with(p);
- return;
- }
- for (unsigned i = 0; i < n; ++i)
- if (p[i] < pmin_[i])
- pmin_[i] = p[i];
- else if (p[i] > pmax_[i])
- pmax_[i] = p[i];
- }
-
- // FIXME: Add "update : (rhs : exact)"
-
- bool has(const point_t& p) const
- {
- precondition(is_valid_);
- for (unsigned i = 0; i < n; ++i)
- if (p[i] < pmin_[i] or p[i] > pmax_[i])
- return false;
- return true;
- }
-
- bool includes(const exact_t& rhs) const
- {
- precondition(is_valid_ and rhs.is_valid());
- for (unsigned i = 0; i < n; ++i)
- if (rhs.pmin()[i] < pmin_[i] or rhs.pmax()[i] > pmax_[i])
- return false;
- return true;
- }
-
- bool is_valid() const
- {
- return is_valid_;
- }
-
void print(std::ostream& ostr) const
{
- ostr << "{ pmin=" << pmin_
- << ", pmax=" << pmax_
- << ", valid=" << is_valid_
- << " }";
+ this->exact().impl_print(ostr);
}
-
+
friend
std::ostream& operator<<(std::ostream& ostr, const
abstract::bbox<E>& bb)
{
@@ -203,57 +83,19 @@
return ostr;
}
- // FIXME: Add the scool code below.
-
-// invariant {
-// n > 1
-// is_valid => (pmax >= pmin) // FIXME: More.
-// }
-
-// (=) const : (rhs : exact) -> bool =
-// {
-// precondition(@is_valid and rhs.is_valid)
-// return @pmin = rhs.pmin and @pmax = rhs.pmax
-// }
-
-// (+=) : (dp : dpoint const ref) -> exact =
-// {
-// precondition(is_valid)
-// pmin += dp
-// pmax += dp
-// }
-
-// (-=) : (dp : dpoint const ref) -> exact =
-// {
-// precondition(is_valid)
-// pmin -= dp
-// pmax -= dp
-// }
-
+ const E& impl_bbox() const
+ {
+ return this->exact();
+ }
+
protected:
- point_t pmin_;
- point_t pmax_;
- bool is_valid_;
-
bbox()
{
- flush();
}
- bbox(const point_t& pmin, const point_t& pmax)
- : pmin_(pmin),
- pmax_(pmax)
- {
- for (unsigned i = 0; i < n; ++i)
- precondition(pmax[i] >= pmin[i]);
- is_valid_ = true;
- }
-
~bbox()
{
- flush();
-
mlc::assert_defined_< point_t >::check();
// typedef oln_type_of(E, fwd_piter) fwd_piter_t;
@@ -267,7 +109,6 @@
// mlc::assert_< mlc::eq_< oln_type_of(bkd_piter_t, grid),
// oln_type_of(point_t, grid) > >::check();
-
}
}; // end of class oln::abstract::bbox<E>
Index: oln/core/abstract/entry.hh
===================================================================
--- oln/core/abstract/entry.hh (revision 0)
+++ oln/core/abstract/entry.hh (revision 0)
@@ -0,0 +1,118 @@
+// Copyright (C) 2005, 2006 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 OLENA_CORE_ABSTRACT_ENTRY_HH
+# define OLENA_CORE_ABSTRACT_ENTRY_HH
+
+# include <oln/core/typedefs.hh>
+
+
+namespace oln
+{
+
+ template < template <class> class abstraction,
+ unsigned num >
+ struct hierarchy
+ {
+ };
+
+
+ namespace internal
+ {
+
+ // fwd decl
+ template < template <class> class abstraction, typename E, unsigned num
>
+ struct entry_node;
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num,
+ typename another_hierarchy = mlc::false_ >
+ struct next_entry_node
+ {
+ // here: no other hierarchy
+ };
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num >
+ struct next_entry_node < abstraction,
+ E,
+ num,
+ mlc::true_>
+
+ : // plug to client sub-abstractions
+ public virtual oln::switch_< hierarchy<abstraction, num>, E >::ret,
+
+ // here: another hierarchy (number is 'num + 1')
+ public entry_node<abstraction, E, num + 1>
+ {
+ };
+
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num >
+ struct entry_node
+ : public next_entry_node< abstraction,
+ E,
+ num,
+ typename mlc::is_defined_< oln::case_< oln::hierarchy<abstraction, num>,
+ E, 1 > >::eval >
+ {
+ };
+
+ } // end of namespace oln::internal
+
+
+
+ template < template <class> class abstraction,
+ unsigned num,
+ typename E >
+ struct default_case_ < oln::hierarchy<abstraction, num>,
+ E >
+ {
+ typedef abstraction<E> ret;
+ };
+
+
+
+ template < template <class> class abstraction,
+ typename E >
+ struct entry : public internal::entry_node<abstraction, E, 1>
+ {
+ protected:
+ entry()
+ {
+ }
+ };
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ABSTRACT_ENTRY_HH
Index: oln/core/abstract/pset.hh
===================================================================
--- oln/core/abstract/pset.hh (revision 521)
+++ oln/core/abstract/pset.hh (working copy)
@@ -33,7 +33,9 @@
# include <oln/core/type.hh>
# include <oln/core/typedefs.hh>
+# include <oln/core/abstract/entry.hh> // NEW!
+
namespace oln
{
@@ -47,27 +49,22 @@
struct vtypes< abstract::pset<E> >
{
typedef mlc::undefined point_type;
-// typedef mlc::undefined fwd_piter_type;
-// typedef mlc::undefined bkd_piter_type;
+ typedef mlc::undefined fwd_piter_type;
+ typedef mlc::undefined bkd_piter_type;
+
+ typedef mlc::none bbox_type;
+ typedef mlc::undefined ra_type;
+ typedef mlc::undefined fixed_type;
};
-// template <typename E>
-// struct single_vtype< abstract::pset<E>, typedef_::coord_type >
-// : type_of_< oln_type_of(E, point), typedef_::coord_type >
-// {};
+ template <typename E>
+ struct ext_vtype< abstract::pset<E>, typedef_::coord_type >
+ {
+ typedef oln_type_of(E, point) P;
+ typedef oln_type_of(P, coord) ret;
+ };
-
-// template <typename E>
-// struct ext_vtype< abstract::pset<E>, typedef_::coord_type >
-// {
-// private:
-// typedef oln_type_of(E, point) P;
-// public:
-// typedef oln_type_of(P, coord) ret;
-// };
-
-
template <typename E>
struct ext_vtype< abstract::pset<E>, typedef_::grid_type >
{
@@ -81,10 +78,13 @@
/// Abstract point class.
template <typename E>
- class pset : public stc::any__simple<E>,
- public oln::type
+ class pset : public virtual stc::any__simple<E>,
+ public virtual oln::type
{
+ public:
+ // ...
+
protected:
pset()
@@ -93,13 +93,12 @@
~pset()
{
mlc::assert_defined_< oln_type_of(E, point) >::check();
+ mlc::assert_defined_< oln_type_of(E, fwd_piter) >::check();
+ mlc::assert_defined_< oln_type_of(E, bkd_piter) >::check();
+
mlc::assert_defined_< oln_type_of(E, coord) >::check();
+ mlc::assert_defined_< oln_type_of(E, grid) >::check();
- // FIXME: BUG! Trouble with circular dependencies.
-
-// mlc::assert_defined_< fwd_piter_t >::check();
-// mlc::assert_defined_< bkd_piter_t >::check();
-
// mlc::assert_< mlc::eq_< oln_type_of(fwd_piter_t, grid),
// oln_type_of(point_t, grid) > >::check();
@@ -110,9 +109,138 @@
}; // end of class oln::abstract::pset<E>
+
+ template <typename E>
+ class fixed_pset : public virtual pset<E>
+ {
+ public:
+
+ unsigned npoints() const
+ {
+ return this->exact().impl_npoints();
+ }
+
+ protected:
+ fixed_pset()
+ {}
+ };
+
+
+
+ template <typename E>
+ class ra_pset : public virtual pset<E>
+ {
+ typedef oln_type_of(E, point) point_t;
+
+ public:
+
+ bool has(const point_t& p) const
+ {
+ return this->exact().impl_has(p);
+ }
+
+ protected:
+ ra_pset()
+ {}
+ };
+
+
+
+ template <typename E>
+ class bboxed_pset : public virtual pset<E>
+ {
+ typedef oln_type_of(E, point) point_t;
+ typedef oln_type_of(E, bbox) bbox_t;
+
+ typedef oln_type_of(point_t, coord) coord_t;
+ typedef oln_type_of(point_t, dim) dim_t;
+ enum { n = mlc_value(dim_t) };
+
+ public:
+
+ const bbox_t& bbox() const
+ {
+ return this->exact().impl_box();
+ }
+
+ bool is_valid() const
+ {
+ return this->exact().impl_is_valid();
+ }
+
+ const point_t& pmin() const
+ {
+ precondition(this->is_valid());
+ return pmin_;
+ }
+
+ coord_t pmin(unsigned i) const
+ {
+ precondition(this->is_valid() and i < n);
+ return pmin_[i];
+ }
+
+ const point_t& pmax() const
+ {
+ precondition(this->is_valid());
+ return pmax_;
+ }
+
+ coord_t pmax(unsigned i) const
+ {
+ precondition(this->is_valid() and i < n);
+ return pmax_[i];
+ }
+
+ unsigned len(unsigned i) const
+ {
+ precondition(this->is_valid() and i < n);
+ return pmax_[i] - pmin_[i] + 1;
+ }
+
+ protected:
+
+ bboxed_pset()
+ {}
+
+ point_t pmin_, pmax_;
+ };
+
+
} // end of namespace oln::abstract
+
+ typedef hierarchy<abstract::pset, 1> pset_fixed_hierarchy;
+ typedef hierarchy<abstract::pset, 2> pset_ra_hierarchy;
+ typedef hierarchy<abstract::pset, 3> pset_bboxed_hierarchy;
+
+
+ template <typename E>
+ struct case_ < pset_fixed_hierarchy, E, 1 >
+ : where_< mlc::eq_< oln_type_of(E, fixed), mlc::true_ > >
+ {
+ typedef abstract::fixed_pset<E> ret;
+ };
+
+
+ template <typename E>
+ struct case_ < pset_ra_hierarchy, E, 1 >
+ : where_< mlc::eq_< oln_type_of(E, ra), mlc::true_ > >
+ {
+ typedef abstract::ra_pset<E> ret;
+ };
+
+
+ template <typename E>
+ struct case_ < pset_bboxed_hierarchy, E, 1 >
+ : where_< mlc::neq_< oln_type_of(E, bbox), mlc::none > >
+ {
+ typedef abstract::bboxed_pset<E> ret;
+ };
+
+
+
} // end of namespace oln
Index: oln/core/gen/bbox.hh
===================================================================
--- oln/core/gen/bbox.hh (revision 521)
+++ oln/core/gen/bbox.hh (working copy)
@@ -56,11 +56,8 @@
struct vtypes< bbox_<point> >
{
typedef point point_type;
-// typedef fwd_piter_<point> fwd_piter_type;
-// typedef bkd_piter_<point> bkd_piter_type;
- typedef typename point::coord_t coord_type;
- // FIXME: BUG! typedef oln_type_of(point, grid) grid_type;
- // FIXME: BUG! typedef typename point::grid_t grid_type;
+ typedef fwd_piter_<point> fwd_piter_type;
+ typedef bkd_piter_<point> bkd_piter_type;
};
@@ -73,17 +70,142 @@
typedef bbox_<point> self_t;
typedef abstract::bbox<self_t> super_t;
+ typedef oln_type_of(point, coord) coord_t;
+
+ typedef oln_type_of(point_t, dim) dim;
+ enum { n = mlc_value(dim) };
+
public:
bbox_()
- {
- }
+ {
+ flush();
+ }
bbox_(const point_t& pmin, const point_t& pmax)
- : super_t(pmin, pmax)
- {
- }
+ {
+ this->pmin_ = pmin;
+ this->pmax_ = pmax;
+ is_valid_ = true;
+ for (unsigned i = 0; i < n; ++i)
+ precondition(pmax[i] >= pmin[i]);
+ }
+
+ bbox_(const self_t& rhs)
+ {
+ // FIXME: Remove these 3 lines?
+ precondition(rhs.is_valid());
+ for (unsigned i = 0; i < n; ++i)
+ precondition(rhs.pmax_[i] >= rhs.pmin_[i]);
+
+ this->pmin_ = rhs.pmin_;
+ this->pmax_ = rhs.pmax_;
+ is_valid_ = rhs.is_valid_;
+
+ for (unsigned i = 0; i < n; ++i)
+ postcondition(this->pmax_[i] >= this->pmin_[i]);
+ }
+
+ self_t& operator=(const self_t& rhs)
+ {
+ // FIXME: Remove these 3 lines?
+ precondition(rhs.is_valid());
+ for (unsigned i = 0; i < n; ++i)
+ precondition(rhs.pmax_[i] >= rhs.pmin_[i]);
+
+ this->pmin_ = rhs.pmin_;
+ this->pmax_ = rhs.pmax_;
+ is_valid_ = rhs.is_valid_;
+
+ for (unsigned i = 0; i < n; ++i)
+ postcondition(this->pmax_[i] >= this->pmin_[i]);
+
+ return *this;
+ }
+
+ unsigned impl_npoints() const
+ {
+ unsigned count = 1;
+ for (unsigned i = 0; i < n; ++i)
+ count *= this->len(i);
+ return count;
+ }
+
+ bool impl_has(const point_t& p) const
+ {
+ precondition(is_valid_);
+ for (unsigned i = 0; i < n; ++i)
+ if (p[i] < this->pmin_[i] or p[i] > this->pmax_[i])
+ return false;
+ return true;
+ }
+
+ void flush()
+ {
+ is_valid_ = false;
+ }
+
+ void init_with(const point_t& p)
+ {
+ precondition(not is_valid_);
+ this->pmin_ = p;
+ this->pmax_ = p;
+ is_valid_ = true;
+ }
+
+ void update_with(const point_t& p)
+ {
+ precondition(is_valid_);
+ for (unsigned i = 0; i < n; ++i)
+ if (p[i] < this->pmin_[i])
+ this->pmin_[i] = p[i];
+ else if (p[i] > this->pmax_[i])
+ this->pmax_[i] = p[i];
+ }
+
+ void take(const point_t& p)
+ {
+ if (not is_valid_)
+ {
+ init_with(p);
+ return;
+ }
+ for (unsigned i = 0; i < n; ++i)
+ if (p[i] < this->pmin_[i])
+ this->pmin_[i] = p[i];
+ else if (p[i] > this->pmax_[i])
+ this->pmax_[i] = p[i];
+ }
+
+ // FIXME: Add "update : (rhs : exact)"
+
+ bool includes(const self_t& rhs) const
+ {
+ precondition(is_valid_ and rhs.is_valid());
+ for (unsigned i = 0; i < n; ++i)
+ if (rhs.pmin()[i] < this->pmin_[i] or rhs.pmax()[i] > this->pmax_[i])
+ return false;
+ return true;
+ }
+
+ bool impl_is_valid() const
+ {
+ return is_valid_;
+ }
+
+ void impl_print(std::ostream& ostr) const
+ {
+ ostr << "{ pmin=" << this->pmin_
+ << ", pmax=" << this->pmax_
+ << ", valid=" << is_valid_
+ << " }";
+ }
+
+ protected:
+
+ bool is_valid_;
+
}; // end of class oln::bbox_<point>