00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_UTIL_EDGE_HH
00027 # define MLN_UTIL_EDGE_HH
00028
00032
00033 # include <iostream>
00034 # include <mln/util/graph_ids.hh>
00035 # include <mln/util/internal/edge_impl.hh>
00036 # include <mln/core/concept/proxy.hh>
00037 # include <mln/core/concept/site.hh>
00038 # include <mln/core/internal/pseudo_site_base.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044
00045 namespace util { template<typename G> class edge; }
00046
00047
00048
00050 template <typename E>
00051 struct Edge
00052 {
00053 };
00054
00055 template <>
00056 struct Edge<void>
00057 {
00058 typedef Site<void> super;
00059 };
00060
00061
00062
00063 namespace util
00064 {
00065
00067 template <typename G>
00068 class edge : public internal::edge_impl_<G>
00069 {
00070 public:
00072 typedef Edge<void> category;
00073
00075 typedef typename edge_id_t::value_t id_value_t;
00076
00078 typedef edge_id_t id_t;
00079
00081 typedef G graph_t;
00082
00085 edge();
00086 explicit edge(const G& g);
00087 edge(const G& g, id_value_t id);
00088 edge(const G& g, const edge_id_t& id);
00090
00091
00095 bool is_valid() const;
00097 void invalidate();
00098
00100 edge_id_t id() const;
00101
00103 void update_id(const edge_id_t& id);
00104
00106 operator edge_id_t() const;
00107
00109 const G& graph() const;
00110
00112 void change_graph(const G& g);
00114
00115
00119 vertex_id_t
00120 v_other(const vertex_id_t& id_v) const;
00122
00123
00127 vertex_id_t v1() const;
00128
00130 vertex_id_t v2() const;
00131
00133 size_t nmax_nbh_edges() const;
00134
00136 edge_id_t ith_nbh_edge(unsigned i) const;
00138
00139
00140 private:
00141 G g_;
00142 edge_id_t id_;
00143 };
00144
00145
00146 template <typename G>
00147 std::ostream&
00148 operator<<(std::ostream& ostr, const edge<G>& p);
00149
00150 template <typename G>
00151 bool
00152 operator==(const edge<G>& lhs, const edge<G>& rhs);
00153
00154 template <typename G>
00155 bool
00156 operator< (const edge<G>& lhs, const edge<G>& rhs);
00157
00158 }
00159
00160
00161
00162 namespace if_possible
00163 {
00164 template <typename G>
00165 void change_target(mln::util::edge<G>& e, const G& new_target)
00166 {
00167 std::cout << "YES: specialization change_target(edge, graph)" << std::endl;
00168 e.change_graph(new_target);
00169 }
00170
00171 }
00172
00173
00174 namespace internal
00175 {
00176
00179
00180 template <typename G, typename E>
00181 struct subject_impl< const util::edge<G>, E >
00182 {
00183 util::edge_id_t id() const;
00184 const G& graph() const;
00185
00186 util::vertex_id_t
00187 v_other(const util::vertex_id_t& id_v) const;
00188
00189 util::vertex_id_t v1() const;
00190
00191 util::vertex_id_t v2() const;
00192
00193 size_t nmax_nbh_edges() const;
00194 util::edge_id_t ith_nbh_edge(unsigned i) const;
00195
00196
00197 private:
00198 const E& exact_() const;
00199 };
00200
00201 template <typename G, typename E>
00202 struct subject_impl< util::edge<G>, E > :
00203 subject_impl< const util::edge<G>, E >
00204 {
00205 void update_id(const util::edge_id_t& id);
00206 void change_graph(const mlc_const(G)& g);
00207 void invalidate();
00208
00209 private:
00210 E& exact_();
00211 };
00212
00214
00215 }
00216
00217
00218
00219 # ifndef MLN_INCLUDE_ONLY
00220
00221
00222
00223
00224
00225 namespace util
00226 {
00227
00228 template <typename G>
00229 inline
00230 edge<G>::edge()
00231 {
00232 invalidate();
00233 }
00234
00235 template <typename G>
00236 inline
00237 edge<G>::edge(const G& g)
00238 : g_(g)
00239 {
00240 invalidate();
00241 }
00242
00243 template <typename G>
00244 inline
00245 edge<G>::edge(const G& g, id_value_t id)
00246 : g_(g), id_(id)
00247 {
00248 mln_precondition(g_.is_valid() && g.has_e(id));
00249 }
00250
00251 template <typename G>
00252 inline
00253 edge<G>::edge(const G& g, const edge_id_t& id)
00254 : g_(g), id_(id)
00255 {
00256 mln_precondition(g_.is_valid() && g.has_e(id));
00257 }
00258
00259 template <typename G>
00260 inline
00261 edge_id_t
00262 edge<G>::id() const
00263 {
00264 return id_;
00265 }
00266
00267 template <typename G>
00268 inline
00269 void
00270 edge<G>::update_id(const edge_id_t& id)
00271 {
00272 id_ = id;
00273 }
00274
00275 template <typename G>
00276 inline
00277 edge<G>::operator edge_id_t() const
00278 {
00279 return id_;
00280 }
00281
00282 template <typename G>
00283 inline
00284 const G&
00285 edge<G>::graph() const
00286 {
00287 return g_;
00288 }
00289
00290 template <typename G>
00291 inline
00292 void
00293 edge<G>::change_graph(const G& g)
00294 {
00295 g_ = g;
00296 }
00297
00298 template <typename G>
00299 inline
00300 bool
00301 edge<G>::is_valid() const
00302 {
00303 return g_.is_valid() && id_.is_valid() && g_.has_e(id_);
00304 }
00305
00306 template <typename G>
00307 inline
00308 void
00309 edge<G>::invalidate()
00310 {
00311
00312 id_.invalidate();
00313 }
00314
00315
00316 template <typename G>
00317 inline
00318 vertex_id_t
00319 edge<G>::v_other(const vertex_id_t& id_v) const
00320 {
00321 mln_precondition(v1() == id_v || v2() == id_v);
00322 return g_.v_other(id_, id_v);
00323 }
00324
00325 template <typename G>
00326 inline
00327 vertex_id_t
00328 edge<G>::v1() const
00329 {
00330 mln_precondition(g_.has_e(id_));
00331 return g_.v1(id_);
00332 }
00333
00334 template <typename G>
00335 inline
00336 vertex_id_t
00337 edge<G>::v2() const
00338 {
00339 mln_precondition(g_.has_e(id_));
00340 return g_.v2(id_);
00341 }
00342
00343 template <typename G>
00344 inline
00345 size_t
00346 edge<G>::nmax_nbh_edges() const
00347 {
00348 mln_precondition(g_.has_e(id_));
00349 return g_.e_nmax_nbh_edges(id_);
00350 }
00351
00352 template <typename G>
00353 inline
00354 edge_id_t
00355 edge<G>::ith_nbh_edge(unsigned i) const
00356 {
00357 mln_precondition(g_.has_e(id_));
00358 return g_.e_ith_nbh_edge(id_, i);
00359 }
00360
00361 template <typename G>
00362 inline
00363 std::ostream&
00364 operator<<(std::ostream& ostr, const edge<G>& p)
00365 {
00366 return ostr << "(" << p.v1() << "," << p.v2() << ")";
00367 }
00368
00369 template <typename G>
00370 inline
00371 bool
00372 operator==(const edge<G>& lhs, const edge<G>& rhs)
00373 {
00374 return lhs.id() == rhs.id()
00375 && (lhs.graph().is_subgraph_of(rhs.graph())
00376 || rhs.graph().is_subgraph_of(lhs.graph()));
00377 }
00378
00379 template <typename G>
00380 inline
00381 bool
00382 operator<(const edge<G>& lhs, const edge<G>& rhs)
00383 {
00384 return lhs.id() < rhs.id();
00385 }
00386
00387 }
00388
00389
00390
00391 namespace internal
00392 {
00393
00394
00395
00396
00397
00398 template <typename G, typename E>
00399 inline
00400 const E&
00401 subject_impl< const util::edge<G>, E >::exact_() const
00402 {
00403 return internal::force_exact<const E>(*this);
00404 }
00405
00406 template <typename G, typename E>
00407 inline
00408 util::edge_id_t
00409 subject_impl< const util::edge<G>, E >::id() const
00410 {
00411 return exact_().get_subject().id();
00412 }
00413
00414 template <typename G, typename E>
00415 inline
00416 const G&
00417 subject_impl< const util::edge<G>, E >::graph() const
00418 {
00419 return exact_().get_subject().graph();
00420 }
00421
00422 template <typename G, typename E>
00423 inline
00424 util::vertex_id_t
00425 subject_impl< const util::edge<G>, E >::v_other(const util::vertex_id_t& id_v) const
00426 {
00427 return exact_().get_subject().v_other(id_v);
00428 }
00429
00430 template <typename G, typename E>
00431 inline
00432 util::vertex_id_t
00433 subject_impl< const util::edge<G>, E >::v1() const
00434 {
00435 return exact_().get_subject().v1();
00436 }
00437
00438 template <typename G, typename E>
00439 inline
00440 util::vertex_id_t
00441 subject_impl< const util::edge<G>, E >::v2() const
00442 {
00443 return exact_().get_subject().v2();
00444 }
00445
00446 template <typename G, typename E>
00447 inline
00448 size_t
00449 subject_impl< const util::edge<G>, E >::nmax_nbh_edges() const
00450 {
00451 return exact_().get_subject().nmax_nbh_edges();
00452 }
00453
00454 template <typename G, typename E>
00455 inline
00456 util::edge_id_t
00457 subject_impl< const util::edge<G>, E >::ith_nbh_edge(unsigned i) const
00458 {
00459 return exact_().get_subject().ith_nbh_edge(i);
00460 }
00461
00462
00463
00464
00465
00466
00467 template <typename G, typename E>
00468 inline
00469 void
00470 subject_impl< util::edge<G>, E >::update_id(const util::edge_id_t& id)
00471 {
00472 return exact_().get_subject().update_id(id);
00473 }
00474
00475 template <typename G, typename E>
00476 inline
00477 void
00478 subject_impl< util::edge<G>, E >::change_graph(const mlc_const(G)& g)
00479 {
00480 return exact_().get_subject().change_graph(g);
00481 }
00482
00483 template <typename G, typename E>
00484 inline
00485 void
00486 subject_impl< util::edge<G>, E >::invalidate()
00487 {
00488 return exact_().get_subject().invalidate();
00489 }
00490
00491 }
00492
00493 # endif // ! MLN_INCLUDE_ONLY
00494
00495 }
00496
00497
00498 #endif // ! MLN_UTIL_EDGE_HH