
--- milena/mln/core/site_set/p_vertices.hh | 281 ++++++++++++++++++++++++ milena/mln/util/internal/graph_vertex_psite.hh | 190 ++++++++++++++++ milena/tests/core/site_set/Makefile.am | 4 +- milena/tests/core/site_set/p_vertices.cc | 91 ++++++++ 4 files changed, 565 insertions(+), 1 deletions(-) create mode 100644 milena/mln/core/site_set/p_vertices.hh create mode 100644 milena/mln/util/internal/graph_vertex_psite.hh create mode 100644 milena/tests/core/site_set/p_vertices.cc diff --git a/milena/mln/core/site_set/p_vertices.hh b/milena/mln/core/site_set/p_vertices.hh new file mode 100644 index 0000000..461bd51 --- /dev/null +++ b/milena/mln/core/site_set/p_vertices.hh @@ -0,0 +1,281 @@ + // Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) + // + // This file is part of the Olena Library. This library is free + // software; you can redistribute it and/or modify it under the terms + // of the GNU General Public License version 2 as published by the + // Free Software Foundation. + // + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + // General Public License for more details. + // + // You should have received a copy of the GNU General Public License + // along with this library; see the file COPYING. If not, write to + // the Free Software Foundation, 51 Franklin Street, Fifth Floor, + // Boston, MA 02111-1307, USA. + // + // As a special exception, you may use this file as part of a free + // software library without restriction. Specifically, if other files + // instantiate templates or use macros or inline functions from this + // file, or you compile this file and link it with other files to + // produce an executable, this file does not by itself cause the + // resulting executable to be covered by the GNU General Public + // License. + // reasons why the executable file might be covered by the GNU General + // Public License. + +#ifndef MLN_CORE_SITE_SET_P_VERTICES_HH +# define MLN_CORE_SITE_SET_P_VERTICES_HH + + /// \file mln/core/site_set/p_vertices.hh + /// \brief Definition of a point set based on a graph. + +# include <mln/core/internal/site_set_base.hh> +# include <mln/core/site_set/p_graph_piter.hh> +# include <mln/util/internal/graph_vertex_psite.hh> +# include <mln/util/graph.hh> + + //# include <mln/util/tracked_ptr.hh> + + //# include <mln/core/image/graph_psite.hh> + //# include <mln/core/site_set/p_vertices_piter.hh> + +namespace mln +{ + // Forward declaration. + template <typename G, typename F> struct p_vertices; + + namespace trait + { + template <typename G, typename F> + struct site_set_< p_vertices<G, F> > + { + typedef trait::site_set::nsites::known nsites; + // FIXME: ! + typedef trait::site_set::bbox::unknown bbox; + typedef trait::site_set::contents::fixed contents; + typedef trait::site_set::arity::unique arity; + }; + } // end of namespace mln::trait + + + template <typename G, typename F> + class p_vertices + : public internal::site_set_base_< typename F::result, p_vertices<G, F> > + { + typedef util::vertex<G> vertex_t; + + typedef p_vertices<G, F> self_; + typedef internal::site_set_base_< typename F::result, self_ > super_; + + typedef G graph_t; + + public: + /// \brief Construct a graph psite set from a graph of points. + /// + /// \param gr The graph upon which the graph psite set is built. + /// + /// \a gr is \em copied internally, so that the graph psite set is + /// still valid after the initial graph has been removed. + p_vertices(const graph_t& gr, const F& f); + + /// Associated types. + /// \{ + /// Element associated type. + typedef mln_site(super_) element; + /// Point_Site associated type. + typedef internal::vertex_psite<G, F> psite; + + /// Forward Site_Iterator associated type. + typedef p_graph_piter< self_, mln_vertex_fwd_iter(G) > fwd_piter; + + /// Backward Site_Iterator associated type. + typedef p_graph_piter< self_, mln_vertex_bkd_iter(G) > bkd_piter; + + /// Site_Iterator associated type. + typedef fwd_piter piter; + /// \} + + /// \brief Return The number of points (sites) of the set, i.e., + /// the number of \em vertices. + /// + /// Required by the mln::Point_Set concept. + /* FIXME: Return type should be std::size_t (see + mln/core/concept/site_set.hh). */ + size_t nsites() const; + + /// Return The number of vertices in the graph. + std::size_t nvertices() const; + + /// Is this site set valid? + bool is_valid() const; + /// Invalidate this site set. + void invalidate(); + + /// Does this site set has \a p? + bool has(const psite& p) const; + + /// Does this site set has \a v? + template <typename G2> + bool has(const util::vertex<G2>& p) const; + + // FIXME: Dummy. + std::size_t memory_size() const; + + /// Accessors. + /// \{ + /// Return the graph associated to this site set (const version) + const graph_t& g() const; + /// Return the association function. + F function() const; + /// \} + + private: + mlc_const(graph_t)* g_; + F f_; + }; + + + /// \brief Comparison between two mln::p_vertices's. + /// + /// Two mln::p_vertices's are considered equal if they share the + /// same graph. + template <typename G, typename F> + bool + operator==(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs); + + + /* FIXME: Extend the `ord' mechanism instead of this ill-defined + pseudo-order. */ + + /// \brief Inclusion of a mln::p_vertices in another one. + /// + /// This inclusion relation is very strict for the moment, since our + /// infrastructure for graphs is simple: a mln::p_vertices is included + /// in another one if their are equal. + /// + /// \todo Refine this later, when we are able to express subgraph + /// relations. + template <typename G, typename F> + bool + operator<=(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs); + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename G, typename F> + inline + p_vertices<G, F>::p_vertices(const graph_t& g, const F& f) + : g_ (&g), f_(f) + { + } + + template <typename G, typename F> + inline + size_t + p_vertices<G, F>::nsites() const + { + return nvertices(); + } + + template <typename G, typename F> + inline + std::size_t + p_vertices<G, F>::nvertices() const + { + return this->g_->v_nmax(); + } + + template <typename G, typename F> + inline + bool + p_vertices<G, F>::is_valid() const + { + return g_ != 0; + } + + template <typename G, typename F> + inline + void + p_vertices<G, F>::invalidate() + { + g_ = 0; + } + + template <typename G, typename F> + inline + bool + p_vertices<G, F>::has(const psite& p) const + { + mln_precondition(is_valid()); + return has(p.v()); + } + + template <typename G, typename F> + template <typename G2> + inline + bool + p_vertices<G, F>::has(const util::vertex<G2>& p) const + { + mln_precondition(is_valid()); + return + // Check whether P is compatible with this psite set. + (p.g() == g_) && + // Check that the vertex id of P belongs to the range of valid + // vertex ids. + (p.is_valid()); + } + + template <typename G, typename F> + inline + std::size_t + p_vertices<G, F>::memory_size() const + { + // FIXME: Dummy; implement (see other site sets). + abort(); + return 0; + } + + template <typename G, typename F> + inline + const typename p_vertices<G, F>::graph_t& + p_vertices<G, F>::g() const + { + mln_precondition(is_valid()); + return *g_; + } + + template <typename G, typename F> + inline + F + p_vertices<G, F>::function() const + { + return f_; + } + + template <typename G, typename F> + bool + operator==(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs) + { + /* FIXME: We should not rely on pointer equality here, as graph + will soon become shells using (shared) tracked pointers to + actual data. So, delegate the equality test to the graphs + themselves. */ + return (*lhs.g_) == (*rhs.g_); + } + + template <typename G, typename F> + bool + operator<=(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs) + { + return lhs == rhs; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of mln + + +#endif // MLN_CORE_SITE_SET_P_VERTICES_HH diff --git a/milena/mln/util/internal/graph_vertex_psite.hh b/milena/mln/util/internal/graph_vertex_psite.hh new file mode 100644 index 0000000..b2fadf9 --- /dev/null +++ b/milena/mln/util/internal/graph_vertex_psite.hh @@ -0,0 +1,190 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH +# define MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH + +# include <mln/core/concept/pseudo_site.hh> + +namespace mln +{ + + template <typename G, typename F> class p_vertices; + +} // end of namespace mln + +/// \file mln/util/internal/graph_vertex_psite.hh +/// \brief Implementation of p_vertices psite. + +namespace mln +{ + + namespace internal + { + + template <typename G, typename F> + class vertex_psite : public mln::Pseudo_Site< vertex_psite<G, F> >, + public internal::proxy_impl< const typename F::result&, vertex_psite<G, F> > + { + typedef Pseudo_Site< vertex_psite<G, F> > super; + + public: + typedef p_vertices<G, F> site_set; + typedef mlc_const(site_set) target; + typedef typename F::result site; + + vertex_psite(); + vertex_psite(const target& t); + + void change_target(const target& new_target); + void change_vertex_id(unsigned id_v); + void update_id(unsigned v_id); + + const target* target_() const; // Hook to the target. + + bool is_valid() const; + void invalidate(); + + typedef const site& q_subject; + const site& subj_(); + const site& to_site() const; + + const util::vertex<G>& v() const; + + protected: + target* t_; + util::vertex<G> v_; + }; + + } // end of namespace internal + +} // end of namespace mln + + +# ifndef MLN_INCLUDE_ONLY + +namespace mln +{ + + namespace internal + { + + template <typename G, typename F> + inline + vertex_psite<G, F>::vertex_psite() + : t_(0) + { + } + + template <typename G, typename F> + inline + vertex_psite<G, F>::vertex_psite(const target& t) + : t_(0) + { + change_target(t); + } + + template <typename G, typename F> + inline + void + vertex_psite<G, F>::change_target(const target& new_target) + { + t_ = &new_target; + v_.change_graph(new_target.g()); + } + + template <typename G, typename F> + inline + void + vertex_psite<G, F>::change_vertex_id(unsigned id_v) + { + v_.update_id(id_v); + } + + template <typename G, typename F> + inline + void + vertex_psite<G, F>::update_id(unsigned v_id) + { + v_.update_id(v_id); + } + + template <typename G, typename F> + inline + const typename vertex_psite<G, F>::target* + vertex_psite<G, F>::target_() const + { + return t_; + } + + template <typename G, typename F> + inline + bool + vertex_psite<G, F>::is_valid() const + { + return t_ != 0 && t_->is_valid(); + } + + template <typename G, typename F> + inline + void + vertex_psite<G, F>::invalidate() + { + t_ = 0; + } + + template <typename G, typename F> + inline + const typename vertex_psite<G, F>::site& + vertex_psite<G, F>::subj_() + { + return to_site(); + } + + template <typename G, typename F> + inline + const typename vertex_psite<G, F>::site& + vertex_psite<G, F>::to_site() const + { + return t_->function()(v_); + } + + template <typename G, typename F> + inline + const util::vertex<G>& + vertex_psite<G, F>::v() const + { + return v_; + } + + } // end of namespace internal + +} // end of namespace mln +# endif // !MLN_INCLUDE_ONLY + +#endif // !MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH + diff --git a/milena/tests/core/site_set/Makefile.am b/milena/tests/core/site_set/Makefile.am index c1f1e14..d1b2cf6 100644 --- a/milena/tests/core/site_set/Makefile.am +++ b/milena/tests/core/site_set/Makefile.am @@ -10,7 +10,8 @@ check_PROGRAMS = \ p_queue \ p_queue_fast \ p_set \ - pset_if + pset_if \ + p_vertices p_array_SOURCES = p_array.cc ##p_bgraph_SOURCES = p_bgraph.cc @@ -20,5 +21,6 @@ p_queue_SOURCES = p_queue.cc p_queue_fast_SOURCES = p_queue_fast.cc p_set_SOURCES = p_set.cc pset_if_SOURCES = pset_if.cc +p_vertices_SOURCES = p_vertices.cc TESTS = $(check_PROGRAMS) diff --git a/milena/tests/core/site_set/p_vertices.cc b/milena/tests/core/site_set/p_vertices.cc new file mode 100644 index 0000000..6db4609 --- /dev/null +++ b/milena/tests/core/site_set/p_vertices.cc @@ -0,0 +1,91 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/core/site_set/p_vertices.cc + * + * \brief Tests on mln::p_vertices. + */ + +#include <mln/util/graph.hh> +#include <mln/core/alias/point2d.hh> +#include <mln/core/site_set/p_vertices.hh> + +template <typename G> +struct my_fun +{ + typedef mln::point2d result; + + const result& operator()(const mln::util::vertex<G>& v) const + { + static mln::point2d res(0, 0); + res.row() = v.id(); + return res; + } + +}; + +int main() +{ + using namespace mln; + + util::graph g; + g.add_vertex (); // 0 + g.add_vertex (); // 1 + g.add_vertex (); // 2 + g.add_vertex (); // 3 + g.add_vertex (); // 4 + g.add_vertex (); // 5 + g.add_edge (0, 1); + g.add_edge (0, 2); + g.add_edge (3, 4); + g.add_edge (4, 5); + g.add_edge (5, 4); + g.add_edge (1, 0); + g.add_edge (5, 3); + g.add_edge (2, 1); + +// typedef point2d (*fun_t)(const util::vertex<util::graph>&); + typedef p_vertices<util::graph, my_fun<util::graph> > p_vertices; + p_vertices pv(g, my_fun<util::graph>()); + + { + mln_fwd_piter_(p_vertices) p(pv); + unsigned i = 0; + for_all(p) + mln_assertion(p.p_hook_().v().id() == i++); + mln_assertion(i == g.v_nmax()); + } + { + mln_bkd_piter_(p_vertices) p(pv); + unsigned i = g.v_nmax() - 1; + for_all(p) + mln_assertion(p.p_hook_().v().id() == i--); + mln_assertion(i == UINT_MAX); + } + + return 0; +} -- 1.5.6.5