https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a slice morpher.
* oln/morpher/tags.hh (oln::morpher::tag::slice): New tag.
* oln/morpher/slice.hh: New file (new morpher).
* oln/core/type_fun/slice.hh: New.
* oln/core/iterator_vtypes.hh: Include it.
(oln::single_vtype<morpher::slice<Image>, typedef_::fwd_piter_type>)
(oln::single_vtype<morpher::slice<Image>, typedef_::bkd_piter_type>):
New.
* oln/core/1d/topo1d.hh, oln/core/2d/topo2d.hh,
* oln/core/3d/topo3d.hh: New (shortcuts).
* oln/core/gen/topo_lbbox.hh (oln::vtypes< topo_lbbox_<point> >:
Reduce the explanation to a reference to the virtual types of
oln::topo_bbox_.
(topo_lbbox::topo_lbbox_(const point&, const point&, unsigned)):
New ctor.
(topo_lbbox::border): New method.
* oln/core/gen/topo_bbox.hh
(topo_bbox::topo_bbox_(const point&, const point&)): New ctor.
* oln/Makefile.am (nobase_oln_HEADERS): Add
core/1d/topo1d.hh, core/2d/topo2d.hh, core/3d/topo3d.hh,
core/gen/piter_isubset.hh, core/type_fun/slice_piter.hh and
morpher/slice.hh.
* tests/morphers/slice_morpher.cc: New test.
* tests/morphers/Makefile.am (check_PROGRAMS): Add slice_morpher.
(slice_morpher_SOURCES): New.
* oln/core/gen/bbox_fwd_piter.hh, oln/core/gen/bbox_bkd_piter.hh,
* tests/morphers/add_neighborhood_morpher.cc: Fix a comment.
oln/Makefile.am | 7
oln/core/1d/topo1d.hh | 38 +++
oln/core/2d/topo2d.hh | 38 +++
oln/core/3d/topo3d.hh | 38 +++
oln/core/gen/bbox_bkd_piter.hh | 2
oln/core/gen/bbox_fwd_piter.hh | 2
oln/core/gen/topo_bbox.hh | 10 -
oln/core/gen/topo_lbbox.hh | 76 ++-----
oln/core/iterator_vtypes.hh | 43 ++++
oln/core/type_fun/slice.hh | 280 +++++++++++++++++++++++++++++
oln/morpher/slice.hh | 206 +++++++++++++++++++++
oln/morpher/tags.hh | 2
tests/morphers/Makefile.am | 4
tests/morphers/add_neighborhood_morpher.cc | 6
tests/morphers/slice_morpher.cc | 92 +++++++++
15 files changed, 780 insertions(+), 64 deletions(-)
Index: tests/morphers/add_neighborhood_morpher.cc
--- tests/morphers/add_neighborhood_morpher.cc (revision 659)
+++ tests/morphers/add_neighborhood_morpher.cc (working copy)
@@ -50,9 +50,9 @@
image_t ima(42, 51);
- /*------------------------------------.
- | add_neighborhood< image2d<char> >. |
- `------------------------------------*/
+ /*---------------------------------------------------.
+ | add_neighborhood< image2d<char>, oln::neighb2d >. |
+ `---------------------------------------------------*/
typedef oln::neighb2d neighb_t;
typedef oln::morpher::add_neighborhood<image_t, neighb_t> image_with_nbh_t;
Index: tests/morphers/slice_morpher.cc
--- tests/morphers/slice_morpher.cc (revision 0)
+++ tests/morphers/slice_morpher.cc (revision 0)
@@ -0,0 +1,92 @@
+// Copyright (C) 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.
+
+/// Test the identity morpher.
+
+#include <cassert>
+
+#include <mlc/assert.hh>
+#include <mlc/is_a.hh>
+
+// FIXME: We should not include oln/basics2d.hh and oln/basics3d.hh,
+// but only oln/core/2d/image2d.hh and oln/core/3d/image3d.hh.
+#include <oln/basics2d.hh>
+#include <oln/basics3d.hh>
+#include <oln/morpher/slice.hh>
+
+#include <oln/level/fill.hh>
+
+
+int
+main()
+{
+ /*---------------.
+ | image2d<int>. |
+ `---------------*/
+
+ typedef oln::image3d<int> image_t;
+
+ // Sanity check: interfaces realized by oln::image2d.
+ mlc::assert_< mlc_is_a_(image_t, oln::abstract::image3d) >::check();
+
+ image_t ima(3, 4, 5);
+ oln::level::fill (ima, 42);
+
+
+ /*----------------------------.
+ | add_slice< image2d<int> >. |
+ `----------------------------*/
+
+ typedef oln::morpher::slice<image_t> slice_t;
+
+ // Check that the instantiated slice morpher realizes the suited
+ // interfaces.
+ mlc::assert_< mlc::eq_<oln_type_of_(slice_t, grid), oln::grid2d>
>::check();
+ mlc::assert_< mlc_is_a_(slice_t, oln::abstract::image2d) >::check();
+ mlc::assert_< mlc_is_a_(slice_t, oln::abstract::mutable_image) >::check();
+
+ // Create a slice of \a ima along the 2nd axis (which the ``row''
+ // axis, numbered 1), and check its peoperties.
+ int slice_row = 2;
+ slice_t ima_with_nbh(ima, 1, slice_row);
+ assert(ima_with_nbh.bbox().nrows() == 3);
+ assert(ima_with_nbh.bbox().ncols() == 5);
+ // Fill a slice of \a ima by filling \a ima_with_nbh.
+ oln::level::fill (ima_with_nbh, 51);
+
+ // Check that \a ima has been altered, by comapring it to a similar
+ // 3D image.
+ image_t ref(3, 4, 5);
+ oln::level::fill (ref, 42);
+ for (unsigned s = 0; s < ima.bbox().nslices(); ++s)
+ for (unsigned c = 0; c < ima.bbox().ncols(); ++c)
+ ref.at(s, slice_row, c) = 51;
+ // FIXME: Implement equality on images.
+ oln_type_of_(image_t, piter) p (ima.topo());
+ for_all (p)
+ assert(ima(p) == ref(p));
+}
Index: tests/morphers/Makefile.am
--- tests/morphers/Makefile.am (revision 659)
+++ tests/morphers/Makefile.am (working copy)
@@ -21,13 +21,17 @@
check_PROGRAMS = \
identity_morpher \
add_neighborhood_morpher \
+ slice_morpher \
value_cast \
+ \
morphers
# Morphers.
identity_morpher_SOURCES = identity_morpher.cc
add_neighborhood_morpher_SOURCES = add_neighborhood_morpher.cc
+slice_morpher_SOURCES = slice_morpher.cc
value_cast_SOURCES = value_cast.cc
+
morphers_SOURCES = morphers.cc
Index: oln/core/type_fun/slice.hh
--- oln/core/type_fun/slice.hh (revision 0)
+++ oln/core/type_fun/slice.hh (revision 0)
@@ -0,0 +1,280 @@
+// Copyright (C) 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 OLN_CORE_TYPE_FUN_SLICE_HH
+# define OLN_CORE_TYPE_FUN_SLICE_HH
+
+# include <mlc/flags.hh>
+
+# include <oln/core/1d/point1d.hh>
+# include <oln/core/1d/topo1d.hh>
+
+# include <oln/core/2d/point2d.hh>
+# include <oln/core/2d/topo2d.hh>
+
+# include <oln/core/3d/point3d.hh>
+# include <oln/core/3d/topo3d.hh>
+
+
+namespace oln
+{
+
+ /*-----------------------------------.
+ | Point translation during slicing. |
+ `-----------------------------------*/
+
+ // FIXME: To be moved elsewhere (these are function on values, not
+ // on types).
+
+ // FIXME: Can't we rewrite this in a more generic way?
+
+ // --------- //
+ // Slicing. //
+ // --------- //
+
+ /// Translate an image point to a slice point.
+ /// \{
+
+ /// 2D to 1D version.
+ point1d slice_point(const point2d& p, unsigned slice_dim)
+ {
+ switch (slice_dim)
+ {
+ case 0:
+ return point1d(p.col());
+ break;
+ case 1:
+ return point1d(p.row());
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /// 3D to 2D version.
+ point2d slice_point(const point3d& p, unsigned slice_dim)
+ {
+ switch (slice_dim)
+ {
+ case 0:
+ return point2d(p.row(), p.col());
+ break;
+ case 1:
+ return point2d(p.slice(), p.col());
+ break;
+ case 2:
+ return point2d(p.slice(), p.row());
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /// \}
+
+
+ // ----------- //
+ // Unslicing. //
+ // ----------- //
+
+ /// Translate a slice point to an image point.
+ /// \{
+
+ /// 1D to 2D version.
+ point2d unslice_point(const point1d& p, unsigned slice_dim, int slice_coord)
+ {
+ switch (slice_dim)
+ {
+ case 0:
+ return point2d(slice_coord, p.index());
+ break;
+ case 1:
+ return point2d(p.index(), slice_coord);
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /// 2D to 3D version.
+ point3d unslice_point(const point2d& p, unsigned slice_dim, int slice_coord)
+ {
+ switch (slice_dim)
+ {
+ case 0:
+ return point3d(slice_coord, p.row(), p.col());
+ break;
+ case 1:
+ return point3d(p.row(), slice_coord, p.col());
+ break;
+ case 2:
+ return point3d(p.row(), p.col(), slice_coord);
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /// \}
+
+
+ /// Error messages raised by static assertions/abortions.
+ namespace ERROR
+ {
+ struct TYPE_FUNCTION_slice_piter_NOT_DEFINED_FOR_THIS_PARAMETER;
+ struct TYPE_FUNCTION_slice_topo_NOT_DEFINED_FOR_THIS_PARAMETER;
+ }
+
+
+ namespace type_fun
+ {
+
+ /*------------------------.
+ | type_fun::slice_piter. |
+ `------------------------*/
+
+ /// Type function returning the ``sliced'' piter corresponding to
+ /// \a Piter
+ /// \{
+
+ /// Default version, undefined.
+ template <typename Piter>
+ struct slice_piter :
+ public mlc::abort_<
+ Piter,
+ oln::ERROR::TYPE_FUNCTION_slice_piter_NOT_DEFINED_FOR_THIS_PARAMETER
+ >
+ {
+ typedef mlc::undefined ret;
+ };
+
+
+ // --------- //
+ // image2d. //
+ // --------- //
+
+ template <>
+ struct slice_piter<fwd_piter2d>
+ {
+ typedef fwd_piter1d ret;
+ };
+
+ template <>
+ struct slice_piter<bkd_piter2d>
+ {
+ typedef bkd_piter1d ret;
+ };
+
+
+ // --------- //
+ // image3d. //
+ // --------- //
+
+ template <>
+ struct slice_piter<fwd_piter3d>
+ {
+ typedef fwd_piter2d ret;
+ };
+
+ template <>
+ struct slice_piter<bkd_piter3d>
+ {
+ typedef bkd_piter2d ret;
+ };
+
+ /// \}
+
+
+ /// Type function returning the ``sliced'' topo corresponding to
+ /// \a Topo
+ /// \{
+
+ /// Default version, undefined.
+ template <typename Topo>
+ struct slice_topo :
+ public mlc::abort_<
+ Topo,
+ oln::ERROR::TYPE_FUNCTION_slice_topo_NOT_DEFINED_FOR_THIS_PARAMETER
+ >
+ {
+ typedef mlc::undefined ret;
+ };
+
+
+ // --------- //
+ // image2d. //
+ // --------- //
+
+ // FIXME: slice_topo<topo2d> is more than a function on type,
+ // because of convert(). (Where should me move this?)
+
+ template <>
+ struct slice_topo<topo2d>
+ {
+ typedef topo1d ret;
+
+ /// Convert a topo2d to a topo1d.
+ static topo1d convert (const topo2d& topo, unsigned slice_dim)
+ {
+ return topo1d(slice_point(topo.bbox().pmin(), slice_dim),
+ slice_point(topo.bbox().pmax(), slice_dim),
+ topo.border());
+ }
+ };
+
+
+ // --------- //
+ // image3d. //
+ // --------- //
+
+ // FIXME: slice_topo<topo3d> is more than a function on type,
+ // because of convert(). (Where should me move this?)
+
+ template <>
+ struct slice_topo<topo3d>
+ {
+
+ typedef topo2d ret;
+
+ /* FIXME: slice_topo<topo3d>::convert() is almost the same as
+ slice_topo<topo2d>::convert(). */
+
+ /// Convert a topo2d to a topo1d.
+ static topo2d convert (const topo3d& topo, unsigned slice_dim)
+ {
+ return topo2d(slice_point(topo.bbox().pmin(), slice_dim),
+ slice_point(topo.bbox().pmax(), slice_dim),
+ topo.border());
+ }
+ };
+
+ } // end of namespace oln::type_fun
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_TYPE_FUN_SLICE_HH
Index: oln/core/iterator_vtypes.hh
--- oln/core/iterator_vtypes.hh (revision 659)
+++ oln/core/iterator_vtypes.hh (working copy)
@@ -33,6 +33,7 @@
# include <oln/core/1d/aliases.hh>
# include <oln/core/2d/aliases.hh>
# include <oln/core/3d/aliases.hh>
+# include <oln/core/type_fun/slice.hh>
namespace oln
@@ -169,7 +170,8 @@
`--------------------------------------------*/
// Forward declarations.
- namespace morpher {
+ namespace morpher
+ {
template <typename Image, typename Isubset> struct add_isubset;
}
template <typename piter_t, typename isubset_t> class piter_isubset_;
@@ -237,7 +239,8 @@
`-------------------------------------------------*/
// Forward declarations.
- namespace morpher {
+ namespace morpher
+ {
template <typename Image, typename Neighb> struct add_neighborhood;
}
template <typename point_t> class fwd_niter_neighb_;
@@ -269,6 +272,42 @@
};
+ /*-----------------------------.
+ | oln::morpher::slice<Image>. |
+ `-----------------------------*/
+
+ // Forward declarations.
+ namespace morpher
+ {
+ template <typename Image> struct slice;
+ }
+ template <typename Piter, typename Topo> class piter_slice_;
+
+
+ /// fwd_piter vtype of morpher::slice.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::fwd_piter_type >
+ {
+ private:
+ typedef oln_type_of(Image, fwd_piter) orig_fwd_piter;
+ public:
+ typedef typename type_fun::slice_piter<orig_fwd_piter>::ret ret;
+ };
+
+ /// bkd_piter vtype of morpher::slice.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::bkd_piter_type >
+ {
+ private:
+ typedef oln_type_of(Image, bkd_piter) orig_bkd_piter;
+ public:
+ typedef typename type_fun::slice_piter<orig_bkd_piter>::ret ret;
+ };
+
+
+ // FIXME: What about niters and qiter?
+
+
} // end of namespace oln
Index: oln/core/1d/topo1d.hh
--- oln/core/1d/topo1d.hh (revision 0)
+++ oln/core/1d/topo1d.hh (revision 0)
@@ -0,0 +1,38 @@
+// Copyright (C) 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 OLN_CORE_1D_TOPO1D_HH
+# define OLN_CORE_1D_TOPO1D_HH
+
+// Headers required for the complete definition of oln::topo1d
+// (i.e., oln::topo_lbbox_<point1d>).
+# include <oln/core/1d/aliases.hh>
+# include <oln/core/1d/point1d.hh>
+# include <oln/core/1d/dpoint1d.hh>
+# include <oln/core/gen/topo_lbbox.hh>
+
+#endif // ! OLN_CORE_1D_TOPO1D_HH
Index: oln/core/2d/topo2d.hh
--- oln/core/2d/topo2d.hh (revision 0)
+++ oln/core/2d/topo2d.hh (revision 0)
@@ -0,0 +1,38 @@
+// Copyright (C) 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 OLN_CORE_2D_TOPO2D_HH
+# define OLN_CORE_2D_TOPO2D_HH
+
+// Headers required for the complete definition of oln::topo2d
+// (i.e., oln::topo_lbbox_<point2d>).
+# include <oln/core/2d/aliases.hh>
+# include <oln/core/2d/point2d.hh>
+# include <oln/core/2d/dpoint2d.hh>
+# include <oln/core/gen/topo_lbbox.hh>
+
+#endif // ! OLN_CORE_2D_TOPO2D_HH
Index: oln/core/3d/topo3d.hh
--- oln/core/3d/topo3d.hh (revision 0)
+++ oln/core/3d/topo3d.hh (revision 0)
@@ -0,0 +1,38 @@
+// Copyright (C) 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 OLN_CORE_3D_TOPO3D_HH
+# define OLN_CORE_3D_TOPO3D_HH
+
+// Headers required for the complete definition of oln::topo3d
+// (i.e., oln::topo_lbbox_<point3d>).
+# include <oln/core/3d/aliases.hh>
+# include <oln/core/3d/point3d.hh>
+# include <oln/core/3d/dpoint3d.hh>
+# include <oln/core/gen/topo_lbbox.hh>
+
+#endif // ! OLN_CORE_3D_TOPO3D_HH
Index: oln/core/gen/topo_bbox.hh
--- oln/core/gen/topo_bbox.hh (revision 659)
+++ oln/core/gen/topo_bbox.hh (working copy)
@@ -123,17 +123,15 @@
public:
topo_bbox_();
-
topo_bbox_(const bbox_t& bb);
+ topo_bbox_(const point& pmin, const point& pmax);
const bbox_t& impl_bbox() const;
-
bbox_t& impl_bbox();
bbox_t& impl_lbbox();
bool impl_has(const point& p) const;
-
bool impl_has_large(const point& p) const;
protected:
@@ -158,6 +156,12 @@
}
template <typename point>
+ topo_bbox_<point>::topo_bbox_(const point& pmin, const point& pmax)
+ : bb_(pmin, pmax)
+ {
+ }
+
+ template <typename point>
const typename topo_bbox_<point>::bbox_t&
topo_bbox_<point>::impl_bbox() const
{
Index: oln/core/gen/bbox_fwd_piter.hh
--- oln/core/gen/bbox_fwd_piter.hh (revision 659)
+++ oln/core/gen/bbox_fwd_piter.hh (working copy)
@@ -59,7 +59,7 @@
- /// Abstract forward point iterator class.
+ /// Generic forward point iterator class.
template <typename point>
class bbox_fwd_piter_ : public internal::bbox_fwd_piter<
bbox_fwd_piter_<point> >,
private mlc::assert_< mlc_is_a(point, abstract::point) >
Index: oln/core/gen/topo_lbbox.hh
--- oln/core/gen/topo_lbbox.hh (revision 659)
+++ oln/core/gen/topo_lbbox.hh (working copy)
@@ -54,58 +54,8 @@
template <typename point>
struct vtypes< topo_lbbox_<point> >
{
- /* Trick to force the instantiation of bbox_<point>.
-
- As bbox_<point> is a template type used to define the `bbox'
- virtual type of topo_lbbox_<point>, it requires some attention
- regarding its instantiation.
-
-
- Metalic's mlc_is_a is used by the static hierarchy mechanism of
- Static. mlc_is_a performs a static typedef introspection,
- taking advantage of the SFINAE rule. However, there two
- phenomena seem to happen here (probably due to the very nature
- of SFINAE):
-
- 1. the statement `mlc_is_a(B, A)' requires the knowledge of the
- entire declaration of the inspected class to answer
- positively if a `B' actually *is a* `A'. If B is a template
- class, this implies that B must have been instantiated for
- mlc_is_a to be able to inspect it;
-
- 2. mlc_is_a does *not* trigger the instantiation of the
- inspected type (probably to prevent any error, in accordance
- to the SFINAE rule).
-
- When a template type is used to define a virtual type, it
- *must* have been instantiated, because it might be used during
- the construction of the base classes of the class it belongs
- to. That is the case of bbox_<point> here.
-
- So, how one can trigger such an instantiation? We used to
- address this problem by using explicit template instantiations
- placed before the definition of the class holding the template
- type used a virtual type :
-
- template class bbox_<point1d>;
- template class bbox_<point2d>;
- template class bbox_<point3d>;
-
- And so on. But this is not good w.r.t. software engineering:
- one must take care of the correct explicit instantiations at
- the right place, which is error-prone --and the C++ compiler
- won't produces easily understandable messages!-- and requires a
- manual addition for each instantiation of the template type
- potentially used as a definition of a virtual type.
-
- A better solution is to force the compiler to instantiate the
- type at the definition site of the virtual type (here, as for
- bbox_<point>). Such an instantiation can be triggered by
- requesting the use of a typedef contained within this type. As
- many template types define a typedef `self_t' to refer to
- themselves, we use this typename to both trigger the
- instantiation of bbox_<point>, and to define
- `vtypes< topo_lbbox_<point> >::bbox_type'. */
+ /* Same trick as in the virtual types of oln::topo_bbox_ to force
+ the compiler to instantiate bbox_<point>. */
typedef typename bbox_<point>::self_type bbox_type;
typedef point point_type;
typedef mlc::true_ is_random_accessible_type;
@@ -124,16 +74,16 @@
public:
topo_lbbox_();
-
topo_lbbox_(const bbox_t& bb, unsigned border);
+ topo_lbbox_(const point& pmin, const point& pmax, unsigned border);
const bbox_t& impl_bbox() const;
bool impl_has(const point& p) const;
-
bool impl_has_large(const point& p) const;
const bbox_t& lbbox() const;
+ unsigned border () const;
protected:
@@ -163,6 +113,17 @@
}
template <typename point>
+ topo_lbbox_<point>::topo_lbbox_(const point& pmin, const point& pmax,
+ unsigned border)
+ : bb_(pmin, pmax), border_(border)
+ {
+ typedef oln_type_of(point, dpoint) dpoint_t;
+ dpoint_t dp;
+ dp.set_all(border);
+ lbb_ = bbox_<point>(bb_.pmin() - dp, bb_.pmax() + dp);
+ }
+
+ template <typename point>
const typename topo_lbbox_<point>::bbox_t&
topo_lbbox_<point>::impl_bbox() const
{
@@ -190,6 +151,13 @@
return lbb_;
}
+ template <typename point>
+ unsigned
+ topo_lbbox_<point>::border () const
+ {
+ return border_;
+ }
+
# endif
} // end of namespace oln
Index: oln/core/gen/bbox_bkd_piter.hh
--- oln/core/gen/bbox_bkd_piter.hh (revision 659)
+++ oln/core/gen/bbox_bkd_piter.hh (working copy)
@@ -59,7 +59,7 @@
- /// Abstract forward point iterator class.
+ /// Generic backward point iterator class.
template <typename point>
class bbox_bkd_piter_ : public internal::bbox_bkd_piter<
bbox_bkd_piter_<point> >,
private mlc::assert_< mlc_is_a(point, abstract::point) >
Index: oln/Makefile.am
--- oln/Makefile.am (revision 659)
+++ oln/Makefile.am (working copy)
@@ -12,6 +12,7 @@
core/1d/image1d.hh \
core/1d/neighb1d.hh \
core/1d/point1d.hh \
+ core/1d/topo1d.hh \
\
core/2d/aliases.hh \
core/2d/array2d.hh \
@@ -20,6 +21,7 @@
core/2d/image2d.hh \
core/2d/neighb2d.hh \
core/2d/point2d.hh \
+ core/2d/topo2d.hh \
\
core/3d/aliases.hh \
core/3d/array3d.hh \
@@ -28,6 +30,7 @@
core/3d/image3d.hh \
core/3d/neighb3d.hh \
core/3d/point3d.hh \
+ core/3d/topo3d.hh \
\
core/abstract/image/accessibility/hierarchy.hh \
\
@@ -111,12 +114,14 @@
core/gen/fwd_niter_neighb.hh \
core/gen/fwd_piter_bbox.hh \
core/gen/fwd_qiter_win.hh \
+ core/gen/piter_isubset.hh \
core/gen/grid.hh \
core/gen/mapimage.hh \
core/gen/neighb.hh \
core/gen/topo_add_nbh.hh \
core/gen/topo_bbox.hh \
core/gen/topo_lbbox.hh \
+ core/gen/topo_slice.hh \
core/gen/window.hh \
\
core/spe/col.hh \
@@ -125,6 +130,7 @@
\
core/type_fun/ch_value.hh \
core/type_fun/plain.hh \
+ core/type_fun/slice_piter.hh \
\
core/internal/bbox_bkd_piter.hh \
core/internal/bbox_fwd_piter.hh \
@@ -161,6 +167,7 @@
morpher/fwd_decls.hh \
morpher/identity.hh \
morpher/tags.hh \
+ morpher/slice.hh \
morpher/thru_fun.hh \
morpher/value_cast.hh \
\
Index: oln/morpher/tags.hh
--- oln/morpher/tags.hh (revision 659)
+++ oln/morpher/tags.hh (working copy)
@@ -37,6 +37,8 @@
{
/// Tag associated to oln::morpher::image_extension.
struct identity;
+ /// Tag associated to oln::morpher::slice.
+ struct slice;
} // end of namespace oln::morpher::tag
Index: oln/morpher/slice.hh
--- oln/morpher/slice.hh (revision 0)
+++ oln/morpher/slice.hh (revision 0)
@@ -0,0 +1,206 @@
+// Copyright (C) 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 OLN_MORPHER_SLICE_HH
+# define OLN_MORPHER_SLICE_HH
+
+# include <cstdlib>
+
+# include <mlc/int.hh>
+# include <mlc/abort.hh>
+
+# include <oln/core/image_entry.hh>
+# include <oln/core/gen/bbox.hh>
+# include <oln/core/type_fun/slice.hh>
+
+
+namespace oln
+{
+
+ /*---------------.
+ | slice<Image>. |
+ `---------------*/
+
+ namespace morpher
+ {
+ // Forward declaration.
+ template <typename Image> struct slice;
+
+ } // end of namespace oln::morpher
+
+
+ /// Super type.
+ template <typename Image>
+ struct set_super_type< morpher::slice<Image> >
+ {
+ typedef image_entry< morpher::slice<Image> > ret;
+ };
+
+
+ /// Virtual types associated to oln::morpher::slice<Image>
+ /// \{
+ template <typename Image>
+ struct vtypes< morpher::slice<Image> >
+ {
+ private:
+ typedef oln_deduce_type_of(Image, grid, dimvalue) orig_dimvalue_type;
+ typedef mlc::uint_< mlc_value(orig_dimvalue_type) - 1 > dimvalue_type;
+
+ public:
+ typedef typename
+ type_fun::slice_topo< oln_type_of(Image, topo) >::ret topo_type;
+
+ typedef grid_<mlc_value(orig_dimvalue_type) - 1> grid_type;
+
+ // psite_type: see below.
+ typedef typename
+ point_< mlc_value(dimvalue_type),
+ oln_deduce_type_of(Image, point, coord) >::ret
+ point_type;
+
+ // piter_type: see below.
+
+ typedef oln_type_of(Image, value) value_type;
+ // rvalue_type: see below.
+
+ // fwd_piter_type: see oln/core/iterator_vtypes.hh.
+ // bkd_piter_type: see oln/core/iterator_vtypes.hh.
+
+ // FIXME: fwd_qiter_type?
+ // FIXME: bkd_qiter_type?
+
+ typedef oln::morpher::tag::slice morpher_type;
+
+ };
+
+ // Coord.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::coord_type >
+ {
+ typedef oln_deduce_type_of(Image, point, coord) ret;
+ };
+
+ // Psite.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::psite_type >
+ {
+ private:
+ typedef morpher::slice<Image> self_t;
+ public:
+ typedef oln_type_of(self_t, point) ret;
+ };
+
+ /* FIXME: Should we keep the `piter' vtype, knowing that the macro
+ `oln_piter' gives the `fwd_piter' vtype (and not the `piter'
+ vtype)? */
+ // Piter.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::piter_type >
+ {
+ typedef oln_type_of(Image, fwd_piter) ret;
+ };
+
+ // Rvalue.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::rvalue_type >
+ {
+ typedef oln_type_of(Image, rvalue) ret;
+ };
+
+ // Lvalue.
+ template <typename Image>
+ struct single_vtype< morpher::slice<Image>, typedef_::lvalue_type >
+ {
+ typedef oln_type_of(Image, lvalue) ret;
+ };
+ /// \}
+
+
+ namespace morpher
+ {
+
+ template <typename Image>
+ class slice : public stc_get_supers(slice<Image>)
+ {
+ typedef slice<Image> self_t;
+
+ typedef oln_type_of(self_t, topo) topo_t;
+ typedef oln_type_of(self_t, rvalue) rvalue_t;
+ typedef oln_type_of(self_t, lvalue) lvalue_t;
+ typedef oln_type_of(self_t, point) point_t;
+
+ typedef oln_type_of(Image, topo) orig_topo_t;
+ typedef oln_type_of(Image, point) orig_point_t;
+
+ typedef oln_deduce_type_of(Image, point, coord) coord_t;
+
+
+ public:
+ // FIXME: Handle the constness.
+ slice(const abstract::image_having_bbox<Image>& image,
+ unsigned slice_dim, coord_t slice_coord) :
+ image_(image.exact()),
+ slice_dim_(slice_dim),
+ slice_coord_(slice_coord),
+ topo_(type_fun::slice_topo<orig_topo_t>::convert(image.topo(),
+ slice_dim))
+ {
+ }
+
+ const topo_t& impl_topo() const
+ {
+ return topo_;
+ }
+
+ rvalue_t impl_op_read(const point_t& p) const
+ {
+ precondition(topo_.has_large(p));
+ orig_point_t q = unslice_point(p, slice_dim_, slice_coord_);
+ return image_(q);
+ }
+
+ lvalue_t impl_op_readwrite(const point_t& p)
+ {
+ precondition(topo_.has_large(p));
+ orig_point_t q = unslice_point(p, slice_dim_, slice_coord_);
+ return image_(q);
+ }
+
+ protected:
+ Image image_;
+ unsigned slice_dim_;
+ coord_t slice_coord_;
+
+ private:
+ topo_t topo_;
+ };
+
+ } // end of namespace oln::morpher
+
+} // end of namespace oln
+
+#endif // ! OLN_MORPHER_SLICE_HH