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
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
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 }
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 }
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 }
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 }
00384
00385
00386
00387 namespace internal
00388 {
00389
00390
00391
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
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 }
00488
00489 # endif // ! MLN_INCLUDE_ONLY
00490
00491 }
00492
00493
00494 #endif // ! MLN_UTIL_EDGE_HH