
* headers.mk: update distributed file list. * mln/make/dummy_p_edges.hh, * mln/make/dummy_p_vertices.hh, * mln/util/line_graph.hh, * mln/util/internal/graph_base.hh, * mln/util/internal/graph_iter.hh, * mln/util/internal/graph_iter_base.hh, * mln/util/internal/graph_nbh_iter.hh, * mln/util/internal/graph_nbh_iter_base.hh, * mln/util/graph.hh, * mln/morpho/attribute/count_adjacent_vertices.hh, * mln/core/concept/graph.hh: update member signatures with vertex and edge ids. * mln/core/site_set/p_graph_piter.hh, * mln/core/internal/graph_psite_base.hh, * mln/core/internal/neighb_niter_impl.hh, * mln/core/internal/graph_psite_base.hh, * mln/core/image/graph_window_piter.hh: comment a conversion operators. Cause ambiguities with iterators/proxies. * mln/core/image/vertex_image.hh, * mln/core/image/edge_image.hh: add new members. * mln/core/internal/site_iterator_base.hh: add a 'target' typedef. * mln/core/site_set/p_edges.hh, * mln/core/site_set/p_vertices.hh: add new constructors. * mln/make/rag_and_labeled_wsl.hh: update doc. * mln/util/graph_ids.hh, * mln/util/edge.hh, * mln/util/vertex.hh: introduce vertex and edge id types. * mln/util/internal/id2element.hh: function mapping ids to graph elements. * mln/make/p_edges_with_mass_centers.hh: fix guards. * tests/make/dummy_p_vertices.cc, * tests/morpho/graph_image_morpho.cc, * tests/morpho/graph_image_wst.cc, * tests/morpho/line_graph_image_morpho.cc, * tests/morpho/line_graph_image_wst.cc, * tests/util/graph.cc, * tests/util/line_graph.cc: update tests according the new routines/constructors/types. * mln/core/concept/object_id.hh: new concept for object ids. --- milena/ChangeLog | 56 ++++ milena/headers.mk | 17 +- milena/mln/core/concept/graph.hh | 40 ++-- milena/mln/core/concept/object_id.hh | 278 ++++++++++++++++++++ milena/mln/core/image/edge_image.hh | 75 ++++-- milena/mln/core/image/graph_window_piter.hh | 20 +- milena/mln/core/image/vertex_image.hh | 127 ++++++--- milena/mln/core/internal/graph_psite_base.hh | 4 +- milena/mln/core/internal/neighb_niter_impl.hh | 8 +- milena/mln/core/internal/site_iterator_base.hh | 3 + milena/mln/core/site_set/p_edges.hh | 22 ++- milena/mln/core/site_set/p_graph_piter.hh | 87 ++++++- milena/mln/core/site_set/p_vertices.hh | 21 ++- milena/mln/make/dummy_p_edges.hh | 6 +- milena/mln/make/dummy_p_vertices.hh | 6 +- milena/mln/make/edge_image.hh | 164 ++++++++++++ milena/mln/make/p_edges_with_mass_centers.hh | 6 +- milena/mln/make/rag_and_labeled_wsl.hh | 52 ++-- milena/mln/make/vertex_image.hh | 28 ++ .../morpho/attribute/count_adjacent_vertices.hh | 3 +- milena/mln/util/edge.hh | 128 ++++++---- milena/mln/util/graph.hh | 123 ++++----- .../dummy_p_vertices.cc => mln/util/graph_ids.hh} | 61 ++--- milena/mln/util/internal/graph_base.hh | 15 +- milena/mln/util/internal/graph_iter.hh | 32 ++-- milena/mln/util/internal/graph_iter_base.hh | 26 ++- milena/mln/util/internal/graph_nbh_iter.hh | 2 +- milena/mln/util/internal/graph_nbh_iter_base.hh | 31 ++- milena/mln/util/internal/id2element.hh | 100 +++++++ milena/mln/util/line_graph.hh | 92 ++++--- milena/mln/util/vertex.hh | 109 +++++--- milena/tests/make/dummy_p_vertices.cc | 4 +- milena/tests/morpho/graph_image_morpho.cc | 5 +- milena/tests/morpho/graph_image_wst.cc | 5 +- milena/tests/morpho/line_graph_image_morpho.cc | 5 +- milena/tests/morpho/line_graph_image_wst.cc | 5 +- milena/tests/util/graph.cc | 12 +- milena/tests/util/line_graph.cc | 12 +- 38 files changed, 1346 insertions(+), 444 deletions(-) create mode 100644 milena/mln/core/concept/object_id.hh create mode 100644 milena/mln/make/edge_image.hh copy milena/{tests/make/dummy_p_vertices.cc => mln/util/graph_ids.hh} (54%) create mode 100644 milena/mln/util/internal/id2element.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 10a5cc4..54be57c 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,61 @@ 2009-04-27 Guillaume Lazzara <lazzara@lrde.epita.fr> + Revamp graph images. + + * headers.mk: update distributed file list. + + * mln/make/dummy_p_edges.hh, + * mln/make/dummy_p_vertices.hh, + * mln/util/line_graph.hh, + * mln/util/internal/graph_base.hh, + * mln/util/internal/graph_iter.hh, + * mln/util/internal/graph_iter_base.hh, + * mln/util/internal/graph_nbh_iter.hh, + * mln/util/internal/graph_nbh_iter_base.hh, + * mln/util/graph.hh, + * mln/morpho/attribute/count_adjacent_vertices.hh, + * mln/core/concept/graph.hh: update member signatures with vertex and + edge ids. + + * mln/core/site_set/p_graph_piter.hh, + * mln/core/internal/graph_psite_base.hh, + * mln/core/internal/neighb_niter_impl.hh, + * mln/core/internal/graph_psite_base.hh, + * mln/core/image/graph_window_piter.hh: comment a conversion + operators. Cause ambiguities with iterators/proxies. + + * mln/core/image/vertex_image.hh, + * mln/core/image/edge_image.hh: add new members. + + * mln/core/internal/site_iterator_base.hh: add a 'target' typedef. + + * mln/core/site_set/p_edges.hh, + * mln/core/site_set/p_vertices.hh: add new constructors. + + * mln/make/rag_and_labeled_wsl.hh: update doc. + + * mln/util/graph_ids.hh, + * mln/util/edge.hh, + * mln/util/vertex.hh: introduce vertex and edge id types. + + * mln/util/internal/id2element.hh: function mapping ids to graph + elements. + + * mln/make/p_edges_with_mass_centers.hh: fix guards. + + * tests/make/dummy_p_vertices.cc, + * tests/morpho/graph_image_morpho.cc, + * tests/morpho/graph_image_wst.cc, + * tests/morpho/line_graph_image_morpho.cc, + * tests/morpho/line_graph_image_wst.cc, + * tests/util/graph.cc, + * tests/util/line_graph.cc: update tests according the new + routines/constructors/types. + + * mln/core/concept/object_id.hh: new concept for object ids. + +2009-04-27 Guillaume Lazzara <lazzara@lrde.epita.fr> + Fix documentation distributed files. * doc/examples/examples.mk, diff --git a/milena/headers.mk b/milena/headers.mk index 590621d..5eaf7f7 100644 --- a/milena/headers.mk +++ b/milena/headers.mk @@ -83,6 +83,7 @@ mln/util/internal/vertex_impl.hh \ mln/util/internal/edge_impl.hh \ mln/util/internal/graph_base.hh \ mln/util/internal/boost_graph.hh \ +mln/util/internal/id2element.hh \ mln/util/internal/graph_nbh_iter_base.hh \ mln/util/internal/boost_graph_property.hh \ mln/util/ord_pair.hh \ @@ -110,6 +111,7 @@ mln/util/pix.hh \ mln/util/tree_fast.hh \ mln/util/site_pair.hh \ mln/util/nil.hh \ +mln/util/graph_ids.hh \ mln/util/eat.hh \ mln/util/essential.hh \ mln/data/memset_.hh \ @@ -135,13 +137,13 @@ mln/trace/resume.hh \ mln/trace/quiet.hh \ mln/trace/stop.hh \ mln/trace/essential.hh \ -mln/make/graph.hh \ mln/make/double_neighb2d.hh \ mln/make/image3d.hh \ mln/make/dpoint2d_h.hh \ mln/make/w_window.hh \ mln/make/cell.hh \ mln/make/image.hh \ +mln/make/influence_zone_adjacency_graph.hh \ mln/make/vec.hh \ mln/make/all.hh \ mln/make/dual_neighb.hh \ @@ -153,11 +155,15 @@ mln/make/w_window2d_int.hh \ mln/make/box1d.hh \ mln/make/voronoi.hh \ mln/make/box2d.hh \ +mln/make/p_edges_with_mass_centers.hh \ mln/make/h_mat.hh \ +mln/make/p_vertices_with_mass_centers.hh \ +mln/make/vertex_image.hh \ mln/make/w_window2d.hh \ mln/make/box3d.hh \ mln/make/detachment.hh \ mln/make/region_adjacency_graph.hh \ +mln/make/dummy_p_vertices.hh \ mln/make/relabelfun.hh \ mln/make/pixel.hh \ mln/make/pix.hh \ @@ -166,6 +172,7 @@ mln/make/w_window1d.hh \ mln/make/image2d.hh \ mln/make/w_window_directional.hh \ mln/make/rag_and_labeled_wsl.hh \ +mln/make/dummy_p_edges.hh \ mln/make/w_window3d_int.hh \ mln/make/essential.hh \ mln/make/w_window1d_int.hh \ @@ -213,7 +220,6 @@ mln/fun/vv2v/diff_abs.hh \ mln/fun/vv2v/land.hh \ mln/fun/vv2v/min.hh \ mln/fun/vv2v/essential.hh \ -mln/fun/internal/array_base.hh \ mln/fun/internal/x2x_linear_impl.hh \ mln/fun/internal/ch_function_value_impl.hh \ mln/fun/internal/resolve.hh \ @@ -257,7 +263,6 @@ mln/fun/i2v/all.hh \ mln/fun/i2v/array.hh \ mln/fun/i2v/all_to.hh \ mln/fun/i2v/essential.hh \ -mln/fun/l2l/relabel.hh \ mln/fun/l2l/all.hh \ mln/fun/l2l/wrap.hh \ mln/fun/l2l/essential.hh \ @@ -963,6 +968,7 @@ mln/core/concept/window.hh \ mln/core/concept/value.hh \ mln/core/concept/accumulator.hh \ mln/core/concept/site_set.hh \ +mln/core/concept/object_id.hh \ mln/core/concept/object.hh \ mln/core/concept/meta_fun.hh \ mln/core/concept/delta_point_site.hh \ @@ -1043,6 +1049,7 @@ mln/labeling/foreground.hh \ mln/labeling/regional_maxima.hh \ mln/labeling/wrap.hh \ mln/labeling/compute.hh \ +mln/labeling/pack.hh \ mln/labeling/regional_minima.hh \ mln/labeling/essential.hh \ mln/labeling/fill_holes.hh \ @@ -1138,6 +1145,7 @@ mln/debug/println.spe.hh \ mln/debug/colorize.hh \ mln/debug/slices_2d.hh \ mln/debug/draw_graph.hh \ +mln/debug/filename.hh \ mln/debug/put_word.hh \ mln/debug/histo.hh \ mln/debug/quiet.hh \ @@ -1151,6 +1159,9 @@ mln/estim/all.hh \ mln/estim/sum.hh \ mln/estim/mean.hh \ mln/estim/essential.hh \ +mln/graph/attribute/representative.hh \ +mln/graph/attribute/card.hh \ +mln/graph/compute.hh \ mln/set/uni.hh \ mln/set/unique.hh \ mln/set/inter.hh \ diff --git a/milena/mln/core/concept/graph.hh b/milena/mln/core/concept/graph.hh index fa07e78..4d43569 100644 --- a/milena/mln/core/concept/graph.hh +++ b/milena/mln/core/concept/graph.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 @@ -33,6 +34,7 @@ /// Definition of the concept of mln::Graph. # include <mln/core/concept/object.hh> +# include <mln/util/graph_ids.hh> namespace mln { @@ -81,21 +83,21 @@ namespace mln void invalidate(); /* // Vertex and edges oriented. - unsigned v_other(unsigned id_e, unsigned id_v) const; + util::vertex_id_t v_other(const util::edge_id_t& id_e, const util::vertex_id_t& id_v) const; // Vertex oriented. size_t v_nmax() const; - bool has_v(unsigned id_v) const; - size_t v_nmax_nbh_edges(unsigned id_v) const; - unsigned v_ith_nbh_edge(unsigned id_v, unsigned i) const; + bool has(unsigned id_v) const; + size_t v_nmax_nbh_edges(const util::vertex_id_t& id_v) const; + util::edge_id_t v_ith_nbh_edge(const util::vertex_id_t& id_v, unsigned i) const; // Edge oriented. size_t e_nmax() const; - bool has_e(unsigned id_e) const; - unsigned v1(unsigned id_e) const; - unsigned v2(unsigned id_e) const; - size_t e_nmax_nbh_edges(unsigned id_e) const; - unsigned e_ith_nbh_edge(unsigned id_e, unsigned i) const; + bool has_e(const util::edge_id_t& id_e) const; + util::vertex_id_t v1(const util::edge_id_t& id_e) const; + util::vertex_id_t v2(const util::edge_id_t& id_e) const; + size_t e_nmax_nbh_edges(const util::edge_id_t& id_e) const; + util::edge_id_t e_ith_nbh_edge(const util::edge_id_t& id_e, unsigned i) const; */ @@ -120,27 +122,27 @@ namespace mln // Check methods const void* (E::*m1)() const = & E::id; m1 = 0; - unsigned (E::*m2)(unsigned id_e, unsigned id_v) const = & E::v_other; + util::vertex_id_t (E::*m2)(const util::edge_id_t& id_e, const util::vertex_id_t& id_v) const = & E::v_other; m2 = 0; size_t (E::*m4)() const = & E::v_nmax; m4 = 0; - bool (E::*m5)(unsigned id_v) const = & E::has_v; + bool (E::*m5)(const util::vertex_id_t& id_v) const = & E::has_v; m5 = 0; - size_t (E::*m6)(unsigned id_v) const = & E::v_nmax_nbh_edges; + size_t (E::*m6)(const util::vertex_id_t& id_v) const = & E::v_nmax_nbh_edges; m6 = 0; - unsigned (E::*m7)(unsigned id_v, unsigned i) const = & E::v_ith_nbh_edge; + util::edge_id_t (E::*m7)(const util::vertex_id_t& id_v, unsigned i) const = & E::v_ith_nbh_edge; m7 = 0; size_t (E::*m8)() const = & E::e_nmax; m8 = 0; - bool (E::*m9)(unsigned id_e) const = & E::has_e; + bool (E::*m9)(const util::edge_id_t& id_e) const = & E::has_e; m9 = 0; - unsigned (E::*m10)(unsigned id_e) const = & E::v1; + util::vertex_id_t (E::*m10)(const util::edge_id_t& id_e) const = & E::v1; m10 = 0; - unsigned (E::*m11)(unsigned id_e) const = & E::v2; + util::vertex_id_t (E::*m11)(const util::edge_id_t& id_e) const = & E::v2; m11 = 0; - size_t (E::*m12)(unsigned id_e) const = & E::e_nmax_nbh_edges; + size_t (E::*m12)(const util::edge_id_t& id_e) const = & E::e_nmax_nbh_edges; m12 = 0; - unsigned (E::*m13)(unsigned id_e, unsigned i) const = & E::e_ith_nbh_edge; + util::edge_id_t (E::*m13)(const util::edge_id_t& id_e, unsigned i) const = & E::e_ith_nbh_edge; m13 = 0; //FIXME: enable this test. Currently does not work because this is diff --git a/milena/mln/core/concept/object_id.hh b/milena/mln/core/concept/object_id.hh new file mode 100644 index 0000000..5bf5547 --- /dev/null +++ b/milena/mln/core/concept/object_id.hh @@ -0,0 +1,278 @@ +// Copyright (C) 2009 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. +// reasons why the executable file might be covered by the GNU General +// Public License. + + +#ifndef MLN_CORE_CONCEPT_OBJECT_ID_HH +# define MLN_CORE_CONCEPT_OBJECT_ID_HH + +/// \file mln/util/internal/element_id.hh +/// +/// Base class of an object id. + + +# include <mln/core/concept/object.hh> +# include <mln/value/concept/integer.hh> +# include <mln/metal/abort.hh> + +namespace mln +{ + + + /// Object category. + template <typename E> + struct Object_Id; + + template <> + struct Object_Id<void> + { + }; + + + + /// Base class of an object id. + /// \tparam Tag the tag type + /// \tparam Equiv the equivalent value. + template <typename Tag, typename V> + class object_id : public value::Integer< object_id<Tag, V> > + { + public: + /// The underlying type id. + typedef V value_t; + typedef unsigned equiv; + typedef V enc; + + /// Constructors + /// @{ + object_id(); + + template <typename V2> + object_id(const V2& id); + + template <typename Tag2, typename V2> + object_id(const object_id<Tag2,V2>& other); + /// @} + + template <typename V2> + object_id<Tag,V>& operator=(const V2& e); + + const V& value() const; + V& value(); + + operator unsigned() const; + + bool is_valid() const; + void invalidate(); + + unsigned to_equiv() const; + + protected: + V id_; + }; + + + template <typename Tag, typename V> + bool + operator==(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs); +// +// template <typename Tag, typename V> +// bool +// operator<(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs); +// +// template <typename Tag, typename V> +// bool +// operator<(const object_id<Tag,V>& lhs, +// const typename object_id<Tag,V>::V& rhs); +// +// template <typename Tag, typename V> +// std::ostream& +// operator<<(std::ostream& ostr, const object_id<Tag,V>& id); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename Tag, typename V> + inline + object_id<Tag,V>::object_id() + : id_(mln_max(V)) + { + } + + template <typename Tag, typename V> + template <typename V2> + inline + object_id<Tag,V>::object_id(const V2& id) + : id_(id) + { + mlc_converts_to(V2,V)::check(); + } + + template <typename Tag, typename V> + template <typename Tag2, typename V2> + inline + object_id<Tag,V>::object_id(const object_id<Tag2,V2>& id) + { + typedef object_id<Tag2,V2> id_t; + mlc_abort(id_t)::check(); + } + + template <typename Tag, typename V> + template <typename V2> + inline + object_id<Tag,V>& + object_id<Tag,V>::operator=(const V2& v) + { + mlc_converts_to(V2,V)::check(); + + id_ = v; + return *this; + } + + template <typename Tag, typename V> + inline + V& + object_id<Tag,V>::value() + { + return id_; + } + + template <typename Tag, typename V> + inline + const V& + object_id<Tag,V>::value() const + { + return id_; + } + + template <typename Tag, typename V> + inline + object_id<Tag,V>::operator unsigned() const + { + return id_; + } + + + template <typename Tag, typename V> + inline + bool + object_id<Tag,V>::is_valid() const + { + return id_ != mln_max(V); + } + + template <typename Tag, typename V> + inline + void + object_id<Tag,V>::invalidate() + { + id_ = mln_max(V); + } + + template <typename Tag, typename V> + inline + unsigned + object_id<Tag,V>::to_equiv() const + { + return id_; + } + + +// template <typename Tag, typename V> +// inline +// std::ostream& +// operator<<(std::ostream& ostr, const object_id<Tag,V>& id) +// { +// return ostr << id.value(); +// } +// +// + template <typename Tag, typename V> + inline + bool + operator==(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs) + { + return lhs.value() == rhs.value(); + } +// +// template <typename Tag, typename V> +// inline +// bool +// operator<(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs) +// { +// return lhs.value() < rhs.value(); +// } +// +// template <typename Tag, typename V> +// inline +// bool +// operator<(const object_id<Tag,V>& lhs, const V& rhs) +// { +// return lhs.value() < rhs; +// } +// +// template <typename Tag, typename V> +// inline +// bool +// operator<=(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs) +// { +// return lhs.value() <= rhs.value(); +// } +// +// template <typename Tag, typename V> +// inline +// bool +// operator<=(const object_id<Tag,V>& lhs, const V& rhs) +// { +// return lhs.value() <= rhs; +// } + +// template <typename Tag, typename V> +// inline +// object_id<Tag,V> +// operator+(const object_id<Tag,V>& lhs, const V& rhs) +// { +// return lhs.value() + rhs; +// } +// +// template <typename Tag, typename V> +// inline +// object_id<Tag,V> +// operator+(const object_id<Tag,V>& lhs, const size_t& rhs) +// { +// return lhs.value() + rhs; +// } + + + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + +#endif // ! MLN_CORE_CONCEPT_OBJECT_ID_HH + diff --git a/milena/mln/core/image/edge_image.hh b/milena/mln/core/image/edge_image.hh index 68e7227..9dcbc2a 100644 --- a/milena/mln/core/image/edge_image.hh +++ b/milena/mln/core/image/edge_image.hh @@ -73,11 +73,13 @@ namespace mln template <typename P, typename V, typename G> struct data< mln::edge_image<P,V,G> > { + typedef typename edge_image<P,V,G>::site_function_t site_function_t; + data(const fun::i2v::array<V>& edge_values, - const p_edges<G,fun::i2v::array<P> >& pv); + const p_edges<G,site_function_t>& pe); fun::i2v::array<V> f_; - p_edges<G,fun::i2v::array<P> > pset_; + p_edges<G,site_function_t> pset_; }; } // end of namespace mln::internal @@ -90,19 +92,41 @@ namespace mln template <typename V, typename G, typename P> edge_image<P,V,G> operator | (const fun::i2v::array<V>& edge_values, - const p_edges<G,fun::i2v::array<P> >& pv); + const p_edges<G,fun::i2v::array<P> >& pe); + + + // Vertex_image_fsite_selector + + namespace internal + { + + template <typename P, typename G> + struct efsite_selector + { + typedef fun::i2v::array<P> site_function_t; + }; + template <typename G> + struct efsite_selector<void,G> + { + typedef util::internal::id2element< G,util::edge<G> > site_function_t; + }; + + + } // end of namespace mln::internal + + template <typename P, typename V, typename G = util::graph> class edge_image : public pw::internal::image_base<fun::i2v::array<V>, - p_edges<G, fun::i2v::array<P> >, + p_edges<G, typename internal::efsite_selector<P,G>::site_function_t >, edge_image<P,V,G> > { typedef pw::internal::image_base<fun::i2v::array<V>, - p_edges<G, fun::i2v::array<P> >, + p_edges<G, typename internal::efsite_selector<P,G>::site_function_t >, edge_image<P,V,G> > super_; public: @@ -112,7 +136,8 @@ namespace mln tag::graph_<G> > skeleton; /// Function mapping graph elements to sites. - typedef fun::i2v::array<P> site_function_t; + typedef typename internal::efsite_selector<P,G>::site_function_t + site_function_t; /// Window type typedef graph_elt_window<G,p_edges<G,site_function_t> > win_t; @@ -122,12 +147,12 @@ namespace mln /// Constructors. /// @{ edge_image(); - + edge_image(const p_edges<G, site_function_t>& pe); edge_image(const Graph<G>& g, - const Function_i2v< fun::i2v::array<P> >& edge_sites, + const Function_i2v< site_function_t >& edge_sites, const Function_i2v< fun::i2v::array<V> >& edge_values); - edge_image(const p_edges<G,fun::i2v::array<P> >& pe, + edge_image(const p_edges<G, site_function_t >& pe, const Function_i2v< fun::i2v::array<V> >& edge_values); template <typename FP, typename FV> @@ -136,7 +161,7 @@ namespace mln const Function_i2v<FV>& edge_values); template <typename FV> - edge_image(const p_edges<G,fun::i2v::array<P> >& pv, + edge_image(const p_edges<G,site_function_t>& pe, const Function_i2v<FV>& edge_values); /// @} @@ -164,9 +189,9 @@ namespace mln inline edge_image<P,V,G> operator | (const fun::i2v::array<V>& edge_values, - const p_edges<G,fun::i2v::array<P> >& pv) + const p_edges<G,fun::i2v::array<P> >& pe) { - edge_image<P,V,G> tmp(edge_values, pv); + edge_image<P,V,G> tmp(edge_values, pe); return tmp; } @@ -180,7 +205,7 @@ namespace mln template <typename P, typename V, typename G> inline data< mln::edge_image<P,V,G> >::data(const fun::i2v::array<V>& f, - const p_edges<G,fun::i2v::array<P> >& ps) + const p_edges<G,site_function_t>& ps) : f_(exact(f)), pset_(ps) { @@ -200,20 +225,28 @@ namespace mln template <typename P, typename V, typename G> inline + edge_image<P,V,G>::edge_image(const p_edges<G,site_function_t>& pe) + : super_(fun::i2v::array<V>(pe.nsites()), pe) + { + } + + + template <typename P, typename V, typename G> + inline edge_image<P,V,G>::edge_image(const Graph<G>& g, - const Function_i2v< fun::i2v::array<P> >& edge_sites, + const Function_i2v< site_function_t >& edge_sites, const Function_i2v< fun::i2v::array<V> >& edge_values) : super_(exact(edge_values), - p_edges<G,fun::i2v::array<P> >(g, exact(edge_sites))) + p_edges<G,site_function_t>(g, exact(edge_sites))) { } template <typename P, typename V, typename G> inline - edge_image<P,V,G>::edge_image(const p_edges<G,fun::i2v::array<P> >& pv, + edge_image<P,V,G>::edge_image(const p_edges<G,site_function_t>& pe, const Function_i2v< fun::i2v::array<V> >& edge_values) - : super_(exact(edge_values), pv) + : super_(exact(edge_values), pe) { } @@ -225,9 +258,8 @@ namespace mln const Function_i2v<FP>& edge_sites, const Function_i2v<FV>& edge_values) : super_(convert::to<fun::i2v::array<V> >(exact(edge_values)), - p_edges<G,fun::i2v::array<P> >(g, exact(edge_sites))) + p_edges<G,site_function_t>(g, exact(edge_sites))) { - mlc_converts_to(FV,fun::i2v::array<V>)::check(); mlc_equal(mln_result(FP),P)::check(); mlc_equal(mln_result(FV),V)::check(); } @@ -237,11 +269,10 @@ namespace mln template <typename P, typename V, typename G> template <typename FV> inline - edge_image<P,V,G>::edge_image(const p_edges<G,fun::i2v::array<P> >& pv, + edge_image<P,V,G>::edge_image(const p_edges<G,site_function_t>& pe, const Function_i2v<FV>& edge_values) - : super_(convert::to<fun::i2v::array<V> >(exact(edge_values)), pv) + : super_(convert::to<fun::i2v::array<V> >(exact(edge_values)), pe) { - mlc_converts_to(FV,fun::i2v::array<V>)::check(); mlc_equal(mln_result(FV),V)::check(); } diff --git a/milena/mln/core/image/graph_window_piter.hh b/milena/mln/core/image/graph_window_piter.hh index 0bd341e..320599d 100644 --- a/milena/mln/core/image/graph_window_piter.hh +++ b/milena/mln/core/image/graph_window_piter.hh @@ -91,10 +91,10 @@ namespace mln /// Compute the current psite. mln_psite(W) compute_p_() const; - /// Convert towards the graph element id. - operator unsigned() const; - /// Return the graph element id. + /// FIXME: we do not want to have this member since there is an + /// automatic conversion to the graph element. + /// C++ does not seem to use this conversion operator. unsigned id() const; /// \} @@ -189,13 +189,13 @@ namespace mln return iter_; } - template <typename S, typename W, typename I> - inline - graph_window_piter<S, W, I>::operator unsigned() const - { - return iter_.id(); - } - +// template <typename S, typename W, typename I> +// inline +// graph_window_piter<S, W, I>::operator unsigned() const +// { +// return iter_.id(); +// } +// template <typename S, typename W, typename I> inline unsigned diff --git a/milena/mln/core/image/vertex_image.hh b/milena/mln/core/image/vertex_image.hh index 09aa15b..6f92753 100644 --- a/milena/mln/core/image/vertex_image.hh +++ b/milena/mln/core/image/vertex_image.hh @@ -40,6 +40,9 @@ # include <mln/pw/internal/image_base.hh> # include <mln/fun/i2v/array.hh> +# include <mln/util/internal/id2element.hh> + + namespace mln { @@ -72,11 +75,14 @@ namespace mln template <typename P, typename V, typename G> struct data< mln::vertex_image<P,V,G> > { + typedef typename vertex_image<P,V,G>::site_function_t site_function_t; + + template <typename F> data(const fun::i2v::array<V>& vertex_values, - const p_vertices<G,fun::i2v::array<P> >& pv); + const p_vertices<G,F>& pv); fun::i2v::array<V> f_; - p_vertices<G,fun::i2v::array<P> > pset_; + p_vertices<G,site_function_t> pset_; }; } // end of namespace mln::internal @@ -91,25 +97,54 @@ namespace mln const p_vertices<G,fun::i2v::array<P> >& pv); + // Vertex_image_fsite_selector + + namespace internal + { + + template <typename P, typename G> + struct vfsite_selector + { + typedef fun::i2v::array<P> site_function_t; + }; + + + + template <typename G> + struct vfsite_selector<void,G> + { + typedef util::internal::id2element< G,util::vertex<G> > site_function_t; + }; + + + } // end of namespace mln::internal + + + template <typename P, typename V, typename G = util::graph> class vertex_image : public pw::internal::image_base<fun::i2v::array<V>, - p_vertices<G, fun::i2v::array<P> >, + p_vertices<G, typename internal::vfsite_selector<P,G>::site_function_t >, vertex_image<P,V,G> > { typedef pw::internal::image_base<fun::i2v::array<V>, - p_vertices<G, fun::i2v::array<P> >, + p_vertices<G, typename internal::vfsite_selector<P,G>::site_function_t >, vertex_image<P,V,G> > super_; public: + typedef typename super_::rvalue rvalue; + typedef typename super_::lvalue lvalue; + + /// Function mapping graph elements to sites. + typedef typename internal::vfsite_selector<P,G>::site_function_t + site_function_t; + + /// Skeleton type. typedef vertex_image< tag::psite_<P>, tag::value_<V>, tag::graph_<G> > skeleton; - /// Function mapping graph elements to sites. - typedef fun::i2v::array<P> site_function_t; - /// Window type typedef graph_elt_window<G,p_vertices<G,site_function_t> > win_t; /// Neighborhood type. @@ -118,23 +153,24 @@ namespace mln /// Constructors. /// @{ vertex_image(); - vertex_image(const Graph<G>& g, - const Function_i2v< fun::i2v::array<P> >& vertex_sites, - const Function_i2v< fun::i2v::array<V> >& vertex_values); - - vertex_image(const p_vertices<G,fun::i2v::array<P> >& pv, + vertex_image(const p_vertices<G, site_function_t>& pv); + vertex_image(const p_vertices<G, site_function_t>& pv, const Function_i2v< fun::i2v::array<V> >& vertex_values); - - template <typename FP, typename FV> - vertex_image(const Graph<G>& g, - const Function_i2v<FP>& vertex_sites, - const Function_i2v<FV>& vertex_values); - template <typename FV> - vertex_image(const p_vertices<G,fun::i2v::array<P> >& pv, + vertex_image(const p_vertices<G, site_function_t>& pv, const Function_i2v<FV>& vertex_values); /// @} + using super_::operator(); + + /// Value accessors/operators overloads. + /// @{ +// rvalue operator()(const util::vertex<G>& v) const; +// lvalue operator()(const util::vertex<G>& v); + rvalue operator()(unsigned v_id) const; + lvalue operator()(unsigned v_id); + /// @} + }; template <typename P, typename V, typename G, typename J> @@ -159,7 +195,7 @@ namespace mln inline vertex_image<P,V,G> operator | (const fun::i2v::array<V>& vertex_values, - const p_vertices<G,fun::i2v::array<P> >& pv) + const p_vertices<G, fun::i2v::array<P> >& pv) { vertex_image<P,V,G> tmp(vertex_values, pv); return tmp; @@ -173,9 +209,10 @@ namespace mln { template <typename P, typename V, typename G> + template <typename F> inline data< mln::vertex_image<P,V,G> >::data(const fun::i2v::array<V>& f, - const p_vertices<G,fun::i2v::array<P> >& ps) + const p_vertices<G,F>& ps) : f_(f), pset_(ps) { @@ -196,18 +233,15 @@ namespace mln template <typename P, typename V, typename G> inline - vertex_image<P,V,G>::vertex_image(const Graph<G>& g, - const Function_i2v< fun::i2v::array<P> >& vertex_sites, - const Function_i2v< fun::i2v::array<V> >& vertex_values) - : super_(exact(vertex_values), - p_vertices<G,fun::i2v::array<P> >(g, exact(vertex_sites))) + vertex_image<P,V,G>::vertex_image(const p_vertices<G,site_function_t>& pv) + : super_(fun::i2v::array<V>(pv.nsites()), pv) { } template <typename P, typename V, typename G> inline - vertex_image<P,V,G>::vertex_image(const p_vertices<G,fun::i2v::array<P> >& pv, + vertex_image<P,V,G>::vertex_image(const p_vertices<G,site_function_t>& pv, const Function_i2v< fun::i2v::array<V> >& vertex_values) : super_(exact(vertex_values), pv) { @@ -215,32 +249,43 @@ namespace mln template <typename P, typename V, typename G> - template <typename FP, typename FV> + template <typename FV> inline - vertex_image<P,V,G>::vertex_image(const Graph<G>& g, - const Function_i2v<FP>& vertex_sites, + vertex_image<P,V,G>::vertex_image(const p_vertices<G,site_function_t>& pv, const Function_i2v<FV>& vertex_values) - : super_(convert::to<fun::i2v::array<V> >(exact(vertex_values)), - p_vertices<G,fun::i2v::array<P> >(g, vertex_sites)) + : super_(convert::to<fun::i2v::array<V> >(exact(vertex_values)), pv) { - mlc_converts_to(FV,fun::i2v::array<V>)::check(); - mlc_equal(mln_result(FP),P)::check(); mlc_equal(mln_result(FV),V)::check(); } +// template <typename P, typename V, typename G> +// typename vertex_image<P,V,G>::rvalue +// vertex_image<P,V,G>::operator()(const util::vertex<G>& v) const +// { +// return this->data_->f_(v.id()); +// } +// +// template <typename P, typename V, typename G> +// typename vertex_image<P,V,G>::lvalue +// vertex_image<P,V,G>::operator()(const util::vertex<G>& v) +// { +// return this->data_->f_(v.id()); +// } template <typename P, typename V, typename G> - template <typename FV> - inline - vertex_image<P,V,G>::vertex_image(const p_vertices<G,fun::i2v::array<P> >& pv, - const Function_i2v<FV>& vertex_values) - : super_(convert::to<fun::i2v::array<V> >(exact(vertex_values)), pv) + typename vertex_image<P,V,G>::rvalue + vertex_image<P,V,G>::operator()(unsigned v_id) const { - mlc_converts_to(FV,fun::i2v::array<V>)::check(); - mlc_equal(mln_result(FV),V)::check(); + return this->data_->f_(v_id); } + template <typename P, typename V, typename G> + typename vertex_image<P,V,G>::lvalue + vertex_image<P,V,G>::operator()(unsigned v_id) + { + return this->data_->f_(v_id); + } # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/core/internal/graph_psite_base.hh b/milena/mln/core/internal/graph_psite_base.hh index 3767fd2..d02df00 100644 --- a/milena/mln/core/internal/graph_psite_base.hh +++ b/milena/mln/core/internal/graph_psite_base.hh @@ -162,8 +162,8 @@ namespace mln const typename S::graph_t& graph() const; unsigned id() const; bool is_valid() const; - operator unsigned() const; - operator const typename S::graph_element&() const; +// operator unsigned() const; +// operator const typename S::graph_element&() const; const typename S::graph_element& element() const; const typename S::graph_element& p_hook_() const; diff --git a/milena/mln/core/internal/neighb_niter_impl.hh b/milena/mln/core/internal/neighb_niter_impl.hh index c17ae1d..9079af6 100644 --- a/milena/mln/core/internal/neighb_niter_impl.hh +++ b/milena/mln/core/internal/neighb_niter_impl.hh @@ -72,10 +72,10 @@ namespace mln return internal::force_exact<E>(*this).compute_p_().id(); } - operator unsigned() const - { - return internal::force_exact<E>(*this).compute_p_().id(); - } +// operator unsigned() const +// { +// return internal::force_exact<E>(*this).compute_p_().id(); +// } }; diff --git a/milena/mln/core/internal/site_iterator_base.hh b/milena/mln/core/internal/site_iterator_base.hh index 793eee0..893a9b2 100644 --- a/milena/mln/core/internal/site_iterator_base.hh +++ b/milena/mln/core/internal/site_iterator_base.hh @@ -59,6 +59,9 @@ namespace mln struct site_iterator_base : Site_Iterator<E>, proxy_impl< const mln_psite(S)&, E> { + /// The associated target type. + typedef S target; + /// The associated site type (as a Site_Proxy). typedef mln_site(S) site; diff --git a/milena/mln/core/site_set/p_edges.hh b/milena/mln/core/site_set/p_edges.hh index ad07474..06af1d3 100644 --- a/milena/mln/core/site_set/p_edges.hh +++ b/milena/mln/core/site_set/p_edges.hh @@ -39,6 +39,9 @@ # include <mln/core/site_set/p_graph_piter.hh> # include <mln/core/site_set/p_edges_psite.hh> # include <mln/util/graph.hh> +# include <mln/util/internal/id2element.hh> + +# include <mln/metal/equal.hh> namespace mln @@ -62,7 +65,7 @@ namespace mln } // end of namespace mln::trait - template <typename G, typename F> + template <typename G, typename F = util::internal::id2element<G,util::edge<G> > > class p_edges : public internal::site_set_base_< mln_result(F), p_edges<G, F> > { @@ -92,6 +95,11 @@ namespace mln /// Construct a graph edge psite set from a graph and a function. /// /// \param gr The graph upon which the graph edge psite set is built. + p_edges(const Graph<G>& gr); + + /// Construct a graph edge psite set from a graph and a function. + /// + /// \param gr The graph upon which the graph edge psite set is built. /// \param f the function mapping edges and sites. p_edges(const Graph<G>& gr, const Function<F>& f); @@ -197,6 +205,18 @@ namespace mln template <typename G, typename F> inline + p_edges<G, F>::p_edges(const Graph<G>& g) + { + typedef util::internal::id2element<G,util::edge<G> > F_REF; + mlc_equal(F, F_REF)::check(); + + mln_precondition(exact(g).is_valid()); + g_ = exact(g); + f_ = util::internal::id2element< G, util::edge<G> >(g); + } + + template <typename G, typename F> + inline p_edges<G, F>::p_edges(const Graph<G>& g, const Function<F>& f) { mln_precondition(exact(g).is_valid()); diff --git a/milena/mln/core/site_set/p_graph_piter.hh b/milena/mln/core/site_set/p_graph_piter.hh index 5642446..dba2b52 100644 --- a/milena/mln/core/site_set/p_graph_piter.hh +++ b/milena/mln/core/site_set/p_graph_piter.hh @@ -44,6 +44,7 @@ namespace mln template <typename S, typename I> class graph_psite; + /*------------------------. | p_graph_piter<S,I>. | `------------------------*/ @@ -88,9 +89,6 @@ namespace mln /// Return the underlying graph element iterator. const iter& hook_elt_() const; - /// Convert towards the graph element id. - operator unsigned() const; - /// Return the graph element id. unsigned id() const; @@ -109,6 +107,33 @@ namespace mln }; + namespace internal + { + + /// \{ + /// subject_impl specialization (Proxy) + template <typename S, typename I, typename E> + struct subject_impl< const p_graph_piter<S,I>&, E > + { + const typename S::graph_t& graph() const; + unsigned id() const; + + private: + const E& exact_() const; + }; + + template <typename S, typename I, typename E> + struct subject_impl< p_graph_piter<S,I>&, E > + : subject_impl< const p_graph_piter<S,I>&, E > + { + mln_q_subject(I) element(); + + private: + E& exact_(); + }; + /// \} + + } // end of namespace mln::internal # ifndef MLN_INCLUDE_ONLY @@ -195,13 +220,6 @@ namespace mln template <typename S, typename I> inline - p_graph_piter<S,I>::operator unsigned() const - { - return iter_.id(); - } - - template <typename S, typename I> - inline unsigned p_graph_piter<S,I>::id() const { @@ -218,6 +236,55 @@ namespace mln p_.update_id(iter_.id()); } + + + namespace internal + { + + /// Subject_impl + + template <typename S, typename I, typename E> + inline + const E& + subject_impl< const p_graph_piter<S,I>&, E >::exact_() const + { + return internal::force_exact<const E>(*this); + } + + template <typename S, typename I, typename E> + inline + const typename S::graph_t& + subject_impl< const p_graph_piter<S,I>&, E >::graph() const + { + return exact_().get_subject().graph(); + } + + template <typename S, typename I, typename E> + inline + unsigned + subject_impl< const p_graph_piter<S,I>&, E >::id() const + { + return exact_().get_subject().id(); + }; + + template <typename S, typename I, typename E> + inline + E& + subject_impl< p_graph_piter<S,I>&, E >::exact_() + { + return internal::force_exact<E>(*this); + } + + template <typename S, typename I, typename E> + inline + mln_q_subject(I) + subject_impl< p_graph_piter<S,I>&, E >::element() + { + return exact_().get_subject().element(); + } + + } // end of namespace mln::internal + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln diff --git a/milena/mln/core/site_set/p_vertices.hh b/milena/mln/core/site_set/p_vertices.hh index b20d19b..f158626 100644 --- a/milena/mln/core/site_set/p_vertices.hh +++ b/milena/mln/core/site_set/p_vertices.hh @@ -38,6 +38,7 @@ # include <mln/core/site_set/p_graph_piter.hh> # include <mln/core/site_set/p_vertices_psite.hh> # include <mln/util/graph.hh> +# include <mln/util/internal/id2element.hh> @@ -64,8 +65,7 @@ namespace mln } // end of namespace mln::trait - - template <typename G, typename F> + template <typename G, typename F = util::internal::id2element<G,util::vertex<G> > > class p_vertices : public internal::site_set_base_< mln_result(F), p_vertices<G,F> > { @@ -94,6 +94,11 @@ namespace mln /// Construct a graph psite set from a graph of points. /// \param gr The graph upon which the graph psite set is built. + /// The identity function is used. + p_vertices(const Graph<G>& gr); + + /// Construct a graph psite set from a graph of points. + /// \param gr The graph upon which the graph psite set is built. /// \param f the function which maps a vertex to a site. p_vertices(const Graph<G>& gr, const Function<F>& f); @@ -214,6 +219,18 @@ namespace mln template <typename G, typename F> inline + p_vertices<G,F>::p_vertices(const Graph<G>& g) + { + typedef util::internal::id2element<G,util::vertex<G> > F_REF; + mlc_equal(F, F_REF)::check(); + + mln_precondition(exact(g).is_valid()); + g_ = exact(g); + f_ = util::internal::id2element< G, util::vertex<G> >(g); + } + + template <typename G, typename F> + inline p_vertices<G,F>::p_vertices(const Graph<G>& g, const Function<F>& f) { mln_precondition(exact(g).is_valid()); diff --git a/milena/mln/make/dummy_p_edges.hh b/milena/mln/make/dummy_p_edges.hh index 927d0d8..7c17aec 100644 --- a/milena/mln/make/dummy_p_edges.hh +++ b/milena/mln/make/dummy_p_edges.hh @@ -67,7 +67,7 @@ namespace mln /// \return A p_edges. // template <typename G> - p_edges< G, pw::cst_<int> > + p_edges<G> dummy_p_edges(const Graph<G>& g); @@ -91,10 +91,10 @@ namespace mln template <typename G> - p_edges< G, pw::cst_<int> > + p_edges<G> dummy_p_edges(const Graph<G>& g) { - return dummy_p_edges(g, 0); + return p_edges<G>(g); } diff --git a/milena/mln/make/dummy_p_vertices.hh b/milena/mln/make/dummy_p_vertices.hh index 910d02e..c9c643d 100644 --- a/milena/mln/make/dummy_p_vertices.hh +++ b/milena/mln/make/dummy_p_vertices.hh @@ -67,7 +67,7 @@ namespace mln /// \return A p_vertices. // template <typename G> - p_vertices< G, pw::cst_<int> > + p_vertices<G> dummy_p_vertices(const Graph<G>& g); @@ -91,10 +91,10 @@ namespace mln template <typename G> - p_vertices< G, pw::cst_<int> > + p_vertices<G> dummy_p_vertices(const Graph<G>& g) { - return dummy_p_vertices(g, 0); + return p_vertices<G>(g); } diff --git a/milena/mln/make/edge_image.hh b/milena/mln/make/edge_image.hh new file mode 100644 index 0000000..7ca6980 --- /dev/null +++ b/milena/mln/make/edge_image.hh @@ -0,0 +1,164 @@ +// Copyright (C) 2009 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_MAKE_EDGE_IMAGE_HH +# define MLN_MAKE_EDGE_IMAGE_HH + +/// \file mln/make/edge_image.hh +/// +/// Routine to create a edge image. + +# include <mln/core/image/edge_image.hh> +# include <mln/core/image/vertex_image.hh> +# include <mln/core/concept/function.hh> +# include <mln/util/internal/id2element.hh> + + +namespace mln +{ + + namespace make + { + + + /// Construct an edge image. + /// + /// \param[in] g A graph + /// \param[in] fv A function mapping edge ids to values. + /// + /// \return an edge image. + // + template <typename V, typename G> + mln::edge_image<void,V,G> + edge_image(const Graph<G>& g, const fun::i2v::array<V>& fv); + + + /// Construct an edge image. + /// + /// \param[in] g A graph + /// \param[in] fp A function mapping edge ids to sites. + /// \param[in] fv A function mapping edge ids to values. + /// + /// \return an edge image. + // + template <typename FP, typename FV, typename G> + mln::edge_image<mln_result(FP),mln_result(FV),G> + edge_image(const Graph<G>& g_, + const Function_i2v<FP>& fp, + const Function_i2v<FV>& fv); + + + /// Construct an edge image. + /// + /// \param[in] v_ima_ A vertex image. + /// \param[in] fp A function mapping edge ids to sites. + /// \param[in] fv A function mapping two vertex ids to a value. + /// The result is associated to the corresponding edge. + /// + /// \return an edge image. + // + template <typename P, typename V, typename FP, typename FV, typename G> + mln::edge_image<mln_result(FP),mln_result(FV),G> + edge_image(const vertex_image<P,V,G>& v_ima_, + const Function_v2v<FP>& fp_, + const Function_vv2v<FV>& fv_); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename V, typename G> + mln::edge_image<void,V,G> + edge_image(const Graph<G>& g, const fun::i2v::array<V>& fv) + { + trace::entering("make::edge_image"); + mln_precondition(exact(g).is_valid()); + + p_vertices<G> pv(g); + mln::edge_image<void,V,G> ima(pv, fv); + + trace::exiting("make::edge_image"); + return ima; + } + + + template <typename FP, typename FV, typename G> + mln::edge_image<mln_result(FP),mln_result(FV),G> + edge_image(const Graph<G>& g_, + const Function_i2v<FP>& fp, + const Function_i2v<FV>& fv) + { + trace::entering("make::edge_image"); + const G& g = exact(g_); + mln_precondition(g.is_valid()); + + p_vertices<G,FP> pv(g,fp); + mln::edge_image<mln_result(FP),mln_result(FV),G> ima(pv, fv); + + trace::exiting("make::edge_image"); + return ima; + } + + + template <typename P, typename V, typename FP, typename FV, typename G> + mln::edge_image<mln_result(FP),mln_result(FV),G> + edge_image(const vertex_image<P,V,G>& v_ima_, + const Function_v2v<FP>& fp_, + const Function_vv2v<FV>& fv_) + { + trace::entering("make::edge_image"); + + const FP& fp = exact(fp_); + const FV& fv = exact(fv_); + const vertex_image<P,V,G>& v_ima = exact(v_ima_); + mln_precondition(v_ima.is_valid()); + + fun::i2v::array<mln_result(FV)> tmp_fv(v_ima.domain().graph().e_nmax()); + + p_edges<G,FP> pe(v_ima.domain().graph(), fp); + + typedef mln::edge_image<mln_result(FP),mln_result(FV),G> edge_ima_t; + edge_ima_t ima_e(pe, tmp_fv); + + mln_piter(edge_ima_t) e(ima_e.domain()); + for_all(e) + ima_e(e) = fv(v_ima(e.element().v1()), v_ima(e.element().v2())); + + trace::exiting("make::edge_image"); + return ima_e; + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::make + +} // end of namespace mln + +# endif // ! MLN_MAKE_EDGE_IMAGE_HH diff --git a/milena/mln/make/p_edges_with_mass_centers.hh b/milena/mln/make/p_edges_with_mass_centers.hh index 06a2376..8a1db50 100644 --- a/milena/mln/make/p_edges_with_mass_centers.hh +++ b/milena/mln/make/p_edges_with_mass_centers.hh @@ -25,8 +25,8 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_MAKE_P_VERTICES_WITH_MASS_CENTERS_HH -# define MLN_MAKE_P_VERTICES_WITH_MASS_CENTERS_HH +#ifndef MLN_MAKE_P_EDGES_WITH_MASS_CENTERS_HH +# define MLN_MAKE_P_EDGES_WITH_MASS_CENTERS_HH /// \file mln/make/p_edges_with_mass_centers.hh /// @@ -118,4 +118,4 @@ namespace mln } // end of namespace mln -#endif // ! MLN_MAKE_P_VERTICES_WITH_MASS_CENTERS_HH +#endif // ! MLN_MAKE_P_EDGES_WITH_MASS_CENTERS_HH diff --git a/milena/mln/make/rag_and_labeled_wsl.hh b/milena/mln/make/rag_and_labeled_wsl.hh index 1ad3705..774c78a 100644 --- a/milena/mln/make/rag_and_labeled_wsl.hh +++ b/milena/mln/make/rag_and_labeled_wsl.hh @@ -64,33 +64,31 @@ namespace mln /// \return A couple. First element is the graph, second element is an /// image with a labeled watershed line. /*! - ** - ** \verbatim - ** - ** |-----------------| |-----------------| - ** | 1 1 1 0 2 2 0 3 | | . . . 1 . . 2 . | - ** | 1 1 0 2 2 2 0 3 | | . . 1 . . . 2 . | - ** | 1 0 4 0 2 0 3 3 | ----> | . 1 . 3 . 4 . . | - ** | 0 4 4 4 0 5 0 3 | | 1 . . . 5 . 6 . | - ** |-----------------| |-----------------| - ** - ** Watershed image Labeled watershed line - ** (watershed line labeled with 0) - ** - ** - ** | - ** | - ** | - ** v - ** - ** 1 -- 2 - 3 - ** \ / / - ** 4 -- 5 - ** - ** Region Adjacency graph (RAG) - ** - ** \endverbatim - ** + \verbatim + + |-----------------| |-----------------| + | 1 1 1 0 2 2 0 3 | | . . . 1 . . 2 . | + | 1 1 0 2 2 2 0 3 | | . . 1 . . . 2 . | + | 1 0 4 0 2 0 3 3 | ----> | . 1 . 3 . 4 . . | + | 0 4 4 4 0 5 0 3 | | 1 . . . 5 . 6 . | + |-----------------| |-----------------| + + Watershed image Labeled watershed line + (watershed line labeled with 0) + + + | + | + | + v + + 1 -- 2 - 3 + \ / / + 4 -- 5 + + Region Adjacency graph (RAG) + + \endverbatim */ template <typename I, typename N> util::couple<util::graph,mln_concrete(I)> diff --git a/milena/mln/make/vertex_image.hh b/milena/mln/make/vertex_image.hh index c5db7ea..dc7e28f 100644 --- a/milena/mln/make/vertex_image.hh +++ b/milena/mln/make/vertex_image.hh @@ -44,6 +44,34 @@ namespace mln { + /// Construct a vertex image + /// + /// \param[in] g A graph. + /// \param[in] fv A function mapping vertex ids to values. + /// + /// \return A vertex image. + // + template <typename V, typename G> + mln::vertex_image<void,V,G> + vertex_image(const Graph<G>& g, const fun::i2v::array<V>& fv); + + + /// Construct a vertex image + /// + /// \param[in] g_ A graph. + /// \param[in] fp A function mapping vertex ids to sites. + /// \param[in] fv A function mapping vertex ids to values. + /// + /// \return A vertex image. + // + template <typename FP, typename FV, typename G> + mln::vertex_image<mln_result(FP),mln_result(FV),G> + vertex_image(const Graph<G>& g_, + const Function_i2v<FP>& fp, + const Function_i2v<FV>& fv); + + + # ifndef MLN_INCLUDE_ONLY template <typename V, typename G> diff --git a/milena/mln/morpho/attribute/count_adjacent_vertices.hh b/milena/mln/morpho/attribute/count_adjacent_vertices.hh index 49e08b3..bc4ae3c 100644 --- a/milena/mln/morpho/attribute/count_adjacent_vertices.hh +++ b/milena/mln/morpho/attribute/count_adjacent_vertices.hh @@ -40,6 +40,7 @@ # include <mln/accu/internal/base.hh> # include <mln/pw/image.hh> # include <mln/util/pix.hh> +# include <mln/util/graph_ids.hh> namespace mln { @@ -114,7 +115,7 @@ namespace mln /// The value of the counter. unsigned count__; /// The set of adjacent vertices. - std::set<unsigned> vertices_; + std::set<util::vertex_id_t> vertices_; }; diff --git a/milena/mln/util/edge.hh b/milena/mln/util/edge.hh index 9d9c3fc..0c759db 100644 --- a/milena/mln/util/edge.hh +++ b/milena/mln/util/edge.hh @@ -34,24 +34,49 @@ /// Definition of a graph edge. # include <iostream> +# include <mln/util/graph_ids.hh> # include <mln/util/internal/edge_impl.hh> # include <mln/core/concept/proxy.hh> +# include <mln/core/concept/site.hh> namespace mln { - namespace util + // Forward declaration. + namespace util { template<typename G> class edge; } + + + + /// edge category flag type. + template <typename E> + struct Edge { + }; + + template <> + struct Edge<void> + { + typedef Site<void> super; + }; + + - /*-------. - | Edge. | - `-------*/ + namespace util + { /// Edge of a graph \p G. template <typename G> class edge : public internal::edge_impl_<G> { public: + /// Object category. + typedef Edge<void> category; + + /// The underlying type used to store edge ids. + typedef typename edge_id_t::value_t id_value_t; + + /// The edge type id. + typedef edge_id_t id_t; /// Graph associated type. typedef G graph_t; @@ -60,7 +85,8 @@ namespace mln /// \{ edge(); explicit edge(const G& g); - edge(const G& g, unsigned id); + edge(const G& g, id_value_t id); + edge(const G& g, const edge_id_t& id); /// \} @@ -72,13 +98,13 @@ namespace mln void invalidate(); /// Return the edge id. - unsigned id() const; + edge_id_t id() const; /// Set id_ with \p id; - void update_id(unsigned id); + void update_id(const edge_id_t& id); /// Conversion to the edge id. - operator unsigned() const; + operator edge_id_t() const; /// Return a reference to the graph holding this edge. const G& graph() const; @@ -91,28 +117,29 @@ namespace mln /// Vertex and edges oriented. /// \{ /// Return the vertex id of this edge which is different from \p id_v. - unsigned v_other(unsigned id_v) const; + vertex_id_t + v_other(const vertex_id_t& id_v) const; /// \} /// Edge oriented. /// \{ /// Return the lowest vertex id adjacent to this edge. - unsigned v1() const; + vertex_id_t v1() const; /// Return the highest vertex id adjacent to this edge. - unsigned v2() const; + vertex_id_t v2() const; /// Return the number max of adjacent edges. size_t nmax_nbh_edges() const; /// Return the \p i th adjacent edge. - unsigned ith_nbh_edge(unsigned i) const; + edge_id_t ith_nbh_edge(unsigned i) const; /// \} private: G g_; - unsigned id_; + edge_id_t id_; }; @@ -141,14 +168,18 @@ namespace mln template <typename G, typename E> struct subject_impl< const util::edge<G>, E > { - unsigned id() const; + util::edge_id_t id() const; const G& graph() const; - unsigned v_other(unsigned id_v) const; - bool is_valid() const; - unsigned v1() const; - unsigned v2() const; + + util::vertex_id_t + v_other(const util::vertex_id_t& id_v) const; + + util::vertex_id_t v1() const; + + util::vertex_id_t v2() const; + size_t nmax_nbh_edges() const; - unsigned ith_nbh_edge(unsigned i) const; + util::edge_id_t ith_nbh_edge(unsigned i) const; private: @@ -159,7 +190,7 @@ namespace mln struct subject_impl< util::edge<G>, E > : subject_impl< const util::edge<G>, E > { - void update_id(unsigned id); + void update_id(const util::edge_id_t& id); void change_graph(const mlc_const(G)& g); void invalidate(); @@ -199,7 +230,15 @@ namespace mln template <typename G> inline - edge<G>::edge(const G& g, unsigned id) + edge<G>::edge(const G& g, id_value_t id) + : g_(g), id_(id) + { + mln_precondition(g_.is_valid() && g.has_e(id)); + } + + template <typename G> + inline + edge<G>::edge(const G& g, const edge_id_t& id) : g_(g), id_(id) { mln_precondition(g_.is_valid() && g.has_e(id)); @@ -207,7 +246,7 @@ namespace mln template <typename G> inline - unsigned + edge_id_t edge<G>::id() const { return id_; @@ -216,14 +255,14 @@ namespace mln template <typename G> inline void - edge<G>::update_id(unsigned id) + edge<G>::update_id(const edge_id_t& id) { id_ = id; } template <typename G> inline - edge<G>::operator unsigned() const + edge<G>::operator edge_id_t() const { return id_; } @@ -249,7 +288,7 @@ namespace mln bool edge<G>::is_valid() const { - return g_.is_valid() && g_.has_e(id_); + return g_.is_valid() && id_.is_valid() && g_.has_e(id_); } template <typename G> @@ -257,14 +296,15 @@ namespace mln void edge<G>::invalidate() { - id_ = mln_max(unsigned); + //id_ = mln_max(unsigned); + id_.invalidate(); } template <typename G> inline - unsigned - edge<G>::v_other(unsigned id_v) const + vertex_id_t + edge<G>::v_other(const vertex_id_t& id_v) const { mln_precondition(v1() == id_v || v2() == id_v); return g_.v_other(id_, id_v); @@ -272,7 +312,7 @@ namespace mln template <typename G> inline - unsigned + vertex_id_t edge<G>::v1() const { mln_precondition(g_.has_e(id_)); @@ -281,7 +321,7 @@ namespace mln template <typename G> inline - unsigned + vertex_id_t edge<G>::v2() const { mln_precondition(g_.has_e(id_)); @@ -299,7 +339,7 @@ namespace mln template <typename G> inline - unsigned + edge_id_t edge<G>::ith_nbh_edge(unsigned i) const { mln_precondition(g_.has_e(id_)); @@ -351,7 +391,7 @@ namespace mln template <typename G, typename E> inline - unsigned + util::edge_id_t subject_impl< const util::edge<G>, E >::id() const { return exact_().get_subject().id(); @@ -367,23 +407,15 @@ namespace mln template <typename G, typename E> inline - unsigned - subject_impl< const util::edge<G>, E >::v_other(unsigned id_v) const + util::vertex_id_t + subject_impl< const util::edge<G>, E >::v_other(const util::vertex_id_t& id_v) const { return exact_().get_subject().v_other(id_v); } template <typename G, typename E> inline - bool - subject_impl< const util::edge<G>, E >::is_valid() const - { - return exact_().get_subject().is_valid(); - } - - template <typename G, typename E> - inline - unsigned + util::vertex_id_t subject_impl< const util::edge<G>, E >::v1() const { return exact_().get_subject().v1(); @@ -391,7 +423,7 @@ namespace mln template <typename G, typename E> inline - unsigned + util::vertex_id_t subject_impl< const util::edge<G>, E >::v2() const { return exact_().get_subject().v2(); @@ -407,7 +439,7 @@ namespace mln template <typename G, typename E> inline - unsigned + util::edge_id_t subject_impl< const util::edge<G>, E >::ith_nbh_edge(unsigned i) const { return exact_().get_subject().ith_nbh_edge(i); @@ -415,13 +447,13 @@ namespace mln /*----------------------------------` - | subject_impl< util::edge<G> | - \----------------------------------*/ + | subject_impl< util::edge<G> | + \----------------------------------*/ template <typename G, typename E> inline void - subject_impl< util::edge<G>, E >::update_id(unsigned id) + subject_impl< util::edge<G>, E >::update_id(const util::edge_id_t& id) { return exact_().get_subject().update_id(id); } diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh index c93e0f9..0614b61 100644 --- a/milena/mln/util/graph.hh +++ b/milena/mln/util/graph.hh @@ -36,17 +36,15 @@ # include <mln/util/internal/graph_base.hh> # include <mln/util/internal/graph_iter.hh> # include <mln/util/internal/graph_nbh_iter.hh> +# include <mln/util/vertex.hh> +# include <mln/util/edge.hh> # include <mln/util/ord_pair.hh> - namespace mln { - namespace util - { - /// Forward declaration. - class graph; - } + /// Forward declaration. + namespace util { class graph; } namespace internal @@ -57,9 +55,9 @@ namespace mln struct data<util::graph> { typedef util::graph G; - typedef std::vector<std::vector<unsigned> > vertices_t; - typedef std::vector<util::ord_pair<unsigned> > edges_t; - typedef std::set<util::ord_pair<unsigned> > edges_set_t; + typedef std::vector<std::vector<util::edge_id_t> > vertices_t; + typedef std::vector<util::ord_pair<util::vertex_id_t> > edges_t; + typedef std::set<util::ord_pair<util::vertex_id_t> > edges_set_t; data(); /// Constructor. @@ -159,34 +157,34 @@ namespace mln /// Add \p n vertices to the graph. /// /// \return A range of vertex ids. - std::pair<unsigned, unsigned> add_vertices(unsigned n); + std::pair<vertex_id_t, vertex_id_t> add_vertices(unsigned n); /// Return the vertex whose id is \a v. /// \{ - vertex_t vertex(unsigned id_v) const; + vertex_t vertex(vertex_id_t id_v) const; /// \} /// Return the number of vertices in the graph. size_t v_nmax() const; /// Check whether a vertex id \p id_v exists in the graph. - bool has_v(unsigned id_v) const; - /// Check whether an edge \p v exists in the graph. - template <typename G> - bool has_v(const util::vertex<G>& v) const; + bool has_v(const vertex_id_t& id_v) const; /// Return the number of adjacent edges of vertex \p id_v. - size_t v_nmax_nbh_edges(unsigned id_v) const; + size_t v_nmax_nbh_edges(const vertex_id_t& id_v) const; /// Returns the \p i th edge adjacent to the vertex \p id_v. - unsigned v_ith_nbh_edge(unsigned id_v, unsigned i) const; + edge_id_t + v_ith_nbh_edge(const vertex_id_t& id_v, + unsigned i) const; /// Return the number of adjacent vertices of vertex \p id_v. - size_t v_nmax_nbh_vertices(unsigned id_v) const; + size_t v_nmax_nbh_vertices(const vertex_id_t& id_v) const; /// Returns the \p i th vertex adjacent to the vertex \p id_v. - unsigned v_ith_nbh_vertex(unsigned id_v, unsigned i) const; + vertex_id_t v_ith_nbh_vertex(const vertex_id_t& id_v, + unsigned i) const; /// \} @@ -197,36 +195,33 @@ namespace mln /// /// \return The id of the new edge if it does not exist yet; /// otherwise, return <tt>mln_max(unsigned)</tt>. - unsigned add_edge(unsigned id_v1, unsigned id_v2); + edge_id_t add_edge(const vertex_id_t& id_v1, const vertex_id_t& id_v2); /// Return the edge whose id is \a e. - edge_t edge(unsigned e) const; + edge_t edge(const edge_id_t& e) const; /// Return the list of all edges. - const std::vector<util::ord_pair<unsigned> >& edges() const; + const std::vector<util::ord_pair<vertex_id_t> >& edges() const; /// Return the number of edges in the graph. size_t e_nmax() const; /// Return whether \p id_e is in the graph. - bool has_e(unsigned id_e) const; - /// Return whether \p e is in the graph. - template <typename G> - bool has_e(const util::edge<G>& e) const; + bool has_e(const edge_id_t& id_e) const; /// Return the first vertex associated to the edge \p id_e. - unsigned v1(unsigned id_e) const; + vertex_id_t v1(const edge_id_t& id_e) const; /// Return the second vertex associated to edge \p id_e - unsigned v2(unsigned id_e) const; + vertex_id_t v2(const edge_id_t& id_e) const; /// Return the number max of adjacent edge, given an edge \p id_e. - size_t e_nmax_nbh_edges(unsigned id_e) const; + size_t e_nmax_nbh_edges(const edge_id_t& id_e) const; /// Return the \p i th edge adjacent to the edge \p id_e. - unsigned e_ith_nbh_edge(unsigned id_e, unsigned i) const; + edge_id_t e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const; /// Return whether this graph is a subgraph /// Return true if g and *this have the same graph_id. @@ -303,7 +298,7 @@ namespace mln } inline - std::pair<unsigned, unsigned> + std::pair<vertex_id_t, vertex_id_t> graph::add_vertices(unsigned n) { /* FIXME: This is not thread-proof (these two lines should @@ -316,7 +311,7 @@ namespace mln inline graph::vertex_t - graph::vertex(unsigned id_v) const + graph::vertex(vertex_id_t id_v) const { mln_assertion(has_v(id_v)); return vertex_t(*this, id_v); @@ -332,54 +327,46 @@ namespace mln inline bool - graph::has_v(unsigned id_v) const + graph::has_v(const vertex_id_t& id_v) const { return id_v < data_->vertices_.size(); } - template <typename G> - inline - bool - graph::has_v(const util::vertex<G>& v) const - { - return v.graph().is_subgraph_of(*this) && has_v(v.id()); - } - inline size_t - graph::v_nmax_nbh_edges(unsigned id_v) const + graph::v_nmax_nbh_edges(const vertex_id_t& id_v) const { mln_precondition(has_v(id_v)); return data_->vertices_[id_v].size(); } inline - unsigned - graph::v_ith_nbh_edge(unsigned id_v, unsigned i) const + edge_id_t + graph::v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const { mln_precondition(has_v(id_v)); if (i >= v_nmax_nbh_edges(id_v)) - return v_nmax(); + return edge_id_t(); return data_->vertices_[id_v][i]; } inline size_t - graph::v_nmax_nbh_vertices(unsigned id_v) const + graph::v_nmax_nbh_vertices(const vertex_id_t& id_v) const { mln_precondition(has_v(id_v)); return v_nmax_nbh_edges(id_v); } inline - unsigned - graph::v_ith_nbh_vertex(unsigned id_v, unsigned i) const + vertex_id_t + graph::v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const { mln_precondition(has_v(id_v)); - unsigned id_e = v_ith_nbh_edge(id_v, i); + edge_id_t id_e = v_ith_nbh_edge(id_v, i); return v_other(id_e, id_v); - } + } /*--------------. @@ -387,8 +374,8 @@ namespace mln `---------------*/ inline - unsigned - graph::add_edge(unsigned id_v1, unsigned id_v2) + edge_id_t + graph::add_edge(const vertex_id_t& id_v1, const vertex_id_t& id_v2) { //FIXME: to be removed! We should not check that, except in without NDEBUG. // Does this edge already exist in the graph? @@ -397,7 +384,7 @@ namespace mln if (data_->edges_set_.find(edge) != data_->edges_set_.end ()) { // Return the erroneous value. - return mln_max(unsigned); + return edge_id_t(); } else { @@ -406,7 +393,7 @@ namespace mln /* FIXME: This is not thread-proof (these two lines should form an atomic section). */ data_->edges_.push_back(edge); - unsigned id = data_->edges_.size() - 1; + edge_id_t id = data_->edges_.size() - 1; // Update the set of edges. # ifndef NDEBUG @@ -424,7 +411,7 @@ namespace mln } inline - const std::vector<util::ord_pair<unsigned> >& + const std::vector<util::ord_pair<vertex_id_t> >& graph::edges() const { return this->data_->edges_; @@ -432,7 +419,7 @@ namespace mln inline graph::edge_t - graph::edge(unsigned e) const + graph::edge(const edge_id_t& e) const { mln_assertion(e < e_nmax()); return edge_t(*this, e); @@ -447,30 +434,22 @@ namespace mln inline bool - graph::has_e(unsigned id_e) const + graph::has_e(const edge_id_t& id_e) const { return id_e < data_->edges_.size(); } - template <typename G> - inline - bool - graph::has_e(const util::edge<G>& e) const - { - return e.graph().is_subgraph_of(*this) && has_e(e.id()); - } - inline - unsigned - graph::v1(unsigned id_e) const + vertex_id_t + graph::v1(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].first(); } inline - unsigned - graph::v2(unsigned id_e) const + vertex_id_t + graph::v2(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].second(); @@ -478,15 +457,15 @@ namespace mln inline size_t - graph::e_nmax_nbh_edges(unsigned id_e) const + graph::e_nmax_nbh_edges(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e)); } inline - unsigned - graph::e_ith_nbh_edge(unsigned id_e, unsigned i) const + edge_id_t + graph::e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const { mln_precondition(has_e(id_e)); if (i >= e_nmax_nbh_edges(id_e)) diff --git a/milena/tests/make/dummy_p_vertices.cc b/milena/mln/util/graph_ids.hh similarity index 54% copy from milena/tests/make/dummy_p_vertices.cc copy to milena/mln/util/graph_ids.hh index 6cfa2b8..df3e981 100644 --- a/milena/tests/make/dummy_p_vertices.cc +++ b/milena/mln/util/graph_ids.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009 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 @@ -21,55 +22,41 @@ // 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 +// License. // reasons why the executable file might be covered by the GNU General // Public License. -/// \file tests/make/dummy_p_vertices.cc +#ifndef MLN_UTIL_GRAPH_IDS_HH +# define MLN_UTIL_GRAPH_IDS_HH + +/// \file mln/util/graph_ids.hh /// -/// Tests on mln::make::dummy_p_vertices. +/// Definition of graph element ids. +# include <mln/core/concept/object_id.hh> -#include <mln/core/image/image2d.hh> -#include <mln/core/site_set/p_array.hh> -#include <mln/util/graph.hh> +namespace mln +{ -#include <mln/value/label_8.hh> + namespace util + { -#include <mln/make/dummy_p_vertices.hh> + /// Object id vertex tag + struct vertex_tag; -int main() -{ - using namespace mln; + /// Vertex id type. + typedef object_id<vertex_tag, unsigned> vertex_id_t; - typedef util::graph G; - G g; - g.add_vertices(5); - g.add_edge(1,2); - g.add_edge(1,3); - g.add_edge(4,3); - g.add_edge(4,2); + // Edge tag for object_id. + struct edge_tag; - { - typedef p_vertices<G, pw::cst_<int> > pe_t; - pe_t pe = make::dummy_p_vertices(g); - - mln_assertion(pe.nsites() == 4); - mln_piter_(pe_t) p(pe); - for_all(p) - mln_assertion(p == 0); - } + // Edge id type. + typedef object_id<edge_tag, unsigned> edge_id_t; - { - typedef p_vertices<G, pw::cst_<point2d> > pe_t; - pe_t pe = make::dummy_p_vertices(g, point2d::plus_infty()); + } // end of namespace mln::util - mln_assertion(pe.nsites() == 4); - mln_piter_(pe_t) p(pe); - for_all(p) - mln_assertion(p == point2d::plus_infty()); - } +} // end of namespace mln -} +#endif // ! MLN_UTIL_GRAPH_IDS_HH diff --git a/milena/mln/util/internal/graph_base.hh b/milena/mln/util/internal/graph_base.hh index f011324..7724087 100644 --- a/milena/mln/util/internal/graph_base.hh +++ b/milena/mln/util/internal/graph_base.hh @@ -70,13 +70,14 @@ namespace mln protected: /// The type of a vertex. typedef util::vertex<E> vertex_t; - /// Internal vertex data type - typedef std::vector<unsigned> vertex_data_t; - /// The type of an edge. typedef util::edge<E> edge_t; + + /// Internal vertex data type + typedef std::vector<edge_id_t> vertex_data_t; + /// Internal edge data type. - typedef ord_pair<unsigned> edge_data_t; + typedef ord_pair<vertex_id_t> edge_data_t; public: /// Misc. methods @@ -102,7 +103,7 @@ namespace mln /// Vertex and edge oriented methods. /// \{ /// Returns the other adjacent vertex id of a given edge id \p id_e. - unsigned v_other(unsigned id_e, unsigned id_v) const; + vertex_id_t v_other(const edge_id_t& id_e, const vertex_id_t& id_v) const; /// \} // FIXME: We might want to externalize this in routine of @@ -169,8 +170,8 @@ namespace mln template<typename E> inline - unsigned - graph_base<E>::v_other(unsigned id_e, unsigned id_v) const + vertex_id_t + graph_base<E>::v_other(const edge_id_t& id_e, const vertex_id_t& id_v) const { const E *g = exact(this); mln_precondition(g->has_e(id_e)); diff --git a/milena/mln/util/internal/graph_iter.hh b/milena/mln/util/internal/graph_iter.hh index 6da2e3c..7cfdcfd 100644 --- a/milena/mln/util/internal/graph_iter.hh +++ b/milena/mln/util/internal/graph_iter.hh @@ -62,11 +62,11 @@ namespace mln protected: /// Returns the id of the first element. /// Called in start(); - unsigned start_id_() const; + util::vertex_id_t start_id_() const; /// Returns the next element id. /// Called in next(); - unsigned next_id_() const; + util::vertex_id_t next_id_() const; friend class graph_iter_base<G, util::vertex<G>, vertex_fwd_iterator<G> >; }; @@ -90,11 +90,11 @@ namespace mln protected: /// Returns the id of the first element. /// Called in start(); - unsigned start_id_() const; + util::vertex_id_t start_id_() const; /// Returns the next element id. /// Called in next(); - unsigned next_id_() const; + util::vertex_id_t next_id_() const; friend class graph_iter_base<G, util::vertex<G>, vertex_bkd_iterator<G> >; }; @@ -118,11 +118,11 @@ namespace mln protected: /// Returns the id of the first element. /// Called in start(); - unsigned start_id_() const; + util::edge_id_t start_id_() const; /// Returns the next element id. /// Called in next(); - unsigned next_id_() const; + util::edge_id_t next_id_() const; friend class graph_iter_base<G, util::edge<G>, edge_fwd_iterator<G> >; }; @@ -146,11 +146,11 @@ namespace mln protected: /// Returns the id of the first element. /// Called in start(); - unsigned start_id_() const; + util::edge_id_t start_id_() const; /// Returns the next element id. /// Called in next(); - unsigned next_id_() const; + util::edge_id_t next_id_() const; friend class graph_iter_base<G, util::edge<G>, edge_bkd_iterator<G> >; }; @@ -180,7 +180,7 @@ namespace mln template <typename G> inline - unsigned + util::vertex_id_t vertex_fwd_iterator<G>::start_id_() const { return 0; @@ -188,7 +188,7 @@ namespace mln template <typename G> inline - unsigned + util::vertex_id_t vertex_fwd_iterator<G>::next_id_() const { return this->p_.id() + 1; @@ -215,7 +215,7 @@ namespace mln template <typename G> inline - unsigned + util::vertex_id_t vertex_bkd_iterator<G>::start_id_() const { return this->p_.graph().v_nmax() - 1; @@ -223,7 +223,7 @@ namespace mln template <typename G> inline - unsigned + util::vertex_id_t vertex_bkd_iterator<G>::next_id_() const { return this->p_.id() - 1; @@ -250,7 +250,7 @@ namespace mln template <typename G> inline - unsigned + util::edge_id_t edge_fwd_iterator<G>::start_id_() const { return 0; @@ -258,7 +258,7 @@ namespace mln template <typename G> inline - unsigned + util::edge_id_t edge_fwd_iterator<G>::next_id_() const { return this->p_.id() + 1; @@ -285,7 +285,7 @@ namespace mln template <typename G> inline - unsigned + util::edge_id_t edge_bkd_iterator<G>::start_id_() const { return this->p_.graph().e_nmax() - 1; @@ -293,7 +293,7 @@ namespace mln template <typename G> inline - unsigned + util::edge_id_t edge_bkd_iterator<G>::next_id_() const { return this->p_.id() - 1; diff --git a/milena/mln/util/internal/graph_iter_base.hh b/milena/mln/util/internal/graph_iter_base.hh index 10cbe64..b8b9fb9 100644 --- a/milena/mln/util/internal/graph_iter_base.hh +++ b/milena/mln/util/internal/graph_iter_base.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 @@ -64,11 +65,15 @@ namespace mln /// Go to the next value. void next(); - /// Return current index - unsigned index() const; + /// Return the element id. + typename Elt::id_t id() const; /// Conversion operator. Returns the element id. - operator unsigned() const; + operator typename Elt::id_t() const; + + /// Conversion operator. Returns the element id. + /// FIXME: May cause ambiguities. + operator typename Elt::id_value_t() const; /// Conversion operator. Returns the graph element. operator const Elt&() const; @@ -134,15 +139,22 @@ namespace mln template <typename G, typename Elt, typename E> inline - unsigned - graph_iter_base<G, Elt, E>::index() const + typename Elt::id_t + graph_iter_base<G, Elt, E>::id() const + { + return p_.id(); + } + + template <typename G, typename Elt, typename E> + inline + graph_iter_base<G, Elt, E>::operator typename Elt::id_t() const { return p_.id(); } template <typename G, typename Elt, typename E> inline - graph_iter_base<G, Elt, E>::operator unsigned() const + graph_iter_base<G, Elt, E>::operator typename Elt::id_value_t() const { return p_.id(); } diff --git a/milena/mln/util/internal/graph_nbh_iter.hh b/milena/mln/util/internal/graph_nbh_iter.hh index b99de7b..9d7d245 100644 --- a/milena/mln/util/internal/graph_nbh_iter.hh +++ b/milena/mln/util/internal/graph_nbh_iter.hh @@ -538,7 +538,7 @@ namespace mln // since it is computed thanks to the edge neighboors of its // two vertices. // We do not want the current edge to be part of its neighbors. - unsigned e_id = this->c_->ith_nbh_edge(this->i_); + util::edge_id_t e_id = this->c_->ith_nbh_edge(this->i_); while (e_id == this->c_->id()) { this->i_ = next_id_(); diff --git a/milena/mln/util/internal/graph_nbh_iter_base.hh b/milena/mln/util/internal/graph_nbh_iter_base.hh index 2654055..3e8e958 100644 --- a/milena/mln/util/internal/graph_nbh_iter_base.hh +++ b/milena/mln/util/internal/graph_nbh_iter_base.hh @@ -63,11 +63,19 @@ namespace mln /// Go to the next value. void next(); - /// Return current index + /// Return current index. + /// (The current element is the i-th neighbor) unsigned index() const; - /// Conversion operator. Returns the element ID. - operator unsigned() const; + /// Returns the element ID. + typename Elt::id_t id() const; + + /// Conversion operator. Returns the element id. + operator typename Elt::id_t() const; + + /// Conversion operator. Returns the element id. + /// FIXME: May cause ambiguities. + operator typename Elt::id_value_t() const; /// The psite around which this iterator moves. const C& center() const; @@ -173,7 +181,22 @@ namespace mln template <typename G, typename C, typename Elt, typename E> inline - nbh_iterator_base<G,C,Elt,E>::operator unsigned() const + typename Elt::id_t + nbh_iterator_base<G,C,Elt,E>::id() const + { + return elt_.id(); + } + + template <typename G, typename C, typename Elt, typename E> + inline + nbh_iterator_base<G,C,Elt,E>::operator typename Elt::id_t() const + { + return elt_.id(); + } + + template <typename G, typename C, typename Elt, typename E> + inline + nbh_iterator_base<G,C,Elt,E>::operator typename Elt::id_value_t() const { return elt_.id(); } diff --git a/milena/mln/util/internal/id2element.hh b/milena/mln/util/internal/id2element.hh new file mode 100644 index 0000000..d574dc3 --- /dev/null +++ b/milena/mln/util/internal/id2element.hh @@ -0,0 +1,100 @@ +// Copyright (C) 2009 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. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_UTIL_INTERNAL_ID2VERTEX_HH +# define MLN_UTIL_INTERNAL_ID2VERTEX_HH + +/// \file mln/util/id2element.hh +/// +/// Function constructing a element from an id. + +#include <mln/core/concept/graph.hh> + +namespace mln +{ + + namespace util + { + + namespace internal + { + + template <typename G, typename Elt> + struct id2element : Function_i2v< id2element<G,Elt> > + { + typedef Elt result; + + id2element(); + id2element(const Graph<G>& g); + Elt operator()(unsigned id) const; + + G g_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename G, typename Elt> + inline + id2element<G,Elt>::id2element() + { + } + + template <typename G, typename Elt> + inline + id2element<G,Elt>::id2element(const Graph<G>& g) + : g_(exact(g)) + { + } + + template <typename G, typename Elt> + inline + Elt + id2element<G,Elt>::operator()(unsigned id) const + { + mln_assertion(g_.is_valid()); + mln_assertion(g_.has(Elt(g_,id))); + /// FIXME: cannot check whether the graph has + /// its element since we must call the proper member according + /// to the element type (has_v or has_e)! + return Elt(g_, id); + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::util::internal + + } // end of namespace mln::util + +} // end of namespace mln + + +# endif // ! MLN_UTIL_INTERNAL_ID2VERTEX_HH + diff --git a/milena/mln/util/line_graph.hh b/milena/mln/util/line_graph.hh index ae49cbc..8ecf7b2 100644 --- a/milena/mln/util/line_graph.hh +++ b/milena/mln/util/line_graph.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory // (LRDE) // // This file is part of the Olena Library. This library is free @@ -30,6 +30,7 @@ # define MLN_UTIL_LINE_GRAPH_HH /// \file mln/util/line_graph.hh +/// /// Definitions of undirected graphs. # include <mln/util/internal/graph_base.hh> @@ -55,9 +56,9 @@ namespace mln template <typename G> struct data< util::line_graph<G> > { - - typedef std::vector<std::vector<unsigned> > vertices_t; - typedef std::vector<util::ord_pair<unsigned> > edges_t; + typedef util::line_graph<G> lg_t; + typedef std::vector<std::vector<util::edge_id_t> > vertices_t; + typedef std::vector<util::ord_pair<util::vertex_id_t> > edges_t; data(); data(const G& g); @@ -153,30 +154,30 @@ namespace mln /// \{ /// Return the vertex whose id is \a v. /// \{ - vertex_t vertex(unsigned id_v) const; + vertex_t vertex(const vertex_id_t& id_v) const; /// \} /// Return the number of vertices in the graph. size_t v_nmax() const; /// Check whether a vertex id \p id_v exists in the graph. - bool has_v(unsigned id_v) const; + bool has_v(const vertex_id_t& id_v) const; /// Check whether an edge \p v exists in the graph. template <typename G2> - bool has_v(const util::vertex<G2>& v) const; + bool has(const util::vertex<G2>& v) const; /// Return the number of adjacent edges of vertex \p id_v. - size_t v_nmax_nbh_edges(unsigned id_v) const; + size_t v_nmax_nbh_edges(const vertex_id_t& id_v) const; /// Returns the \p i th edge adjacent to the vertex \p id_v. - unsigned v_ith_nbh_edge(unsigned id_v, unsigned i) const; + edge_id_t v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const; /// Return the number of adjacent vertices of vertex \p id_v. - size_t v_nmax_nbh_vertices(unsigned id_v) const; + size_t v_nmax_nbh_vertices(const vertex_id_t& id_v) const; /// Returns the \p i th vertex adjacent to the vertex \p id_v. - unsigned v_ith_nbh_vertex(unsigned id_v, unsigned i) const; + vertex_id_t v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const; /// \} @@ -185,29 +186,30 @@ namespace mln /// Edge oriented. /// \{ /// Return the edge whose id is \a e. - edge_t edge(unsigned e) const; + edge_t edge(const edge_id_t& e) const; /// Return the number of edges in the graph. size_t e_nmax() const; /// Return whether \p id_e is in the graph. - bool has_e(unsigned id_e) const; + bool has_e(const util::edge_id_t& id_e) const; + /// Return whether \p e is in the graph. template <typename G2> - bool has_e(const util::edge<G2>& e) const; + bool has(const util::edge<G2>& e) const; /// Return the first vertex associated to the edge \p id_e. - unsigned v1(unsigned id_e) const; + vertex_id_t v1(const edge_id_t& id_e) const; /// Return the second vertex associated to edge \p id_e - unsigned v2(unsigned id_e) const; + vertex_id_t v2(const edge_id_t& id_e) const; /// Return the number max of adjacent edge, given an edge \p id_e. - size_t e_nmax_nbh_edges(unsigned id_e) const; + size_t e_nmax_nbh_edges(const edge_id_t& id_e) const; /// Return the \p i th edge adjacent to the edge \p id_e. - unsigned e_ith_nbh_edge(unsigned id_e, unsigned i) const; + edge_id_t e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const; /// Return whether this graph is a subgraph /// Return true if g and *this have the same graph_id. @@ -251,23 +253,29 @@ namespace mln g_ = g; // Initialize vertices and edges. - std::set<util::ord_pair<unsigned> > edges_set; + //FIXME: use an adjacency matrix!! + std::set<util::ord_pair<util::vertex_id_t> > edges_set; + vertices_.resize(g.e_nmax()); mln_edge_iter(G) e(g); mln_edge_nbh_edge_iter(G) ne(e); for_all(e) + { + util::vertex_id_t v1(e.id().value()); for_all(ne) { - util::ord_pair<unsigned> edge(e, ne); + util::vertex_id_t v2(ne.id().value()); + util::ord_pair<util::vertex_id_t> edge(v1, v2); if (edges_set.find(edge) == edges_set.end()) { - vertices_[e].push_back(edges_.size()); - vertices_[ne].push_back(edges_.size()); + vertices_[v1].push_back(edges_.size()); + vertices_[v2].push_back(edges_.size()); edges_set.insert(edge); edges_.push_back(edge); } } + } } template <typename G> @@ -302,7 +310,7 @@ namespace mln template <typename G> inline typename line_graph<G>::vertex_t - line_graph<G>::vertex(unsigned id_v) const + line_graph<G>::vertex(const vertex_id_t& id_v) const { mln_assertion(has_v(id_v)); return vertex_t(*this, id_v); @@ -320,16 +328,16 @@ namespace mln template <typename G> inline bool - line_graph<G>::has_v(unsigned id_v) const + line_graph<G>::has_v(const vertex_id_t& id_v) const { - return data_->g_.has_e(id_v); + return data_->g_.has_v(id_v); } template <typename G> template <typename G2> inline bool - line_graph<G>::has_v(const util::vertex<G2>& v) const + line_graph<G>::has(const util::vertex<G2>& v) const { //FIXME: not sure... return v.graph().is_subgraph_of(*this) && has_v(v.id()); @@ -338,7 +346,7 @@ namespace mln template <typename G> inline size_t - line_graph<G>::v_nmax_nbh_edges(unsigned id_v) const + line_graph<G>::v_nmax_nbh_edges(const vertex_id_t& id_v) const { mln_precondition(has_v(id_v)); return data_->vertices_[id_v].size(); @@ -346,8 +354,8 @@ namespace mln template <typename G> inline - unsigned - line_graph<G>::v_ith_nbh_edge(unsigned id_v, unsigned i) const + edge_id_t + line_graph<G>::v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const { mln_precondition(has_v(id_v)); if (i >= v_nmax_nbh_edges(id_v)) @@ -358,7 +366,7 @@ namespace mln template <typename G> inline size_t - line_graph<G>::v_nmax_nbh_vertices(unsigned id_v) const + line_graph<G>::v_nmax_nbh_vertices(const vertex_id_t& id_v) const { mln_precondition(has_v(id_v)); return v_nmax_nbh_edges(id_v); @@ -366,8 +374,8 @@ namespace mln template <typename G> inline - unsigned - line_graph<G>::v_ith_nbh_vertex(unsigned id_v, unsigned i) const + vertex_id_t + line_graph<G>::v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const { mln_precondition(has_v(id_v)); @@ -383,7 +391,7 @@ namespace mln template <typename G> inline typename line_graph<G>::edge_t - line_graph<G>::edge(unsigned e) const + line_graph<G>::edge(const edge_id_t& e) const { mln_assertion(e < e_nmax()); return edge_t(*this, e); @@ -400,7 +408,7 @@ namespace mln template <typename G> inline bool - line_graph<G>::has_e(unsigned id_e) const + line_graph<G>::has_e(const edge_id_t& id_e) const { return id_e < data_->edges_.size(); } @@ -409,15 +417,15 @@ namespace mln template <typename G2> inline bool - line_graph<G>::has_e(const util::edge<G2>& e) const + line_graph<G>::has(const util::edge<G2>& e) const { return e.graph().is_subgraph_of(*this) && has_e(e.id()); } template <typename G> inline - unsigned - line_graph<G>::v1(unsigned id_e) const + vertex_id_t + line_graph<G>::v1(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].first(); @@ -425,8 +433,8 @@ namespace mln template <typename G> inline - unsigned - line_graph<G>::v2(unsigned id_e) const + vertex_id_t + line_graph<G>::v2(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].second(); @@ -435,7 +443,7 @@ namespace mln template <typename G> inline size_t - line_graph<G>::e_nmax_nbh_edges(unsigned id_e) const + line_graph<G>::e_nmax_nbh_edges(const edge_id_t& id_e) const { mln_precondition(has_e(id_e)); return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e)); @@ -443,8 +451,8 @@ namespace mln template <typename G> inline - unsigned - line_graph<G>::e_ith_nbh_edge(unsigned id_e, unsigned i) const + edge_id_t + line_graph<G>::e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const { mln_precondition(has_e(id_e)); if (i >= e_nmax_nbh_edges(id_e)) diff --git a/milena/mln/util/vertex.hh b/milena/mln/util/vertex.hh index 9b55f9b..4b43ef3 100644 --- a/milena/mln/util/vertex.hh +++ b/milena/mln/util/vertex.hh @@ -30,6 +30,7 @@ # define MLN_UTIL_VERTEX_HH # include <iostream> +# include <mln/util/graph_ids.hh> # include <mln/util/internal/vertex_impl.hh> # include <mln/core/concept/proxy.hh> @@ -42,15 +43,42 @@ namespace mln { + // Forward declaration. + namespace util { template<typename G> class vertex; } + + /// Vertex category flag type. + template <typename E> + struct Vertex + { + }; + + template <> + struct Vertex<void> + { + typedef Site<void> super; + }; + + + namespace util { /// Vertex of a graph \p G. template<typename G> - class vertex : public internal::vertex_impl_<G> + class vertex + : public Site< vertex<G> >, + public internal::vertex_impl_<G> { public: + /// Object category. + typedef Vertex<void> Category; + + /// The underlying type used to store vertex ids. + typedef typename vertex_id_t::value_t id_value_t; + + /// The vertex type id. + typedef vertex_id_t id_t; /// Graph associated type. typedef G graph_t; @@ -59,7 +87,8 @@ namespace mln /// \{ vertex(); explicit vertex(const G& g); - vertex(const G& g, unsigned id); + vertex(const G& g, const id_value_t& id); + vertex(const G& g, const vertex_id_t& id); /// \} /// Check whether the vertex is still part of the graph. @@ -67,10 +96,11 @@ namespace mln /// Invalidate that vertex. void invalidate(); - unsigned other(unsigned id_e) const; + /// Returns the other vertex located on edge \p id_e. + vertex_id_t other(const edge_id_t& id_e) const; /// Returns the ith edge starting from this vertex. - unsigned ith_nbh_edge(unsigned i) const; + edge_id_t ith_nbh_edge(unsigned i) const; /// Returns the number max of edges starting from this vertex. /// If g_ is a sub graph of another graph, nmax will be retrived from @@ -78,7 +108,7 @@ namespace mln unsigned nmax_nbh_edges() const; /// Returns the ith vertex adjacent to this vertex. - unsigned ith_nbh_vertex(unsigned i) const; + vertex_id_t ith_nbh_vertex(unsigned i) const; /// Returns the number max of vertices adjacent to this vertex. unsigned nmax_nbh_vertices() const; @@ -87,20 +117,21 @@ namespace mln void change_graph(const G& g); /// Update the vertex id. - void update_id(unsigned id); + void update_id(const vertex_id_t& id); /// Returns the graph pointer this vertex belongs to. const G& graph() const; /// Returns the vertex id. - unsigned id() const; + const vertex_id_t& id() const; /// Conversion to the vertex id. - operator unsigned() const; + /// FIXME: May cause ambiguities... :( + operator vertex_id_t() const; protected: G g_; - unsigned id_; + vertex_id_t id_; }; @@ -135,14 +166,18 @@ namespace mln template <typename G, typename E> struct subject_impl< const util::vertex<G>, E > { - bool is_valid() const; +// Can't be provided since there is an ambiguity with the iterator's +// member. +// +// bool is_valid() const; + const G& graph() const; - unsigned id() const; + const util::vertex_id_t& id() const; - unsigned other(unsigned id_e) const; - unsigned ith_nbh_edge(unsigned i) const; + util::vertex_id_t other(const util::edge_id_t& id_e) const; + util::edge_id_t ith_nbh_edge(unsigned i) const; unsigned nmax_nbh_edges() const; - unsigned ith_nbh_vertex(unsigned i) const; + util::vertex_id_t ith_nbh_vertex(unsigned i) const; unsigned nmax_nbh_vertices() const; private: @@ -155,7 +190,7 @@ namespace mln { void invalidate(); void change_graph(const G& g); - void update_id(unsigned id); + void update_id(const util::vertex_id_t& id); private: E& exact_(); @@ -195,7 +230,15 @@ namespace mln template<typename G> inline - vertex<G>::vertex(const G& g, unsigned id) + vertex<G>::vertex(const G& g, const id_value_t& id) + : g_(g), id_(id) + { + mln_assertion(is_valid()); + } + + template<typename G> + inline + vertex<G>::vertex(const G& g, const vertex_id_t& id) : g_(g), id_(id) { mln_assertion(is_valid()); @@ -219,8 +262,8 @@ namespace mln template<typename G> inline - unsigned - vertex<G>::other(unsigned id_e) const + vertex_id_t + vertex<G>::other(const edge_id_t& id_e) const { mln_precondition(g_.has_v(id_)); mln_precondition(g_.has_e(id_e)); @@ -230,7 +273,7 @@ namespace mln template<typename G> inline - unsigned + edge_id_t vertex<G>::ith_nbh_edge(unsigned i) const { mln_precondition(g_.has_v(id_)); @@ -248,7 +291,7 @@ namespace mln template<typename G> inline - unsigned + vertex_id_t vertex<G>::ith_nbh_vertex(unsigned i) const { mln_precondition(g_.has_v(id_)); @@ -275,7 +318,7 @@ namespace mln template<typename G> inline void - vertex<G>::update_id(unsigned id) + vertex<G>::update_id(const vertex_id_t& id) { id_ = id; } @@ -290,7 +333,7 @@ namespace mln template<typename G> inline - unsigned + const vertex_id_t& vertex<G>::id() const { return id_; @@ -298,7 +341,7 @@ namespace mln template<typename G> inline - vertex<G>::operator unsigned() const + vertex<G>::operator vertex_id_t() const { return id_; } @@ -344,14 +387,6 @@ namespace mln template <typename G, typename E> inline - bool - subject_impl< const util::vertex<G>, E >::is_valid() const - { - return exact_().get_subject().is_valid(); - } - - template <typename G, typename E> - inline const G& subject_impl< const util::vertex<G>, E >::graph() const { @@ -360,7 +395,7 @@ namespace mln template <typename G, typename E> inline - unsigned + const util::vertex_id_t& subject_impl< const util::vertex<G>, E >::id() const { return exact_().get_subject().id(); @@ -370,15 +405,15 @@ namespace mln template <typename G, typename E> inline - unsigned - subject_impl< const util::vertex<G>, E >::other(unsigned id_e) const + util::vertex_id_t + subject_impl< const util::vertex<G>, E >::other(const util::edge_id_t& id_e) const { return exact_().get_subject().other(id_e); } template <typename G, typename E> inline - unsigned + util::edge_id_t subject_impl< const util::vertex<G>, E >::ith_nbh_edge(unsigned i) const { return exact_().get_subject().ith_nbh_edge(i); @@ -394,7 +429,7 @@ namespace mln template <typename G, typename E> inline - unsigned + util::vertex_id_t subject_impl< const util::vertex<G>, E >::ith_nbh_vertex(unsigned i) const { return exact_().get_subject().ith_nbh_vertex(i); @@ -435,7 +470,7 @@ namespace mln template <typename G, typename E> inline void - subject_impl< util::vertex<G>, E >::update_id(unsigned id) + subject_impl< util::vertex<G>, E >::update_id(const util::vertex_id_t& id) { exact_().get_subject().update_id(id); }; diff --git a/milena/tests/make/dummy_p_vertices.cc b/milena/tests/make/dummy_p_vertices.cc index 6cfa2b8..344d72c 100644 --- a/milena/tests/make/dummy_p_vertices.cc +++ b/milena/tests/make/dummy_p_vertices.cc @@ -55,7 +55,7 @@ int main() typedef p_vertices<G, pw::cst_<int> > pe_t; pe_t pe = make::dummy_p_vertices(g); - mln_assertion(pe.nsites() == 4); + mln_assertion(pe.nsites() == 5); mln_piter_(pe_t) p(pe); for_all(p) mln_assertion(p == 0); @@ -65,7 +65,7 @@ int main() typedef p_vertices<G, pw::cst_<point2d> > pe_t; pe_t pe = make::dummy_p_vertices(g, point2d::plus_infty()); - mln_assertion(pe.nsites() == 4); + mln_assertion(pe.nsites() == 5); mln_piter_(pe_t) p(pe); for_all(p) mln_assertion(p == point2d::plus_infty()); diff --git a/milena/tests/morpho/graph_image_morpho.cc b/milena/tests/morpho/graph_image_morpho.cc index 35b3045..5f42933 100644 --- a/milena/tests/morpho/graph_image_morpho.cc +++ b/milena/tests/morpho/graph_image_morpho.cc @@ -42,6 +42,7 @@ #include <mln/core/var.hh> #include <mln/fun/i2v/array.hh> #include <mln/util/graph.hh> +#include <mln/make/vertex_image.hh> #include <mln/debug/draw_graph.hh> #include <mln/debug/iota.hh> @@ -102,8 +103,8 @@ int main() for (unsigned i = 0; i < iota.size(); ++i) iota(i) = 10 + i; - typedef vertex_image<point2d,unsigned,util::graph> ima_t; - ima_t ima(g, sites, iota); + typedef vertex_image<point2d, unsigned, util::graph> ima_t; + ima_t ima = make::vertex_image(g, sites, iota); /*-------------------------------------. | Image representation/visualization. | diff --git a/milena/tests/morpho/graph_image_wst.cc b/milena/tests/morpho/graph_image_wst.cc index 7eb1c24..c3d0fc6 100644 --- a/milena/tests/morpho/graph_image_wst.cc +++ b/milena/tests/morpho/graph_image_wst.cc @@ -38,6 +38,7 @@ #include <mln/core/var.hh> #include <mln/fun/i2v/array.hh> #include <mln/util/graph.hh> +#include <mln/make/vertex_image.hh> #include <mln/morpho/meyer_wst.hh> @@ -95,8 +96,8 @@ int main() for (unsigned i = 0; i < iota.size(); ++i) iota(i) = 10 + i; - typedef vertex_image<point2d,unsigned,util::graph> ima_t; - ima_t ima(g,sites,iota); + typedef vertex_image<point2d, unsigned, util::graph> ima_t; + ima_t ima = make::vertex_image(g, sites, iota); /*------. | WST. | diff --git a/milena/tests/morpho/line_graph_image_morpho.cc b/milena/tests/morpho/line_graph_image_morpho.cc index 3a5becb..adee818 100644 --- a/milena/tests/morpho/line_graph_image_morpho.cc +++ b/milena/tests/morpho/line_graph_image_morpho.cc @@ -38,6 +38,7 @@ #include <mln/util/line_graph.hh> #include <mln/util/graph.hh> #include <mln/util/site_pair.hh> +#include <mln/make/vertex_image.hh> #include <mln/morpho/erosion.hh> #include <mln/morpho/dilation.hh> @@ -103,8 +104,8 @@ int main() for (unsigned i = 0; i < iota.size(); ++i) iota(i) = 10 + i; - typedef vertex_image<P,unsigned,util::line_graph<util::graph> > ima_t; - ima_t ima(lg, sites, iota); + typedef vertex_image< P, unsigned, util::line_graph<util::graph> > ima_t; + ima_t ima = make::vertex_image(lg, sites, iota); /*-------------------------------. diff --git a/milena/tests/morpho/line_graph_image_wst.cc b/milena/tests/morpho/line_graph_image_wst.cc index afc39ba..67af966 100644 --- a/milena/tests/morpho/line_graph_image_wst.cc +++ b/milena/tests/morpho/line_graph_image_wst.cc @@ -39,6 +39,7 @@ #include <mln/util/graph.hh> #include <mln/util/line_graph.hh> #include <mln/util/site_pair.hh> +#include <mln/make/vertex_image.hh> #include <mln/morpho/watershed/flooding.hh> @@ -105,7 +106,7 @@ int main() sites(9) = P(point2d(1,2), point2d(1,3)); // Site associated to vertex 6. // Edge values. - typedef fun::i2v::array<int> edge_values_t; + typedef fun::i2v::array<unsigned> edge_values_t; edge_values_t edge_values(10); static const unsigned values[] = { 0, 10, 5, 2, 4, 6, 0, 3, 5, 2 }; @@ -113,7 +114,7 @@ int main() edge_values(i) = values[i]; typedef vertex_image< P, unsigned, util::line_graph<util::graph> > ima_t; - ima_t ima(lg, sites, edge_values); + ima_t ima = make::vertex_image(lg, sites, edge_values); /*------------. diff --git a/milena/tests/util/graph.cc b/milena/tests/util/graph.cc index d832023..7e3910e 100644 --- a/milena/tests/util/graph.cc +++ b/milena/tests/util/graph.cc @@ -53,26 +53,26 @@ int main () unsigned i = 0; mln_vertex_fwd_iter_(util::graph) v(g); for_all(v) - mln_assertion(i++ == v.index()); + mln_assertion(i++ == v.id()); mln_assertion(i != 0); i = 0; mln_edge_fwd_iter_(util::graph) e(g); for_all(e) - mln_assertion(i++ == e.index()); + mln_assertion(i++ == e.id()); mln_assertion(i != 0); } { unsigned i = g.v_nmax() - 1; mln_vertex_bkd_iter_(util::graph) v(g); for_all(v) - mln_assertion(i-- == v.index()); + mln_assertion(i-- == v.id()); mln_assertion(i != g.v_nmax() - 1); i = g.e_nmax() - 1; mln_edge_bkd_iter_(util::graph) e(g); for_all(e) - mln_assertion(i-- == e.index()); + mln_assertion(i-- == e.id()); mln_assertion(i != g.e_nmax() - 1); } @@ -84,7 +84,7 @@ int main () { unsigned i = 0; for_all(n) - mln_assertion(i++ == n.index()); + mln_assertion(i++ == n.id()); mln_assertion(i != 0); } } @@ -95,7 +95,7 @@ int main () { unsigned i = v.nmax_nbh_edges(); for_all(e) - mln_assertion(--i == e.index()); + mln_assertion(--i == e.id()); mln_assertion((v.nmax_nbh_edges() == 0 && i == 0) || i != v.nmax_nbh_edges()); } } diff --git a/milena/tests/util/line_graph.cc b/milena/tests/util/line_graph.cc index 1a65dee..811a695 100644 --- a/milena/tests/util/line_graph.cc +++ b/milena/tests/util/line_graph.cc @@ -61,13 +61,13 @@ int main() unsigned i = 0; mln_vertex_fwd_iter_(LG) v(lg); for_all(v) - mln_assertion(i++ == v.index()); + mln_assertion(i++ == v.id()); mln_assertion(i != 0); i = 0; mln_edge_fwd_iter_(LG) e(lg); for_all(e) - mln_assertion(i++ == e.index()); + mln_assertion(i++ == e.id()); mln_assertion(i != 0); } @@ -76,13 +76,13 @@ int main() unsigned i = lg.v_nmax() - 1; mln_vertex_bkd_iter_(LG) v(lg); for_all(v) - mln_assertion(i-- == v.index()); + mln_assertion(i-- == v.id()); mln_assertion(i != lg.v_nmax() - 1); i = lg.e_nmax() - 1; mln_edge_bkd_iter_(LG) e(lg); for_all(e) - mln_assertion(i-- == e.index()); + mln_assertion(i-- == e.id()); mln_assertion(i != lg.e_nmax() - 1); } @@ -94,7 +94,7 @@ int main() { unsigned i = 0; for_all(n) - mln_assertion(i++ == n.index()); + mln_assertion(i++ == n.id()); mln_assertion(i != 0); } } @@ -107,7 +107,7 @@ int main() { unsigned i = v.nmax_nbh_edges(); for_all(e) - mln_assertion(--i == e.index()); + mln_assertion(--i == e.id()); mln_assertion((v.nmax_nbh_edges() == 0 && i == 0) || i != v.nmax_nbh_edges()); } } -- 1.5.6.5
participants (1)
-
Guillaume Lazzara