Milena (Olena)
User documentation 2.0a Id
|
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