• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

edge.hh

00001 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_UTIL_EDGE_HH
00028 # define MLN_UTIL_EDGE_HH
00029 
00033 
00034 # include <iostream>
00035 # include <mln/util/graph_ids.hh>
00036 # include <mln/util/internal/edge_impl.hh>
00037 # include <mln/core/concept/proxy.hh>
00038 # include <mln/core/concept/site.hh>
00039 # include <mln/core/internal/pseudo_site_base.hh>
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   // Forward declaration.
00046   namespace util { template<typename G> class edge; }
00047 
00048 
00049 
00051   template <typename E>
00052   struct Edge
00053   {
00054   };
00055 
00056   template <>
00057   struct Edge<void>
00058   {
00059     typedef Site<void> super;
00060   };
00061 
00062 
00063 
00064   namespace util
00065   {
00066 
00068     template <typename G>
00069     class edge : public internal::edge_impl_<G>
00070     {
00071     public:
00073       typedef Edge<void> category;
00074 
00076       typedef typename edge_id_t::value_t id_value_t;
00077 
00079       typedef edge_id_t id_t;
00080 
00082       typedef G graph_t;
00083 
00086       edge();
00087       explicit edge(const G& g);
00088       edge(const G& g, id_value_t id);
00089       edge(const G& g, const edge_id_t& id);
00091 
00092 
00096       bool is_valid() const;
00098       void invalidate();
00099 
00101       edge_id_t id() const;
00102 
00104       void update_id(const edge_id_t& id);
00105 
00107       operator edge_id_t() const;
00108 
00110       const G& graph() const;
00111 
00113       void change_graph(const G& g);
00115 
00116 
00120       vertex_id_t
00121       v_other(const vertex_id_t& id_v) const;
00123 
00124 
00128       vertex_id_t v1() const;
00129 
00131       vertex_id_t v2() const;
00132 
00134       size_t nmax_nbh_edges() const;
00135 
00137       edge_id_t ith_nbh_edge(unsigned i) const;
00139 
00140 
00141     private:
00142       G g_;
00143       edge_id_t id_;
00144     };
00145 
00146 
00147     template <typename G>
00148     std::ostream&
00149     operator<<(std::ostream& ostr, const edge<G>& p);
00150 
00151     template <typename G>
00152     bool
00153     operator==(const edge<G>& lhs, const edge<G>& rhs);
00154 
00155     template <typename G>
00156     bool
00157     operator< (const edge<G>& lhs, const edge<G>& rhs);
00158 
00159   } // end of namespace mln::util
00160 
00161 
00162 
00163   namespace if_possible
00164   {
00165     template <typename G>
00166     void change_target(mln::util::edge<G>& e, const G& new_target)
00167     {
00168       std::cout << "YES: specialization change_target(edge, graph)" << std::endl;
00169       e.change_graph(new_target);
00170     }
00171 
00172   } // end of namespace mln::if_possible
00173 
00174 
00175   namespace internal
00176   {
00177 
00180 
00181     template <typename G, typename E>
00182     struct subject_impl< const util::edge<G>, E >
00183     {
00184       util::edge_id_t id() const;
00185       const G& graph() const;
00186 
00187       util::vertex_id_t
00188       v_other(const util::vertex_id_t& id_v) const;
00189 
00190       util::vertex_id_t v1() const;
00191 
00192       util::vertex_id_t v2() const;
00193 
00194       size_t nmax_nbh_edges() const;
00195       util::edge_id_t ith_nbh_edge(unsigned i) const;
00196 
00197 
00198     private:
00199       const E& exact_() const;
00200     };
00201 
00202     template <typename G, typename E>
00203     struct subject_impl< util::edge<G>, E > :
00204       subject_impl< const util::edge<G>, E >
00205     {
00206       void update_id(const util::edge_id_t& id);
00207       void change_graph(const mlc_const(G)& g);
00208       void invalidate();
00209 
00210     private:
00211       E& exact_();
00212     };
00213 
00215 
00216   } // end of namespace mln::internal
00217 
00218 
00219 
00220 # ifndef MLN_INCLUDE_ONLY
00221 
00222   namespace util
00223   {
00224 
00225     template <typename G>
00226     inline
00227     edge<G>::edge()
00228     {
00229       invalidate();
00230     }
00231 
00232     template <typename G>
00233     inline
00234     edge<G>::edge(const G& g)
00235       : g_(g)
00236     {
00237       invalidate();
00238     }
00239 
00240     template <typename G>
00241     inline
00242     edge<G>::edge(const G& g, id_value_t id)
00243       : g_(g), id_(id)
00244     {
00245       mln_precondition(g_.is_valid() && g.has_e(id));
00246     }
00247 
00248     template <typename G>
00249     inline
00250     edge<G>::edge(const G& g, const edge_id_t& id)
00251       : g_(g), id_(id)
00252     {
00253       mln_precondition(g_.is_valid() && g.has_e(id));
00254     }
00255 
00256     template <typename G>
00257     inline
00258     edge_id_t
00259     edge<G>::id() const
00260     {
00261       return id_;
00262     }
00263 
00264     template <typename G>
00265     inline
00266     void
00267     edge<G>::update_id(const edge_id_t& id)
00268     {
00269       id_ = id;
00270     }
00271 
00272     template <typename G>
00273     inline
00274     edge<G>::operator edge_id_t() const
00275     {
00276       return id_;
00277     }
00278 
00279     template <typename G>
00280     inline
00281     const G&
00282     edge<G>::graph() const
00283     {
00284       return g_;
00285     }
00286 
00287     template <typename G>
00288     inline
00289     void
00290     edge<G>::change_graph(const G& g)
00291     {
00292       g_ = g;
00293     }
00294 
00295     template <typename G>
00296     inline
00297     bool
00298     edge<G>::is_valid() const
00299     {
00300       return g_.is_valid() && id_.is_valid() && g_.has_e(id_);
00301     }
00302 
00303     template <typename G>
00304     inline
00305     void
00306     edge<G>::invalidate()
00307     {
00308       id_.invalidate();
00309     }
00310 
00311 
00312     template <typename G>
00313     inline
00314     vertex_id_t
00315     edge<G>::v_other(const vertex_id_t& id_v) const
00316     {
00317       mln_precondition(v1() == id_v || v2() == id_v);
00318       return g_.v_other(id_, id_v);
00319     }
00320 
00321     template <typename G>
00322     inline
00323     vertex_id_t
00324     edge<G>::v1() const
00325     {
00326       mln_precondition(g_.has_e(id_));
00327       return g_.v1(id_);
00328     }
00329 
00330     template <typename G>
00331     inline
00332     vertex_id_t
00333     edge<G>::v2() const
00334     {
00335       mln_precondition(g_.has_e(id_));
00336       return g_.v2(id_);
00337     }
00338 
00339     template <typename G>
00340     inline
00341     size_t
00342     edge<G>::nmax_nbh_edges() const
00343     {
00344       mln_precondition(g_.has_e(id_));
00345       return g_.e_nmax_nbh_edges(id_);
00346     }
00347 
00348     template <typename G>
00349     inline
00350     edge_id_t
00351     edge<G>::ith_nbh_edge(unsigned i) const
00352     {
00353       mln_precondition(g_.has_e(id_));
00354       return g_.e_ith_nbh_edge(id_, i);
00355     }
00356 
00357     template <typename G>
00358     inline
00359     std::ostream&
00360     operator<<(std::ostream& ostr, const edge<G>& p)
00361     {
00362       return ostr << "(" << p.v1() << "," << p.v2() << ")";
00363     }
00364 
00365     template <typename G>
00366     inline
00367     bool
00368     operator==(const edge<G>& lhs, const edge<G>& rhs)
00369     {
00370       return lhs.id() == rhs.id()
00371               && (lhs.graph().is_subgraph_of(rhs.graph())
00372                   || rhs.graph().is_subgraph_of(lhs.graph()));
00373     }
00374 
00375     template <typename G>
00376     inline
00377     bool
00378     operator<(const edge<G>& lhs, const edge<G>& rhs)
00379     {
00380       return lhs.id() < rhs.id();
00381     }
00382 
00383   } // end of namespace mln::util
00384 
00385 
00386 
00387   namespace internal
00388   {
00389 
00390     /*-----------------------------------------.
00391     | subject_impl< const util::edge<G>, E >.  |
00392     `-----------------------------------------*/
00393 
00394     template <typename G, typename E>
00395     inline
00396     const E&
00397     subject_impl< const util::edge<G>, E >::exact_() const
00398     {
00399       return internal::force_exact<const E>(*this);
00400     }
00401 
00402     template <typename G, typename E>
00403     inline
00404     util::edge_id_t
00405     subject_impl< const util::edge<G>, E >::id() const
00406     {
00407       return exact_().get_subject().id();
00408     }
00409 
00410     template <typename G, typename E>
00411     inline
00412     const G&
00413     subject_impl< const util::edge<G>, E >::graph() const
00414     {
00415       return exact_().get_subject().graph();
00416     }
00417 
00418     template <typename G, typename E>
00419     inline
00420     util::vertex_id_t
00421     subject_impl< const util::edge<G>, E >::v_other(const util::vertex_id_t& id_v) const
00422     {
00423       return exact_().get_subject().v_other(id_v);
00424     }
00425 
00426     template <typename G, typename E>
00427     inline
00428     util::vertex_id_t
00429     subject_impl< const util::edge<G>, E >::v1() const
00430     {
00431       return exact_().get_subject().v1();
00432     }
00433 
00434     template <typename G, typename E>
00435     inline
00436     util::vertex_id_t
00437     subject_impl< const util::edge<G>, E >::v2() const
00438     {
00439       return exact_().get_subject().v2();
00440     }
00441 
00442     template <typename G, typename E>
00443     inline
00444     size_t
00445     subject_impl< const util::edge<G>, E >::nmax_nbh_edges() const
00446     {
00447       return exact_().get_subject().nmax_nbh_edges();
00448     }
00449 
00450     template <typename G, typename E>
00451     inline
00452     util::edge_id_t
00453     subject_impl< const util::edge<G>, E >::ith_nbh_edge(unsigned i) const
00454     {
00455       return exact_().get_subject().ith_nbh_edge(i);
00456     }
00457 
00458 
00459     /*-----------------------------------.
00460     | subject_impl< util::edge<G>, E >.  |
00461     `-----------------------------------*/
00462 
00463     template <typename G, typename E>
00464     inline
00465     void
00466     subject_impl< util::edge<G>, E >::update_id(const util::edge_id_t& id)
00467     {
00468       return exact_().get_subject().update_id(id);
00469     }
00470 
00471     template <typename G, typename E>
00472     inline
00473     void
00474     subject_impl< util::edge<G>, E >::change_graph(const mlc_const(G)& g)
00475     {
00476       return exact_().get_subject().change_graph(g);
00477     }
00478 
00479     template <typename G, typename E>
00480     inline
00481     void
00482     subject_impl< util::edge<G>, E >::invalidate()
00483     {
00484       return exact_().get_subject().invalidate();
00485     }
00486 
00487   } // end of namespace mln::internal
00488 
00489 # endif // ! MLN_INCLUDE_ONLY
00490 
00491 } // end of namespace mln
00492 
00493 
00494 #endif // ! MLN_UTIL_EDGE_HH

Generated on Tue Oct 4 2011 15:23:42 for Milena (Olena) by  doxygen 1.7.1