522: Test on abstract::pset alternative code for static inheritance.
2006-09-05 Thierry GERAUD <theo@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>
participants (1)
-
Thierry GERAUD