
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Playing with runs, several update, and some bug fixes. Prefer a value type as parameter over a value set type. * mln/core/p_vaccess.hh (todo): Remove; done: (internal): Move material in... * mln/core/internal/site_set_impl.hh: ...this new file. (p_vaccess_impl__nsites, p_vaccess_impl__bbox), (p_vaccess_impl): Rename as... (site_set_impl__nsites, site_set_impl__bbox), (site_set_impl): ...these. * mln/core/p_vaccess.hh (clear): New method. (Sp): Rename as... (S): ...this. (Sv): Change this parameter into... (V): ...this one and update. The semantics of this parameter is now a value type (no more a value set type). That is an idea to generalize. To every value type V is associated the value set type mln::value::set<V>. That will simplify a lot of code in different parts of the library. Propagate. * mln/core/p_set_of.hh (nelements, clear): New methods. (todo): Remove; done: (site_set_impl): New inheritance. (nsites, bbox): Update properties. (insert): Update code. * mln/core/concept/site_set.hh (clear): New expected method when the contents property is 'dynamic'. (element): Add static check. * mln/core/box.hh (P): Add static check. (element): New typedef. * mln/core/p_mutable_array_of.hh (nelements); New method. (clear): Fix missing method. (is_empty_): Add this overriding so that 'is_empty' works. * mln/core/p_array.hh (clear): Fix missing postcondition. * mln/core/sparse_image.hh (todo): Remove; done: (p_run_set): Replace by... (p_set_of<p_run<P>>): ...this type. Add aliases. * mln/core/alias: New directory. * mln/core/alias/p_run2d.hh: New. * mln/core/alias/p_runs2d.hh: New. Introduce a general converter. * mln/convert/to_p_run_set.hh: Remove; obsolete because replace by a more generic new mechanism: * mln/convert/impl: New directory. * mln/convert/impl/from_image_to_site_set.hh: New. * mln/convert/impl/all.hh: New. * mln/convert/from_to.hh: New. * mln/convert/all.hh: Update. Update tutorial examples. * doc/tutorial/examples/p_run_set.cc: Rename as... * doc/tutorial/examples/p_run.cc: ...this. Update. * doc/tutorial/examples/p_vaccess.cc, * doc/tutorial/examples/p_mutable_array_of.cc: Update. Now bench. The result is twofold: - p_set_of<p_run<P>> is as fast as the deprecated p_run_set<P>; - the dedicated iterators (in my sandbox) are twice as fast as the general ones (the p_double_* stuff); yet such a difference is not so significant! * mln/core/p_runs.hh (clear): New method; just to be able to bench! * sandbox/geraud/p_runs__with_dedicated_piter.hh (clear): New method. * doc/benchmark/p_runs.cc: Update. Misc. * doc/tutorial/examples/proxy.cc: Update/fix. * mln/core/image2d.hh (alt): Fix missing update. * doc/benchmark/image2d.cc: Likewise. * mln/core/internal/site_set_base.hh (S): Fix typo; rename as... (P): ...this. * mln/core/macros.hh (mln_i_element, mln_i_element_), (mln_r_element, mln_r_element_): New macros. * mln/core/pset_if.hh (is_valid, memory_size): Fix missing methods. * mln/core/pset_if_piter.hh (pi_change_target_): Fix sig. * mln/labeling/blobs.hh (todo): New. (blobs): Add a test on label overflow. * mln/trait/image/status.txt: Fix missing image type. doc/benchmark/image2d.cc | 4 doc/benchmark/p_runs.cc | 47 +++- doc/tutorial/examples/p_mutable_array_of.cc | 59 +---- doc/tutorial/examples/p_run.cc | 21 + doc/tutorial/examples/p_vaccess.cc | 56 ++-- doc/tutorial/examples/proxy.cc | 4 mln/convert/all.hh | 4 mln/convert/from_to.hh | 102 ++++++++ mln/convert/impl/all.hh | 40 +++ mln/convert/impl/from_image_to_site_set.hh | 148 ++++++++++++ mln/core/alias/p_run2d.hh | 50 ++++ mln/core/alias/p_runs2d.hh | 50 ++++ mln/core/box.hh | 8 mln/core/concept/site_set.hh | 15 + mln/core/image2d.hh | 7 mln/core/internal/site_set_base.hh | 14 - mln/core/internal/site_set_impl.hh | 201 +++++++++++++++++ mln/core/macros.hh | 12 + mln/core/p_array.hh | 1 mln/core/p_mutable_array_of.hh | 35 +++ mln/core/p_runs.hh | 14 + mln/core/p_set_of.hh | 35 ++- mln/core/p_vaccess.hh | 289 ++++++------------------- mln/core/pset_if.hh | 38 ++- mln/core/pset_if_piter.hh | 2 mln/core/sparse_image.hh | 19 - mln/labeling/blobs.hh | 7 mln/trait/image/status.txt | 1 sandbox/geraud/p_runs__with_dedicated_piter.hh | 16 + 29 files changed, 962 insertions(+), 337 deletions(-) Index: doc/tutorial/examples/p_vaccess.cc --- doc/tutorial/examples/p_vaccess.cc (revision 2154) +++ doc/tutorial/examples/p_vaccess.cc (working copy) @@ -7,8 +7,12 @@ # include <mln/util/timer.hh> # include <mln/labeling/blobs.hh> +# include <mln/core/alias/p_runs2d.hh> # include <mln/core/p_vaccess.hh> -# include <mln/convert/to_p_run_set.hh> +# include <mln/core/image_if.hh> +# include <mln/pw/all.hh> +# include <mln/convert/from_to.hh> + template <typename I, typename S> @@ -39,7 +43,7 @@ unsigned n; { - typedef p_vaccess< value::set<bool>, p_array<point2d> > Arr; + typedef p_vaccess<bool, p_array<point2d> > Arr; mlc_equal(Arr::element, point2d)::check(); Arr arr; fill(arr, ima); @@ -56,35 +60,37 @@ debug::println(lab); { - typedef p_vaccess< value::set<int_u8>, p_run_set<point2d> > Arr; - mlc_equal(Arr::element, p_run<point2d>)::check(); + typedef p_vaccess<int_u8, p_runs2d> Arr; + mlc_equal(Arr::element, p_run2d)::check(); Arr arr; - convert::impl::fill_p_run_set_(arr, lab); + convert::from_to(lab | (pw::value(lab) != pw::cst(0u)), arr); mln_assertion(arr.nsites() == n); - for (unsigned l = 1; l <= nlabels; ++l) + for (unsigned l = 0; l <= nlabels; ++l) { - mln_assertion(! arr(l).is_empty()); - std::cout << l << ": #" - << arr(l).nsites() << " in " - << arr(l).bbox() << std::endl; + std::cout << l << ": #" << arr(l).nsites(); + if (! arr(l).is_empty()) + std::cout << " in " << arr(l).bbox(); + std::cout << std::endl; + } + std::cout << std::endl; + } + + { + p_runs2d rs; + convert::from_to(ima, rs); + mln_assertion(rs.bbox() == ima.bbox()); + + image2d<int_u8> ima_(ima.domain()); + level::fill(ima_, 0); + for (unsigned r = 0; r < rs.nelements(); ++r) + { + mln_piter_(p_run2d) p(rs[r]); + for_all(p) + ima_(p) = r + 1; } + debug::println(ima_); } -// p_run_set<point2d> rs = convert::to_p_run_set(ima); -// std::cout << rs.zratio() << std::endl; -// std::cout << rs.bbox() << std::endl; - - -// image2d<value::int_u8> ima_(ima.domain()); -// level::fill(ima_, 0); -// for (unsigned r = 0; r < rs.nruns(); ++r) -// { -// mln_piter_(p_run<point2d>) p(rs.run(r)); -// for_all(p) -// ima_(p) = r + 1; -// } -// debug::println(ima_); -// io::pgm::save(ima_, "tmp.pgm"); } Index: doc/tutorial/examples/proxy.cc --- doc/tutorial/examples/proxy.cc (revision 2154) +++ doc/tutorial/examples/proxy.cc (working copy) @@ -38,10 +38,8 @@ { mln_psite_(Arr1) p(arr1, 0); std::cout << p << ' ' << arr1[0] << std::endl; - point2d& v = unproxy_rec(p); + std::cout << &(arr1[0]) << ' ' << &(unproxy_rec(p)) << std::endl; - unproxy_rec(p).row() = 12; - mln_assertion(arr1[0].row() != 12); // FIXME: that's normal! std::cout << p.get_subject() << std::endl; std::cout << p.to_site() << std::endl; Index: doc/tutorial/examples/p_run.cc --- doc/tutorial/examples/p_run.cc (revision 2154) +++ doc/tutorial/examples/p_run.cc (working copy) @@ -1,8 +1,10 @@ # include <mln/core/image2d.hh> -# include <mln/debug/println.hh> -# include <mln/convert/to_p_run_set.hh> +# include <mln/core/alias/p_run2d.hh> +# include <mln/core/p_set_of.hh> -# include <mln/core/sparse_image.hh> +# include <mln/convert/from_to.hh> +# include <mln/debug/println.hh> +// # include <mln/core/sparse_image.hh> template <typename I> @@ -20,7 +22,7 @@ { using namespace mln; - typedef p_run_set<point2d> Runs; + typedef p_set_of<p_run2d> Runs; bool vals[6][5] = { {1, 1, 1, 1, 1}, @@ -33,13 +35,14 @@ image2d<bool> ima = make::image2d(vals); debug::println(ima); - Runs rs = convert::to_p_run_set(ima); + Runs rs; + convert::from_to(ima, rs); std::cout << rs << std::endl; - mln_assertion(rs.nruns() == 8); + mln_assertion(rs.nelements() == 8); mln_assertion(rs.nsites() == 16); - mln_assertion(rs.zratio() < 1); +// mln_assertion(rs.zratio() < 1); - sparse_image<point2d,int> ima_(rs); - display(ima_); +// sparse_image<point2d,int> ima_(rs); +// display(ima_); } Index: doc/tutorial/examples/p_mutable_array_of.cc --- doc/tutorial/examples/p_mutable_array_of.cc (revision 2154) +++ doc/tutorial/examples/p_mutable_array_of.cc (working copy) @@ -1,58 +1,25 @@ # include <mln/core/image2d.hh> -# include <mln/debug/println.hh> # include <mln/core/p_mutable_array_of.hh> # include <mln/core/p_run.hh> +# include <mln/convert/from_to.hh> - - -namespace mln -{ - - - template <typename I, typename S> - void - convert_to_runs(const Image<I>& input_, Site_Set<S>& s_) - { - typedef mln_site(I) P; - mlc_is(mln_element(S), p_run<P>)::check(); - - const I& input = exact(input_); - S& s = exact(s_); - mln_precondition(input.has_data()); - - mln_fwd_piter(I) p(input.domain()); - p.start(); - for (;;) - { - // Skip background. - while (p.is_valid() && input(p) == false) - p.next(); - if (! p.is_valid()) // The end. - break; - mln_invariant(input(p) == true); - P start = p, q; - // Go to run end. - do - { - q = p; - p.next(); - } - while (p.is_valid() && input(p) == true && p == q + right); - s.insert(p_run<P>(start, q)); - } - } - -} // mln - +// Used by display. +# include <mln/geom/bbox.hh> +# include <mln/debug/println.hh> +# include <mln/core/sub_image.hh> template <typename S> void display(const S& s) { + using namespace mln; + + image2d<unsigned> ima(geom::bbox(s)); mln_fwd_piter(S) p(s); + unsigned c = 0; for_all(p) - std::cout << p << ' '; - std::cout << std::endl; + ima(p) = ++c; + debug::println(ima | s); } @@ -73,8 +40,10 @@ typedef p_mutable_array_of< p_run<point2d> > Runs; Runs rs; - convert_to_runs(ima, rs); + convert::from_to(ima, rs); std::cout << rs << std::endl; display(rs); + + // FIXME: Use the "mutable" feature of rs... } Index: doc/benchmark/p_runs.cc --- doc/benchmark/p_runs.cc (revision 2154) +++ doc/benchmark/p_runs.cc (working copy) @@ -1,8 +1,13 @@ # include <mln/io/pbm/load.hh> # include <mln/core/image2d.hh> -# include <mln/convert/to_p_runs.hh> +# include <mln/core/alias/p_run2d.hh> +# include <mln/core/p_set_of.hh> +# include <mln/convert/from_to.hh> # include <mln/util/timer.hh> +# include <sandbox/geraud/p_runs__with_dedicated_piter.hh> + + const unsigned n_times = 32; @@ -44,11 +49,39 @@ image2d<bool> ima; io::pbm::load(ima, "../../img/lena.pbm"); - p_runs<point2d> rs = convert::to_p_runs(ima); - mln_assertion(rs.zratio() < 1); + unsigned c; + std::cout << "ref: " << browse_ima(ima, c) << std::endl; + + { + util::timer t; + t.start(); + + // Conversion. + p_set_of<p_run2d> rs; + convert::from_to(ima, rs); + std::cout << "enc: " << t.read() << std::endl; + // FIXME: mln_assertion(rs.zratio() < 1); + + // Browsing. + unsigned cr; + std::cout << "brs: " << browse_runs(rs, cr) << std::endl; + mln_assertion(cr == c); + } + + { + util::timer t; + t.start(); + + // Conversion. + p_runs<point2d> rs; + convert::from_to(ima, rs); + std::cout << "enc: " << t.read() << std::endl; + // FIXME: mln_assertion(rs.zratio() < 1); + + // Browsing. + unsigned cr; + std::cout << "brs: " << browse_runs(rs, cr) << std::endl; + mln_assertion(cr == c); + } - unsigned c1, c2; - std::cout << browse_ima(ima, c1) << std::endl; - std::cout << browse_runs(rs, c2) << std::endl; - mln_assertion(c2 == c1); } Index: doc/benchmark/image2d.cc --- doc/benchmark/image2d.cc (revision 2154) +++ doc/benchmark/image2d.cc (working copy) @@ -60,7 +60,7 @@ int** array = data.array_; mln::point2d p; - int & row = p.row(), & col = p.col(); + mln::def::coord & row = p.row(), & col = p.col(); for (row = 0; row < size; ++row) for (col = 0; col < size; ++col) array[row][col] = 0; @@ -77,7 +77,7 @@ mln::util::timer t; t.start(); mln::point2d p; - int & row = p.row(), & col = p.col(); + mln::def::coord & row = p.row(), & col = p.col(); for (row = 0; row < size; ++row) for (col = 0; col < size; ++col) ima.at(row, col) = 0; Index: mln/trait/image/status.txt --- mln/trait/image/status.txt (revision 2154) +++ mln/trait/image/status.txt (working copy) @@ -40,6 +40,7 @@ ** value morpher KO cast_image +KO value::stack_image ** domain morpher Index: mln/core/macros.hh --- mln/core/macros.hh (revision 2154) +++ mln/core/macros.hh (working copy) @@ -181,6 +181,12 @@ // i +/// Shortcuts to access the insertion-element type associated to T. +/// \{ +# define mln_i_element(T) typename T::i_element +# define mln_i_element_(T) T::i_element +/// \} + /// Shortcuts to access the image type associated to T. /// \{ # define mln_image(T) typename T::image @@ -285,6 +291,12 @@ // r +/// Shortcuts to access the removal-element type associated to T. +/// \{ +# define mln_r_element(T) typename T::r_element +# define mln_r_element_(T) T::r_element +/// \} + /// Shortcuts to access the result type associated to T. /// \{ # define mln_result(T) typename T::result Index: mln/core/internal/site_set_impl.hh --- mln/core/internal/site_set_impl.hh (revision 0) +++ mln/core/internal/site_set_impl.hh (revision 0) @@ -0,0 +1,201 @@ +// Copyright (C) 2008 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 MLN_CORE_INTERNAL_SITE_SET_IMPL_HH +# define MLN_CORE_INTERNAL_SITE_SET_IMPL_HH + +/// \internal \file mln/core/internal/site_set_impl.hh +/// Provide implementation for optional site set methods. + +# include <mln/core/concept/site_set.hh> +# include <mln/accu/bbox.hh> + + + +namespace mln +{ + + namespace internal + { + + /// \internal The facade. + /// Parameter \c Sc is the site set component. + template <typename Sc> + struct site_set_impl; + + + + // For .nsites() + + template <typename trait_nsites, typename Sc> + struct site_set_impl__nsites + { + protected: + template <typename T> + void update_nsites_(const T&); // No-op. + }; + + template <typename Sc> + struct site_set_impl__nsites< trait::site_set::nsites::known, Sc> + { + site_set_impl__nsites(); + unsigned nsites() const; + protected: + void update_nsites_(const mln_site(Sc)& p); + template <typename S> + void update_nsites_(const Site_Set<S>& s); + unsigned nsites_; + }; + + + // For .bbox() + + template <typename trait_bbox, typename Sc> + struct site_set_impl__bbox + { + typedef const mln::box<mln_site(Sc)>& q_box; + q_box bbox() const; + + protected: + void update_bbox_(const mln_site(Sc)& p); + template <typename S> + void update_bbox_(const Site_Set<S>& s); + + accu::bbox<mln_site(Sc)> bb_; + }; + + template <typename Sc> + struct site_set_impl__bbox< trait::site_set::nsites::unknown, Sc > + { + protected: + template <typename T> + void update_bbox_(const T&); // No-op. + }; + + + // Facade. + + template <typename Sc> + struct site_set_impl + : site_set_impl__nsites< mln_trait_site_set_nsites(Sc), Sc>, + site_set_impl__bbox < mln_trait_site_set_bbox(Sc), Sc> + { + }; + + + + +# ifndef MLN_INCLUDE_ONLY + + + // site_set_impl__nsites + + template <typename trait_nsites, typename Sc> + template <typename T> + inline + void + site_set_impl__nsites<trait_nsites, Sc>::update_nsites_(const T&) + { + // No-op. + } + + template <typename Sc> + inline + site_set_impl__nsites<trait::site_set::nsites::known, Sc>::site_set_impl__nsites() + : nsites_(0) + { + } + + template <typename Sc> + inline + unsigned + site_set_impl__nsites<trait::site_set::nsites::known, Sc>::nsites() const + { + return nsites_; + } + + template <typename Sc> + inline + void + site_set_impl__nsites<trait::site_set::nsites::known, Sc>::update_nsites_(const mln_site(Sc)&) + { + ++nsites_; + } + + template <typename Sc> + template <typename S> + inline + void + site_set_impl__nsites<trait::site_set::nsites::known, Sc>::update_nsites_(const Site_Set<S>& s) + { + nsites_ += exact(s).nsites(); + } + + // site_set_impl__bbox + + template <typename trait_bbox, typename Sc> + inline + typename site_set_impl__bbox<trait_bbox, Sc>::q_box + site_set_impl__bbox<trait_bbox, Sc>::bbox() const + { + return bb_.to_result(); + } + + template <typename trait_bbox, typename Sc> + inline + void + site_set_impl__bbox<trait_bbox, Sc>::update_bbox_(const mln_site(Sc)& p) + { + bb_.take(p); + } + + template <typename trait_bbox, typename Sc> + template <typename S> + inline + void + site_set_impl__bbox<trait_bbox, Sc>::update_bbox_(const Site_Set<S>& s) + { + bb_.take(exact(s).bbox()); + } + + template <typename Sc> + template <typename T> + inline + void + site_set_impl__bbox< trait::site_set::nsites::unknown, Sc >::update_bbox_(const T&) + { + // No-op. + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_SITE_SET_IMPL_HH Index: mln/core/internal/site_set_base.hh --- mln/core/internal/site_set_base.hh (revision 2154) +++ mln/core/internal/site_set_base.hh (working copy) @@ -72,25 +72,27 @@ # ifndef MLN_INCLUDE_ONLY - template <typename S, typename E> + template <typename P, typename E> inline - site_set_base_<S,E>::site_set_base_() + site_set_base_<P,E>::site_set_base_() { } - template <typename S, typename E> + template <typename P, typename E> inline bool - site_set_base_<S,E>::is_empty() const + site_set_base_<P,E>::is_empty() const { return exact(this)->is_empty_(); } - template <typename S, typename E> + template <typename P, typename E> inline bool - site_set_base_<S,E>::is_empty_() const + site_set_base_<P,E>::is_empty_() const { + mlc_is(mln_trait_site_set_nsites(E), + trait::site_set::nsites::known)::check(); return exact(this)->nsites() == 0; } Index: mln/core/p_set_of.hh --- mln/core/p_set_of.hh (revision 2154) +++ mln/core/p_set_of.hh (working copy) @@ -31,12 +31,11 @@ /*! \file mln/core/p_set_of.hh * * \brief Definition of a set of site sets. - * - * \todo Zed: Add nsites and bbox when possible (see p_vaccess). */ # include <mln/core/p_double.hh> # include <mln/core/internal/site_set_base.hh> +# include <mln/core/internal/site_set_impl.hh> # include <mln/util/set.hh> @@ -54,8 +53,8 @@ template <typename S> struct site_set_< p_set_of<S> > { - typedef trait::site_set::nsites::unknown nsites; - typedef trait::site_set::bbox::unknown bbox; + typedef mln_trait_site_set_nsites(S) nsites; + typedef mln_trait_site_set_bbox(S) bbox; typedef trait::site_set::contents::growing contents; typedef trait::site_set::arity::multiple arity; }; @@ -71,6 +70,7 @@ template <typename S> class p_set_of : public internal::site_set_base_< mln_element(S), p_set_of<S> >, + public internal::site_set_impl<S>, private mlc_is_a(S, Site_Set)::check_t { typedef p_set_of<S> self_; @@ -119,6 +119,13 @@ /// Return the \p i-th site set. const S& operator[](unsigned i) const; + /// Give the number of elements (site sets) of this composite. + unsigned nelements() const; + + + /// Clear this set. + void clear(); + /// Return the size of this site set in memory. std::size_t memory_size() const; @@ -176,7 +183,9 @@ void p_set_of<S>::insert(const S& s) { - s_.append(s); + s_.insert(s); + this->update_nsites_(s); + this->update_bbox_(s); } template <typename S> @@ -188,6 +197,22 @@ return s_[i]; } + template <typename S> + inline + unsigned + p_set_of<S>::nelements() const + { + return s_.nelements(); + } + + template <typename S> + inline + void + p_set_of<S>::clear() + { + s_.clear(); + mln_postcondition(this->is_empty()); + } template <typename S> inline Index: mln/core/p_vaccess.hh --- mln/core/p_vaccess.hh (revision 2154) +++ mln/core/p_vaccess.hh (working copy) @@ -30,10 +30,6 @@ /*! \file mln/core/p_vaccess.hh * - * \todo Factor the implementation classes for site set based on a - * couple of structures. Such piece of code shall be used in p_set_of - * and p_array_of. - * * \todo Fix the FIXMEs. */ @@ -41,7 +37,8 @@ # include <mln/core/p_double.hh> # include <mln/core/internal/site_set_base.hh> # include <mln/core/internal/pseudo_site_base.hh> -# include <mln/accu/bbox.hh> +# include <mln/core/internal/site_set_impl.hh> +# include <mln/value/set.hh> @@ -49,18 +46,18 @@ { // Forward declaration. - template <typename Sv, typename Sp> class p_vaccess; + template <typename V, typename S> class p_vaccess; namespace trait { - template <typename Sv, typename Sp> - struct site_set_< p_vaccess<Sv,Sp> > + template <typename V, typename S> + struct site_set_< p_vaccess<V,S> > { - typedef mln_trait_site_set_nsites(Sp) nsites; - typedef mln_trait_site_set_bbox(Sp) bbox; + typedef mln_trait_site_set_nsites(S) nsites; + typedef mln_trait_site_set_bbox(S) bbox; typedef trait::site_set::contents::growing contents; typedef trait::site_set::arity::multiple arity; }; @@ -69,90 +66,31 @@ - namespace internal - { - - // For .nsites() - - template <typename trait_nsites, typename Sp> - struct p_vaccess_impl__nsites - { - protected: - template <typename T> - void update_nsites_(const T&); // No-op. - }; - - template <typename Sp> - struct p_vaccess_impl__nsites< trait::site_set::nsites::known, Sp> - { - p_vaccess_impl__nsites(); - unsigned nsites() const; - protected: - void update_nsites_(const mln_site(Sp)& p); - template <typename S> - void update_nsites_(const Site_Set<S>& s); - unsigned nsites_; - }; - - // For .bbox() - - template <typename trait_bbox, typename Sp> - struct p_vaccess_impl__bbox - { - typedef const mln::box<mln_site(Sp)>& q_box; - q_box bbox() const; - - protected: - void update_bbox_(const mln_site(Sp)& p); - template <typename S> - void update_bbox_(const Site_Set<S>& s); - - accu::bbox<mln_site(Sp)> bb_; - }; - - template <typename Sp> - struct p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp > - { - protected: - template <typename T> - void update_bbox_(const T&); // No-op. - }; - - // Facade. - - template <typename Sp> - struct p_vaccess_impl - : p_vaccess_impl__nsites< mln_trait_site_set_nsites(Sp), Sp>, - p_vaccess_impl__bbox < mln_trait_site_set_bbox(Sp), Sp> - { - }; - - } // end of namespace mln::internal - - - /*! \brief FIXME */ - template <typename Sv, typename Sp> - class p_vaccess : public internal::site_set_base_< mln_site(Sp), - p_vaccess<Sv,Sp> >, - public internal::p_vaccess_impl< Sp > + template <typename V, typename S> + class p_vaccess : public internal::site_set_base_< mln_site(S), + p_vaccess<V,S> >, + public internal::site_set_impl< S > { - typedef p_vaccess<Sv,Sp> self_; + typedef p_vaccess<V,S> self_; public: /// Value associated type. - typedef mln_value(Sv) value; + typedef V value; + + /// Value_Set associated type. + typedef mln::value::set<V> vset; /// Psite associated type. - typedef p_double_psite<self_, Sp> psite; + typedef p_double_psite<self_, S> psite; /// Forward Site_Iterator associated type. - typedef p_double_piter<self_, mln_fwd_viter(Sv), mln_fwd_piter(Sp)> fwd_piter; + typedef p_double_piter<self_, mln_fwd_viter(vset), mln_fwd_piter(S)> fwd_piter; /// Backward Site_Iterator associated type. - typedef p_double_piter<self_, mln_bkd_viter(Sv), mln_bkd_piter(Sp)> bkd_piter; + typedef p_double_piter<self_, mln_bkd_viter(vset), mln_bkd_piter(S)> bkd_piter; /// Site_Iterator associated type. typedef fwd_piter piter; @@ -160,7 +98,7 @@ /// Constructor. p_vaccess(); - p_vaccess(const Sv& vset); + p_vaccess(const V& vset); /// Test if \p p belongs to this site set. @@ -168,43 +106,47 @@ /// Test if the couple (value \p v, psite \p p) belongs to this /// site set. - bool has(const value& v, const mln_psite(Sp)& p) const; + bool has(const V& v, const mln_psite(S)& p) const; /// Test if this site set is valid. bool is_valid() const; /// Element associated type. - typedef mln_element(Sp) element; + typedef mln_element(S) element; /// Insertion element associated type. - typedef std::pair<value, element> i_element; + typedef std::pair<V, element> i_element; /// Insert a pair \p v_e (value v, element e). void insert(const i_element& v_e); /// Insert \p e at value \p v. - void insert(const value& v, const element& e); + void insert(const V& v, const element& e); + + + // Clear this set. + void clear(); + /// Give the set of values. + const mln::value::set<V>& values() const; + /// Return the site set at value \p v. - const Sp& operator()(const value& v) const; + const S& operator()(const V& v) const; + /// Return the size of this site set in memory. std::size_t memory_size() const; - - /// Give the set of values. - const Sv& values() const; - // Required by p_double-related classes. - const Sv& set_1_() const; - const Sp& set_2_(const value& v) const; + const V& set_1_() const; + const S& set_2_(const V& v) const; protected: - Sv vs_; - std::vector<Sp> ps_; + mln::value::set<V> vs_; + std::vector<S> ps_; }; @@ -213,197 +155,122 @@ # ifndef MLN_INCLUDE_ONLY - // p_vaccess<Sv,Sp> + // p_vaccess<V,S> - template <typename Sv, typename Sp> + template <typename V, typename S> inline - p_vaccess<Sv,Sp>::p_vaccess() + p_vaccess<V,S>::p_vaccess() : vs_(), ps_(vs_.nvalues()) { } - template <typename Sv, typename Sp> + template <typename V, typename S> inline - p_vaccess<Sv,Sp>::p_vaccess(const Sv& vset) + p_vaccess<V,S>::p_vaccess(const V& vset) : vs_(vset), ps_(vs_.nvalues()) { } - template <typename Sv, typename Sp> + template <typename V, typename S> inline bool - p_vaccess<Sv,Sp>::has(const psite&) const + p_vaccess<V,S>::has(const psite&) const { // FIXME return true; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline bool - p_vaccess<Sv,Sp>::has(const value& v, const mln_psite(Sp)& p) const + p_vaccess<V,S>::has(const V& v, const mln_psite(S)& p) const { return ps_[vs_.index_of(v)].has(p); } - template <typename Sv, typename Sp> + template <typename V, typename S> inline bool - p_vaccess<Sv,Sp>::is_valid() const + p_vaccess<V,S>::is_valid() const { // FIXME return true; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline void - p_vaccess<Sv,Sp>::insert(const value& v, const element& e) + p_vaccess<V,S>::insert(const V& v, const element& e) { ps_[vs_.index_of(v)].insert(e); this->update_nsites_(e); this->update_bbox_(e); } - template <typename Sv, typename Sp> + template <typename V, typename S> inline void - p_vaccess<Sv,Sp>::insert(const i_element& v_e) + p_vaccess<V,S>::insert(const i_element& v_e) { insert(v_e.first, v_e.second); } - template <typename Sv, typename Sp> + template <typename V, typename S> inline - const Sp& - p_vaccess<Sv,Sp>::operator()(const value& v) const + void + p_vaccess<V,S>::clear() + { + const unsigned n = ps_.size(); + for (unsigned i = 0; i < n; ++i) + ps_[i].clear(); + } + + template <typename V, typename S> + inline + const S& + p_vaccess<V,S>::operator()(const V& v) const { return ps_[vs_.index_of(v)]; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline std::size_t - p_vaccess<Sv,Sp>::memory_size() const + p_vaccess<V,S>::memory_size() const { std::size_t mem = 0; - for (unsigned i = 0; i < ps_.size(); ++i) + const unsigned n = ps_.size(); + for (unsigned i = 0; i < n; ++i) mem += ps_[i].memory_size(); return sizeof(*this) + mem; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline - const Sv& - p_vaccess<Sv,Sp>::values() const + const mln::value::set<V>& + p_vaccess<V,S>::values() const { return vs_; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline - const Sv& - p_vaccess<Sv,Sp>::set_1_() const + const V& + p_vaccess<V,S>::set_1_() const { return vs_; } - template <typename Sv, typename Sp> + template <typename V, typename S> inline - const Sp& - p_vaccess<Sv,Sp>::set_2_(const value& v) const + const S& + p_vaccess<V,S>::set_2_(const V& v) const { return ps_[vs_.index_of(v)]; } - - namespace internal - { - - // p_vaccess_impl__nsites - - template <typename trait_nsites, typename Sp> - template <typename T> - inline - void - p_vaccess_impl__nsites<trait_nsites, Sp>::update_nsites_(const T&) - { - // No-op. - } - - template <typename Sp> - inline - p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::p_vaccess_impl__nsites() - : nsites_(0) - { - } - - template <typename Sp> - inline - unsigned - p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::nsites() const - { - return nsites_; - } - - template <typename Sp> - inline - void - p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::update_nsites_(const mln_site(Sp)&) - { - ++nsites_; - } - - template <typename Sp> - template <typename S> - inline - void - p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::update_nsites_(const Site_Set<S>& s) - { - nsites_ += exact(s).nsites(); - } - - // p_vaccess_impl__bbox - - template <typename trait_bbox, typename Sp> - inline - typename p_vaccess_impl__bbox<trait_bbox, Sp>::q_box - p_vaccess_impl__bbox<trait_bbox, Sp>::bbox() const - { - return bb_.to_result(); - } - - template <typename trait_bbox, typename Sp> - inline - void - p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const mln_site(Sp)& p) - { - bb_.take(p); - } - - template <typename trait_bbox, typename Sp> - template <typename S> - inline - void - p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const Site_Set<S>& s) - { - bb_.take(exact(s).bbox()); - } - - template <typename Sp> - template <typename T> - inline - void - p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp >::update_bbox_(const T&) - { - // No-op. - } - - } // end of namespace mln::internal - - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/alias/p_run2d.hh --- mln/core/alias/p_run2d.hh (revision 0) +++ mln/core/alias/p_run2d.hh (revision 0) @@ -0,0 +1,50 @@ +// Copyright (C) 2008 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 MLN_CORE_ALIAS_P_RUN2D_HH +# define MLN_CORE_ALIAS_P_RUN2D_HH + +/*! \file mln/core/alias/p_run2d.hh + * + * \brief Definition of the mln::p_run2d alias. + */ + +# include <mln/core/p_run.hh> +# include <mln/core/point2d.hh> + + +namespace mln +{ + + /// Type alias for a run of 2d points. + typedef p_run<point2d> p_run2d; + + +} // end of namespace mln + + +#endif // ! MLN_CORE_ALIAS_P_RUN2D_HH Index: mln/core/alias/p_runs2d.hh --- mln/core/alias/p_runs2d.hh (revision 0) +++ mln/core/alias/p_runs2d.hh (revision 0) @@ -0,0 +1,50 @@ +// Copyright (C) 2008 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 MLN_CORE_ALIAS_P_RUNS2D_HH +# define MLN_CORE_ALIAS_P_RUNS2D_HH + +/*! \file mln/core/alias/p_runs2d.hh + * + * \brief Definition of the mln::p_runs2d alias. + */ + +# include <mln/core/alias/p_run2d.hh> +# include <mln/core/p_set_of.hh> + + +namespace mln +{ + + /// Type alias for a set of runs of 2d points. + typedef p_set_of<p_run2d> p_runs2d; + + +} // end of namespace mln + + +#endif // ! MLN_CORE_ALIAS_P_RUNS2D_HH Index: mln/core/pset_if_piter.hh --- mln/core/pset_if_piter.hh (revision 2154) +++ mln/core/pset_if_piter.hh (working copy) @@ -118,7 +118,7 @@ template <typename Pi, typename S, typename F> inline void - pset_if_piter_<Pi,S,F>::pi_change_target_(const pset_if<S,F>& s) const + pset_if_piter_<Pi,S,F>::pi_change_target_(const pset_if<S,F>& s) { pi_.change_target(s.overset()); } Index: mln/core/box.hh --- mln/core/box.hh (revision 2154) +++ mln/core/box.hh (working copy) @@ -73,12 +73,16 @@ */ template <typename P> struct box : public Box< box<P> >, - public internal::box_impl_< P::dim, mln_coord(P), box<P> > + public internal::box_impl_< P::dim, mln_coord(P), box<P> >, + private mlc_is_unqualif(P)::check_t { /// Dimension. enum { dim = P::dim }; - /// PSite associated type. + /// Element associated type. + typedef P element; + + /// Psite associated type. typedef P psite; /// Site associated type. Index: mln/core/p_mutable_array_of.hh --- mln/core/p_mutable_array_of.hh (revision 2154) +++ mln/core/p_mutable_array_of.hh (working copy) @@ -125,6 +125,16 @@ /// Return the \p i-th site set (mutable version). S& operator[](unsigned i); + /// Give the number of elements (site sets) of this composite. + unsigned nelements() const; + + + /// Clear this set. + void clear(); + + /// Test if the site set is empty. + bool is_empty_() const; // Override the default impl since we have not .nsites(). + /// Return the size of this site set in memory. std::size_t memory_size() const; @@ -205,6 +215,31 @@ template <typename S> inline + unsigned + p_mutable_array_of<S>::nelements() const + { + return arr_.nelements(); + } + + template <typename S> + inline + void + p_mutable_array_of<S>::clear() + { + arr_.clear(); + mln_postcondition(this->is_empty()); + } + + template <typename S> + inline + bool + p_mutable_array_of<S>::is_empty_() const + { + return arr_.is_empty(); + } + + template <typename S> + inline std::size_t p_mutable_array_of<S>::memory_size() const { Index: mln/core/pset_if.hh --- mln/core/pset_if.hh (revision 2154) +++ mln/core/pset_if.hh (working copy) @@ -31,6 +31,8 @@ /*! \file mln/core/pset_if.hh * * \brief Definition of the restriction of a point set w.r.t. a predicate. + * + * \todo Change pset_ attribute type to S*. */ # include <mln/core/internal/site_set_base.hh> @@ -84,18 +86,22 @@ typedef internal::site_set_base_<mln_psite(S), self_> super_; public: - typedef mln_psite(S) psite; + /// Element associated type. + typedef mln_element(S) element; + /// Psite associated type. + typedef mln_psite(S) psite; + /// Forward Site_Iterator associated type. typedef pset_if_piter_<mln_fwd_piter(S), S, F> fwd_piter; - /// Site_Iterator associated type. - typedef fwd_piter piter; - /// Backward Site_Iterator associated type. typedef pset_if_piter_<mln_bkd_piter(S), S, F> bkd_piter; + /// Site_Iterator associated type. + typedef fwd_piter piter; + /// Constructor with a point set \p pset and a predicate \p f. pset_if(const S& pset, const F& f); @@ -104,6 +110,10 @@ pset_if(); + /// Test if this site set is valid. + bool is_valid() const; + + /// Test if \p p belongs to the subset. bool has(const psite& p) const; @@ -116,6 +126,10 @@ /// Give the predicate function. const F& predicate() const; + + /// Return the size of this site set in memory. + std::size_t memory_size() const; + protected: S pset_; @@ -149,6 +163,14 @@ template <typename S, typename F> inline + bool + pset_if<S,F>::is_valid() const + { + return pset_.is_valid(); + } + + template <typename S, typename F> + inline const S& pset_if<S,F>::overset() const { @@ -185,6 +207,14 @@ return f_; } + template <typename S, typename F> + inline + std::size_t + pset_if<S,F>::memory_size() const + { + return pset_.memory_size() + sizeof(f_); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/p_array.hh --- mln/core/p_array.hh (revision 2154) +++ mln/core/p_array.hh (working copy) @@ -422,6 +422,7 @@ p_array<P>::clear() { vect_.clear(); + mln_postcondition(this->is_empty()); } template <typename P> Index: mln/core/concept/site_set.hh --- mln/core/concept/site_set.hh (revision 2154) +++ mln/core/concept/site_set.hh (working copy) @@ -32,6 +32,8 @@ * * \brief Definition of the concept of mln::Site_Set. * + * \todo Add a "composite" property. + * * \todo Rewrite and move out the ops. */ @@ -39,6 +41,7 @@ # include <mln/trait/site_sets.hh> # include <mln/metal/not_equal.hh> # include <mln/metal/is_a.hh> +# include <mln/metal/is_unqualif.hh> # include <mln/util/yes.hh> // Temporary include. @@ -69,6 +72,8 @@ typedef Site_Set<void> category; /* + typedef element; + typedef site; typedef psite; @@ -202,8 +207,10 @@ { typedef typename E::i_element i_element; mlc_equal(mlc_unqualif(i_element), i_element)::check(); - void (E::*m)(const i_element&) = & E::insert; - m = 0; + void (E::*m1)(const i_element&) = & E::insert; + m1 = 0; + void (E::*m2)() = & E::clear; + m2 = 0; } }; @@ -220,6 +227,8 @@ mlc_equal(mlc_unqualif(r_element), r_element)::check(); void (E::*m2)(const r_element&) = & E::remove; m2 = 0; + void (E::*m3)() = & E::clear; + m3 = 0; } }; @@ -242,6 +251,8 @@ // mlc_is_a( mln_trait_site_set_nsites(E), mln::trait::site_set::nsites::any )::check(); // Check associated types. + typedef mln_element(E) element; + mlc_is_unqualif(element)::check(); typedef mln_site(E) site; typedef mln_psite(E) psite; typedef mln_piter(E) piter; Index: mln/core/sparse_image.hh --- mln/core/sparse_image.hh (revision 2154) +++ mln/core/sparse_image.hh (working copy) @@ -31,13 +31,12 @@ /*! \file mln/core/sparse_image.hh * * \brief Definition of an image with sparse encoding. - * - * \todo Update p_run_set<P> to p_set_of< p_run<P> >. */ # include <vector> # include <mln/core/internal/image_primary.hh> -# include <mln/core/p_runs.hh> +# include <mln/core/p_set_of.hh> +# include <mln/core/p_run.hh> # include <mln/value/set.hh> @@ -58,7 +57,7 @@ data(); /// Domain. - p_run_set<P> domain_; + p_set_of< p_run<P> > domain_; /// Image. std::vector< std::vector<T> > values_; @@ -107,11 +106,11 @@ */ template <typename P, typename T> class sparse_image - : public internal::image_primary< p_run_set<P>, + : public internal::image_primary< p_set_of< p_run<P> >, sparse_image<P,T> > { typedef sparse_image<P,T> self_; - typedef internal::image_primary<p_run_set<P>, self_> super_; + typedef internal::image_primary<p_set_of< p_run<P> >, self_> super_; public: /// Value associated type. @@ -136,7 +135,7 @@ sparse_image(); /// Constructor from a set of runs. - sparse_image(const p_run_set<P>& s); + sparse_image(const p_set_of< p_run<P> >& s); /// Add a new range to the image. @@ -160,7 +159,7 @@ /// Give the definition domain. - const p_run_set<P>& domain() const; + const p_set_of< p_run<P> >& domain() const; }; @@ -189,7 +188,7 @@ template <typename P, typename T> inline - sparse_image<P,T>::sparse_image(const p_run_set<P>& s) + sparse_image<P,T>::sparse_image(const p_set_of< p_run<P> >& s) { this->data_ = new internal::data< sparse_image<P,T> >(); this->data_->domain_ = s; @@ -248,7 +247,7 @@ template <typename P, typename T> inline - const p_run_set<P>& + const p_set_of< p_run<P> >& sparse_image<P,T>::domain() const { mln_precondition(this->has_data()); Index: mln/core/p_runs.hh --- mln/core/p_runs.hh (revision 2154) +++ mln/core/p_runs.hh (working copy) @@ -145,6 +145,10 @@ void insert(const p_run_set<P>& other); + /// Clear this set. + void clear(); + + /// Return the i-th run. const p_run<P>& run(unsigned i) const; @@ -325,6 +329,16 @@ template <typename P> inline + void + p_run_set<P>::clear() + { + nsites_ = 0; + b_.init(); + run_.clear(); + } + + template <typename P> + inline unsigned p_run_set<P>::nruns() const { Index: mln/core/image2d.hh --- mln/core/image2d.hh (revision 2154) +++ mln/core/image2d.hh (working copy) @@ -188,9 +188,10 @@ template <typename P> T& alt(const P& p) { + typedef def::coord coord_t; mln_precondition(this->has(p)); -// std::cout << (int*)(&p.p_hook_()) << ' ' +// std::cout << (coord_t*)(&p.p_hook_()) << ' ' // << &(p.row()) << ' ' // << &(p.get_subject()) << ' ' // << &(p.to_site()) << std::endl; @@ -198,8 +199,8 @@ // return this->data_->array_[p.to_site().row()][p.to_site().col()]; // return this->data_->array_[p.row()][p.col()]; // return this->data_->array_[p.get_subject().row()][p.get_subject().col()]; - // return this->data_->array_ [*(int*)(&p.get_subject())] [*((int*)(&p.get_subject()) + 1)]; - return this->data_->array_ [*(int*)(&p.p_hook_())] [*((int*)(&p.p_hook_()) + 1)]; + // return this->data_->array_ [*(coord_t*)(&p.get_subject())] [*((coord_t*)(&p.get_subject()) + 1)]; + return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)]; // return this->data_->array_[0][0];; } Index: mln/convert/impl/from_image_to_site_set.hh --- mln/convert/impl/from_image_to_site_set.hh (revision 0) +++ mln/convert/impl/from_image_to_site_set.hh (revision 0) @@ -0,0 +1,148 @@ +// Copyright (C) 2008 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 MLN_CONVERT_IMPL_FROM_IMAGE_TO_SITE_SET_HH +# define MLN_CONVERT_IMPL_FROM_IMAGE_TO_SITE_SET_HH + +/*! \file mln/convert/from_to.hh + * + * \brief General conversion procedure from an image to a site_set. + * + * \todo Augment code + add checks. + * + * \todo Add (?) the case p_run-based -> site set. + */ + +# include <utility> +# include <mln/core/concept/image.hh> +# include <mln/core/concept/site_set.hh> +# include <mln/core/p_run.hh> +# include <mln/metal/converts_to.hh> + + + +namespace mln +{ + + namespace convert + { + + namespace impl + { + + /// Convertion of an image \p from towards a site set \p to. + template <typename I, typename S> + void + from_image_to_site_set(const Image<I>& from, Site_Set<S>& to); + + + +# ifndef MLN_INCLUDE_ONLY + + + // Case: binary image -> set of point runs. + + template <typename I, typename P, typename S> + void + from_image_to_site_set_(const I& input, const Gpoint<P>&, + S& s, const mln::p_run<P>&) + { + s.clear(); + mln_fwd_piter(I) p(input.domain()); + p.start(); + for (;;) + { + // Skip background. + while (p.is_valid() && input(p) == false) + p.next(); + if (! p.is_valid()) // The end. + break; + mln_invariant(input(p) == true); + P start = p, q; + // Go to run end. + do + { + q = p; + p.next(); + } + while (p.is_valid() && input(p) == true && + // p follows q in a run, i.e., "p == q + right": + cut_(p.to_site()) == cut_(q) && p.last_coord() == q.last_coord() + 1); + s.insert(p_run<P>(start, q)); + } + } + + + template <typename I, typename P, typename S> + void + from_image_to_site_set_(const I& input, const Gpoint<P>&, + S& s, const std::pair< mln_value(I), p_run<P> >&) + { + s.clear(); + mln_value(I) O = literal::zero; + mln_fwd_piter(I) p(input.domain()); + p.start(); + for (;;) + { + if (! p.is_valid()) // The end. + break; + mln_value(I) v = input(p); + P start = p, q; + // Go to run end. + do + { + q = p; + p.next(); + } + while (p.is_valid() && input(p) == v && + cut_(p.to_site()) == cut_(q) && p.last_coord() == q.last_coord() + 1); + s.insert(v, p_run<P>(start, q)); + } + } + + + // Facade. + + template <typename I, typename S> + inline + void + from_image_to_site_set(const Image<I>& from, Site_Set<S>& to) + { + from_image_to_site_set_(exact(from), mln_deduce(I, pset, element)(), + exact(to), mln_i_element(S)()); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::convert::impl + + } // end of namespace mln::convert + +} // end of namespace mln + + +#endif // ! MLN_CONVERT_IMPL_FROM_IMAGE_TO_SITE_SET_HH Index: mln/convert/impl/all.hh --- mln/convert/impl/all.hh (revision 0) +++ mln/convert/impl/all.hh (revision 0) @@ -0,0 +1,40 @@ +// Copyright (C) 2008 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 MLN_CONVERT_IMPL_ALL_HH +# define MLN_CONVERT_IMPL_ALL_HH + +/*! \file mln/convert/impl/all.hh + * + * \brief File that includes all from-to conversion routines. + */ + + +# include <mln/convert/impl/from_image_to_site_set.hh> + + +#endif // ! MLN_CONVERT_IMPL_ALL_HH Index: mln/convert/from_to.hh --- mln/convert/from_to.hh (revision 0) +++ mln/convert/from_to.hh (revision 0) @@ -0,0 +1,102 @@ +// Copyright (C) 2008 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 MLN_CONVERT_FROM_TO_HH +# define MLN_CONVERT_FROM_TO_HH + +/*! \file mln/convert/from_to.hh + * + * \brief General conversion procedure between two objects. + * + * \todo Prefer a static check that fails in the "unknown" case. + */ + +# include <mln/core/concept/object.hh> +# include <mln/convert/impl/all.hh> +# include <mln/metal/is.hh> + + +namespace mln +{ + + namespace convert + { + + + /// Convertion of an object \p from towards an object \p to. + template <typename F, typename T> + inline + void + from_to(const Object<F>& from, Object<T>& to); + + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Default (Object -> Object) means "unknown conversion". + template <typename F, typename T> + void + from_to_(const Object<F>& from, Object<T>& to); + + + // Image -> Site_Set. + template <typename I, typename S> + inline + void + from_to_(const Image<I>& from, Site_Set<S>& to) + { + mlc_is(mln_trait_site_set_contents(S), + mln::trait::site_set::contents::dynamic)::check(); + mln_precondition(exact(from).has_data()); + mln::convert::impl::from_image_to_site_set(from, to); + } + + + } // end of namespace mln::convert::impl + + + template <typename F, typename T> + inline + void + from_to(const Object<F>& from, Object<T>& to) + { + trace::entering("convert::from_to"); + impl::from_to_(exact(from), exact(to)); + trace::exiting("convert::from_to"); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::convert + +} // end of namespace mln + + +#endif // ! MLN_CONVERT_FROM_TO_HH Index: mln/convert/all.hh --- mln/convert/all.hh (revision 2154) +++ mln/convert/all.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -40,6 +40,8 @@ namespace convert {} } +# include <mln/convert/from_to.hh> + # include <mln/convert/to_dpoint.hh> # include <mln/convert/to_fun.hh> # include <mln/convert/to_image.hh> Index: mln/labeling/blobs.hh --- mln/labeling/blobs.hh (revision 2154) +++ mln/labeling/blobs.hh (working copy) @@ -33,6 +33,8 @@ * * \brief Connected component labeling of the binary objects of a binary * image using a queue-based algorithm. + * + * \todo Handle abort in a nice way... */ # include <mln/core/concept/image.hh> @@ -97,6 +99,11 @@ if (input(p) && ! output(p)) // Object point, not labeled yet. { // Label this point component. + if (nlabels == mln_max(L)) + { + std::cerr << "FIXME: labeling aborted!" << std::endl; + return output; + } ++nlabels; mln_invariant(qu.is_empty()); qu.push(p); Index: sandbox/geraud/p_runs__with_dedicated_piter.hh --- sandbox/geraud/p_runs__with_dedicated_piter.hh (revision 2154) +++ sandbox/geraud/p_runs__with_dedicated_piter.hh (working copy) @@ -50,7 +50,7 @@ // Forward declarations. template <typename P> class p_runs; - template <typename P> class p_runs_piste; + template <typename P> class p_runs_psite; template <typename P> class p_runs_fwd_piter_; template <typename P> class p_runs_bkd_piter_; @@ -142,6 +142,10 @@ void insert(const p_runs<P>& other); + /// Clear this set. + void clear(); + + /// Return the i-th run. const p_run<P>& run(unsigned i) const; @@ -445,6 +449,16 @@ template <typename P> inline + void + p_runs<P>::clear() + { + nsites_ = 0; + b_.init(); + run_.clear(); + } + + template <typename P> + inline unsigned p_runs<P>::nruns() const {