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
00039 namespace mln
00040 {
00041
00042
00043 namespace util { template<typename G> class edge; }
00044
00045
00046
00048 template <typename E>
00049 struct Edge
00050 {
00051 };
00052
00053 template <>
00054 struct Edge<void>
00055 {
00056 typedef Site<void> super;
00057 };
00058
00059
00060
00061 namespace util
00062 {
00063
00065 template <typename G>
00066 class edge : public internal::edge_impl_<G>
00067 {
00068 public:
00070 typedef Edge<void> category;
00071
00073 typedef typename edge_id_t::value_t id_value_t;
00074
00076 typedef edge_id_t id_t;
00077
00079 typedef G graph_t;
00080
00083 edge();
00084 explicit edge(const G& g);
00085 edge(const G& g, id_value_t id);
00086 edge(const G& g, const edge_id_t& id);
00088
00089
00093 bool is_valid() const;
00095 void invalidate();
00096
00098 edge_id_t id() const;
00099
00101 void update_id(const edge_id_t& id);
00102
00104 operator edge_id_t() const;
00105
00107 const G& graph() const;
00108
00110 void change_graph(const G& g);
00112
00113
00117 vertex_id_t
00118 v_other(const vertex_id_t& id_v) const;
00120
00121
00125 vertex_id_t v1() const;
00126
00128 vertex_id_t v2() const;
00129
00131 size_t nmax_nbh_edges() const;
00132
00134 edge_id_t ith_nbh_edge(unsigned i) const;
00136
00137 private:
00138 G g_;
00139 edge_id_t id_;
00140 };
00141
00142
00143 template <typename G>
00144 std::ostream&
00145 operator<<(std::ostream& ostr, const edge<G>& p);
00146
00147 template <typename G>
00148 bool
00149 operator==(const edge<G>& lhs, const edge<G>& rhs);
00150
00151 template <typename G>
00152 bool
00153 operator< (const edge<G>& lhs, const edge<G>& rhs);
00154
00155 }
00156
00157
00158
00159 namespace internal
00160 {
00161
00164
00165 template <typename G, typename E>
00166 struct subject_impl< const util::edge<G>, E >
00167 {
00168 util::edge_id_t id() const;
00169 const G& graph() const;
00170
00171 util::vertex_id_t
00172 v_other(const util::vertex_id_t& id_v) const;
00173
00174 util::vertex_id_t v1() const;
00175
00176 util::vertex_id_t v2() const;
00177
00178 size_t nmax_nbh_edges() const;
00179 util::edge_id_t ith_nbh_edge(unsigned i) const;
00180
00181
00182 private:
00183 const E& exact_() const;
00184 };
00185
00186 template <typename G, typename E>
00187 struct subject_impl< util::edge<G>, E > :
00188 subject_impl< const util::edge<G>, E >
00189 {
00190 void update_id(const util::edge_id_t& id);
00191 void change_graph(const mlc_const(G)& g);
00192 void invalidate();
00193
00194 private:
00195 E& exact_();
00196 };
00197
00199
00200 }
00201
00202
00203
00204 # ifndef MLN_INCLUDE_ONLY
00205
00206
00207
00208
00209
00210 namespace util
00211 {
00212
00213 template <typename G>
00214 inline
00215 edge<G>::edge()
00216 {
00217 invalidate();
00218 }
00219
00220 template <typename G>
00221 inline
00222 edge<G>::edge(const G& g)
00223 : g_(g)
00224 {
00225 invalidate();
00226 }
00227
00228 template <typename G>
00229 inline
00230 edge<G>::edge(const G& g, id_value_t id)
00231 : g_(g), id_(id)
00232 {
00233 mln_precondition(g_.is_valid() && g.has_e(id));
00234 }
00235
00236 template <typename G>
00237 inline
00238 edge<G>::edge(const G& g, const edge_id_t& id)
00239 : g_(g), id_(id)
00240 {
00241 mln_precondition(g_.is_valid() && g.has_e(id));
00242 }
00243
00244 template <typename G>
00245 inline
00246 edge_id_t
00247 edge<G>::id() const
00248 {
00249 return id_;
00250 }
00251
00252 template <typename G>
00253 inline
00254 void
00255 edge<G>::update_id(const edge_id_t& id)
00256 {
00257 id_ = id;
00258 }
00259
00260 template <typename G>
00261 inline
00262 edge<G>::operator edge_id_t() const
00263 {
00264 return id_;
00265 }
00266
00267 template <typename G>
00268 inline
00269 const G&
00270 edge<G>::graph() const
00271 {
00272 return g_;
00273 }
00274
00275 template <typename G>
00276 inline
00277 void
00278 edge<G>::change_graph(const G& g)
00279 {
00280 g_ = g;
00281 }
00282
00283 template <typename G>
00284 inline
00285 bool
00286 edge<G>::is_valid() const
00287 {
00288 return g_.is_valid() && id_.is_valid() && g_.has_e(id_);
00289 }
00290
00291 template <typename G>
00292 inline
00293 void
00294 edge<G>::invalidate()
00295 {
00296
00297 id_.invalidate();
00298 }
00299
00300
00301 template <typename G>
00302 inline
00303 vertex_id_t
00304 edge<G>::v_other(const vertex_id_t& id_v) const
00305 {
00306 mln_precondition(v1() == id_v || v2() == id_v);
00307 return g_.v_other(id_, id_v);
00308 }
00309
00310 template <typename G>
00311 inline
00312 vertex_id_t
00313 edge<G>::v1() const
00314 {
00315 mln_precondition(g_.has_e(id_));
00316 return g_.v1(id_);
00317 }
00318
00319 template <typename G>
00320 inline
00321 vertex_id_t
00322 edge<G>::v2() const
00323 {
00324 mln_precondition(g_.has_e(id_));
00325 return g_.v2(id_);
00326 }
00327
00328 template <typename G>
00329 inline
00330 size_t
00331 edge<G>::nmax_nbh_edges() const
00332 {
00333 mln_precondition(g_.has_e(id_));
00334 return g_.e_nmax_nbh_edges(id_);
00335 }
00336
00337 template <typename G>
00338 inline
00339 edge_id_t
00340 edge<G>::ith_nbh_edge(unsigned i) const
00341 {
00342 mln_precondition(g_.has_e(id_));
00343 return g_.e_ith_nbh_edge(id_, i);
00344 }
00345
00346 template <typename G>
00347 inline
00348 std::ostream&
00349 operator<<(std::ostream& ostr, const edge<G>& p)
00350 {
00351 return ostr << "(" << p.v1() << "," << p.v2() << ")";
00352 }
00353
00354 template <typename G>
00355 inline
00356 bool
00357 operator==(const edge<G>& lhs, const edge<G>& rhs)
00358 {
00359 return lhs.id() == rhs.id()
00360 && (lhs.graph().is_subgraph_of(rhs.graph())
00361 || rhs.graph().is_subgraph_of(lhs.graph()));
00362 }
00363
00364 template <typename G>
00365 inline
00366 bool
00367 operator<(const edge<G>& lhs, const edge<G>& rhs)
00368 {
00369 return lhs.id() < rhs.id();
00370 }
00371
00372 }
00373
00374
00375
00376 namespace internal
00377 {
00378
00379
00380
00381
00382
00383 template <typename G, typename E>
00384 inline
00385 const E&
00386 subject_impl< const util::edge<G>, E >::exact_() const
00387 {
00388 return internal::force_exact<const E>(*this);
00389 }
00390
00391 template <typename G, typename E>
00392 inline
00393 util::edge_id_t
00394 subject_impl< const util::edge<G>, E >::id() const
00395 {
00396 return exact_().get_subject().id();
00397 }
00398
00399 template <typename G, typename E>
00400 inline
00401 const G&
00402 subject_impl< const util::edge<G>, E >::graph() const
00403 {
00404 return exact_().get_subject().graph();
00405 }
00406
00407 template <typename G, typename E>
00408 inline
00409 util::vertex_id_t
00410 subject_impl< const util::edge<G>, E >::v_other(const util::vertex_id_t& id_v) const
00411 {
00412 return exact_().get_subject().v_other(id_v);
00413 }
00414
00415 template <typename G, typename E>
00416 inline
00417 util::vertex_id_t
00418 subject_impl< const util::edge<G>, E >::v1() const
00419 {
00420 return exact_().get_subject().v1();
00421 }
00422
00423 template <typename G, typename E>
00424 inline
00425 util::vertex_id_t
00426 subject_impl< const util::edge<G>, E >::v2() const
00427 {
00428 return exact_().get_subject().v2();
00429 }
00430
00431 template <typename G, typename E>
00432 inline
00433 size_t
00434 subject_impl< const util::edge<G>, E >::nmax_nbh_edges() const
00435 {
00436 return exact_().get_subject().nmax_nbh_edges();
00437 }
00438
00439 template <typename G, typename E>
00440 inline
00441 util::edge_id_t
00442 subject_impl< const util::edge<G>, E >::ith_nbh_edge(unsigned i) const
00443 {
00444 return exact_().get_subject().ith_nbh_edge(i);
00445 }
00446
00447
00448
00449
00450
00451
00452 template <typename G, typename E>
00453 inline
00454 void
00455 subject_impl< util::edge<G>, E >::update_id(const util::edge_id_t& id)
00456 {
00457 return exact_().get_subject().update_id(id);
00458 }
00459
00460 template <typename G, typename E>
00461 inline
00462 void
00463 subject_impl< util::edge<G>, E >::change_graph(const mlc_const(G)& g)
00464 {
00465 return exact_().get_subject().change_graph(g);
00466 }
00467
00468 template <typename G, typename E>
00469 inline
00470 void
00471 subject_impl< util::edge<G>, E >::invalidate()
00472 {
00473 return exact_().get_subject().invalidate();
00474 }
00475
00476 }
00477
00478 # endif // ! MLN_INCLUDE_ONLY
00479
00480 }
00481
00482
00483 #endif // ! MLN_UTIL_EDGE_HH