https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add a morpher adding a neighborhood to an image. * mln/neighb/image.hh: New. Provide a morpher adding a neighborhood to an image. * mln/neighb/get.hh: New. Get the neighborhood from an image with neighborhood. * mln/metal/has_neighborhood.hh: New. Provide a static assertion `has_neighborhood' for images. * mln/tag/skeleton.hh (mln::tag::neighb_): New tag. * mln/trait/ch_value.hh (trait::impl::ch_value_< M< tag::image_<I>, tag::neighb_<N> >, V >): New specialization for mln::neighb::image<I, N>. * tests/Makefile.am (SUBDIRS): Add neighb. * tests/neighb/Makefile.am: New. * tests/neighb/image.cc: New. Exercize mln/neighb/images.cc and mln/neighb/get.cc. mln/metal/has_neighborhood.hh | 53 +++++++++++ mln/neighb/get.hh | 194 ++++++++++++++++++++++++++++++++++++++++++ mln/neighb/image.hh | 191 +++++++++++++++++++++++++++++++++++++++++ mln/tag/skeleton.hh | 3 mln/trait/ch_value.hh | 10 +- tests/Makefile.am | 1 tests/neighb/Makefile.am | 10 ++ tests/neighb/image.cc | 59 ++++++++++++ 8 files changed, 519 insertions(+), 2 deletions(-) Index: mln/neighb/image.hh --- mln/neighb/image.hh (revision 0) +++ mln/neighb/image.hh (revision 0) @@ -0,0 +1,191 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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 MLN_NEIGHB_IMAGE_HH +# define MLN_NEIGHB_IMAGE_HH + +/// \file mln/neighb/image.hh +/// \brief An image morpher adding a neighborhood to an image. + +# include <mln/core/internal/image_identity.hh> +# include <mln/core/concept/neighborhood.hh> + + +namespace mln +{ + + // Fwd decl. + namespace neighb { template <typename I, typename N> struct image; } + + /// Create an image with a neighborhood from an image and a + /// neighborhood. + template <typename I, typename N> + neighb::image<I, N> + operator+ (Image<I>& ima, const Neighborhood<N>& nbh); + + + namespace internal + { + + /// \internal Data structure for mln::neighb::image + template <typename I, typename N> + struct data_< mln::neighb::image<I, N> > + { + data_(I& ima, const N& nbh); + + I ima_; + N nbh_; + }; + + } // end of namespace mln::internal + + + + namespace trait + { + + template <typename I, typename N> + struct image_< neighb::image<I, N> > + : public default_image_morpher_< I, mln_value(I), neighb::image<I, N> > + + { + typedef trait::image::category::morpher category; + + typedef trait::image::neighb::some neighb; + }; + + } // end of namespace mln::trait + + + namespace neighb + { + /// \brief A class that embodies an image with an attached + /// neighborhood. + /// + /// Parameter \c I is the actual type of the image, and \c N is + /// the one of the neighborhood. + /// + /// \pre The domains of \c I and \c N must be compatible. + template <typename I, typename N> + struct image + : public internal::image_identity_ < I, mln_pset(I), image <I, N> > + { + /// Point_Site associated type. + typedef mln_psite(I) psite; + + /// Point_Set associated type. + typedef mln_pset(I) pset; + + /// Neighborhood associated type. + typedef N neighb; + + /// Skeleton. + typedef image< tag::image_<I>, tag::neighb_<N> > skeleton; + + /// Constructor. + image(Image<I>& ima, const Neighborhood<N>& nbh); + + /// Test if this image has been initialized. + bool has_data() const; + + /// Return the neighborhood associated to this image. + const neighb& neighborhood() const; + }; + + } // end of namespace mln::neighb + + +# ifndef MLN_INCLUDE_ONLY + + /*------------. + | operator+. | + `------------*/ + + template <typename I, typename N> + neighb::image<I, N> + operator+ (Image<I>& ima, const Neighborhood<N>& nbh) + { + neighb::image<I, N> tmp(ima, nbh); + return tmp; + } + + /*--------------------------------------. + | internal::data_< cast_image_<T,I> >. | + `--------------------------------------*/ + + namespace internal + { + template <typename I, typename N> + inline + data_< neighb::image<I, N> >::data_(I& ima, const N& nbh) + : ima_(ima), + nbh_(nbh) + { + } + } + + /*----------------------. + | neighb::image<I, N>. | + `----------------------*/ + + namespace neighb + { + + template <typename I, typename N> + inline + image<I, N>::image(Image<I>& ima, const Neighborhood<N>& nbh) + { + this->data_ = + new mln::internal::data_< mln::neighb::image<I, N> >(exact(ima), + exact(nbh)); + } + + template <typename I, typename N> + inline + bool + image<I, N>::has_data() const + { + return this->delegatee_()->has_data(); + } + + template <typename I, typename N> + inline + const N& + image<I, N>::neighborhood() const + { + return this->data_->nbh_; + } + + } // end of namespace mln::neighb + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#include <mln/neighb/get.hh> + +#endif // ! MLN_NEIGHB_IMAGE_HH Index: mln/neighb/get.hh --- mln/neighb/get.hh (revision 0) +++ mln/neighb/get.hh (revision 0) @@ -0,0 +1,194 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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 MLN_NEIGHB_GET_HH +# define MLN_NEIGHB_GET_HH + +/// \file mln/neighb/get.hh +/// \brief Define function that returns the neighborhood assocoatied +/// to an image. + +# include <mln/trait/images.hh> +# include <mln/neighb/image.hh> + + +/// Shortcuts to access the neighborhood type associated to I. +/// \{ +# define mln_neighb(T) typename mln::neighb::get_helper<I>::type +# define mln_neighb_(T) mln::neighb::get_helper<I>::type +/// \} + + +namespace mln +{ + + namespace neighb + { + + // Fwd decl. + template <typename I> + struct get_helper; + + template <typename I> + typename get_helper<I>::type + get(const Image<I>& ima); + + + /// FIXME: Move this to mln/trait/neighb.hh? And split + /// neighborhood type deduction from neighborhood access (fun)? + + /// Get the (possible) neighborhood type associated to an image + /// type \c I. + template <typename I> + struct get_helper + { + /// Select the neighborhood from the presence of the + /// neighborhood and the category of the image. + /// { + + // FIXME: Rename select_from_traits. + + template <typename image_neighb, typename image_category, typename I_> + struct select_from_traits; + + /// Case where the image has a neighborhood and is a primary + /// image. + template <typename I_> + struct select_from_traits<trait::image::neighb::some, + trait::image::category::primary, + I_> + { + typedef typename I_::neighb type; + + static const type& + run(const I_& ima) { return ima.neighborhood(); } + }; + + /// Special case: neighb::image<I_, N_>. + template <typename I_, typename N_> + struct select_from_traits<trait::image::neighb::some, + trait::image::category::morpher, + mln::neighb::image<I_, N_> > + { + typedef typename neighb::image<I_, N_>::neighb type; + + static const type& + run(const neighb::image<I_, N_>& ima) { return ima.neighborhood(); } + }; + + /// Case where the image has a neighborhood and is a morpher. + template <typename I_> + struct select_from_traits<trait::image::neighb::some, + trait::image::category::morpher, + I_> + { + typedef typename get_helper<typename I_::delegatee>::type type; + + static const type& + run(const I_& ima) { return neighb::get( *ima.delegatee_() ); } + }; + + /// Case where the image has a neighborhood and is a identity morpher. + template <typename I_> + struct select_from_traits<trait::image::neighb::some, + trait::image::category::identity_morpher, + I_> + { + typedef typename get_helper<typename I_::delegatee>::type type; + + static const type& + run(const I_& ima) { return neighb::get( *ima.delegatee_() ); } + }; + + /// Case where the image has a neighborhood and is a value morpher. + template <typename I_> + struct select_from_traits<trait::image::neighb::some, + trait::image::category::value_morpher, + I_> + { + typedef typename get_helper<typename I_::delegatee>::type type; + + static const type& + run(const I_& ima) { return neighb::get( *ima.delegatee_() ); } + }; + + /// \brief Default case: error. + /// + /// Causes: + /// \li the image has no neighborhood; + /// \li the image category is of an invalid morpher type (e.g., + /// a domain morpher); + /// \li the trait for the neighborhood of the image is not + /// defined or ill-defined; + /// \li the trait for the image category is not defined or + /// ill-defined. + template <typename image_neighb, typename image_category, typename I_> + struct select_from_traits + { + /// Nothing. + }; + + /// \} + + typedef select_from_traits< mln_trait_image_neighb(I), + mln_trait_image_category(I), + I > selection_; + + typedef typename selection_::type type; + + static const type& run(const I& ima) { return selection_::run(ima); } + }; + + + +# ifndef MLN_INCLUDE_ONLY + + // Facade. + + template <typename I> + inline + typename get_helper<I>::type + get(const Image<I>& ima) + { + trace::entering("neighb::get"); + + mln_precondition(exact(ima).has_data()); + typename neighb::get_helper<I>::type res = + neighb::get_helper<I>::run(exact(ima)); + + trace::exiting("neighb::get"); + return res; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::neighb + +} // end of namespace mln + + +#endif // ! MLN_NEIGHB_GET_HH Index: mln/metal/has_neighborhood.hh --- mln/metal/has_neighborhood.hh (revision 0) +++ mln/metal/has_neighborhood.hh (revision 0) @@ -0,0 +1,53 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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 MLN_METAL_HAS_NEIGHBORHOOD_HH +# define MLN_METAL_HAS_NEIGHBORHOOD_HH + +# include <mln/neighb/get.hh> + +namespace mln +{ + + namespace metal + { + + template <typename I> + struct has_neighborhood + { + static void check() + { + // Ensure the image has a `neighb' property. + typedef mln_neighb(I) neighb; + } + }; + + } // end of namespace mln::metal + +} // end of namespace mln + +#endif // ! MLN_METAL_HAS_NEIGHBORHOOD_HH Index: mln/tag/skeleton.hh --- mln/tag/skeleton.hh (revision 1685) +++ mln/tag/skeleton.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -48,6 +48,7 @@ template <typename S> struct pset_ { typedef S param; }; template <typename D> struct data_ { typedef D param; }; template <typename F> struct function_ { typedef F param; }; + template <typename N> struct neighb_ { typedef N param; }; // With value. template <unsigned u> struct unsigned_ { enum { value = u }; }; Index: mln/trait/ch_value.hh --- mln/trait/ch_value.hh (revision 1685) +++ mln/trait/ch_value.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -109,6 +109,14 @@ typedef mln_ch_value(I, V) ret; }; + // For mln::neighb::image<I, N>. + template < template <class, class> class M, typename I, typename N, + typename V > + struct ch_value_< M< tag::image_<I>, tag::neighb_<N> >, V > + { + typedef M < mln_ch_value(I, V), N > ret; + }; + template < template <class, class> class M, typename I, typename S, typename V > struct ch_value_< M< tag::image_<I>, tag::pset_<S> >, V > Index: tests/Makefile.am --- tests/Makefile.am (revision 1685) +++ tests/Makefile.am (working copy) @@ -18,6 +18,7 @@ level \ logical \ morpho \ + neighb \ norm \ set \ util \ Index: tests/neighb/image.cc --- tests/neighb/image.cc (revision 0) +++ tests/neighb/image.cc (revision 0) @@ -0,0 +1,59 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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. + +/*! \file tests/neighb/image.cc + * + * \brief Tests on mln::neighb::image. + */ + +#include <mln/neighb/image.hh> +#include <mln/core/image2d.hh> +#include <mln/core/neighb2d.hh> +#include <mln/metal/has_neighborhood.hh> + + +int main() +{ + using namespace mln; + + typedef image2d<int> ima_t; + typedef neighb2d nbh_t; + + typedef neighb::image<ima_t, nbh_t> ima_with_nbh_t; + + metal::has_neighborhood<ima_with_nbh_t>::check(); + + ima_t ima (make::box2d(5, 5)); + + // Explicit construction. + ima_with_nbh_t ima1 (ima, c4()); + neighb::get(ima1); + + // Construction using operator+. + ima_with_nbh_t ima2 = ima + c4(); + neighb::get(ima2); +} Index: tests/neighb/Makefile.am --- tests/neighb/Makefile.am (revision 0) +++ tests/neighb/Makefile.am (revision 0) @@ -0,0 +1,10 @@ +## Process this file through Automake to create Makefile.in -*- Makefile -*- + +include $(top_srcdir)/milena/tests/tests.mk + +check_PROGRAMS = \ + image + +image_SOURCES = image.cc + +TESTS = $(check_PROGRAMS)