Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
edge.hh
1 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_UTIL_EDGE_HH
28 # define MLN_UTIL_EDGE_HH
29 
33 
34 # include <iostream>
35 # include <mln/util/graph_ids.hh>
36 # include <mln/util/internal/edge_impl.hh>
37 # include <mln/core/concept/proxy.hh>
38 # include <mln/core/concept/site.hh>
39 # include <mln/core/internal/pseudo_site_base.hh>
40 
41 
42 namespace mln
43 {
44 
45  // Forward declaration.
46  namespace util { template<typename G> class edge; }
47 
48 
49 
51  template <typename E>
52  struct Edge
53  {
54  };
55 
56  template <>
57  struct Edge<void>
58  {
59  typedef Site<void> super;
60  };
61 
62 
63 
64  namespace util
65  {
66 
68  template <typename G>
69  class edge : public internal::edge_impl_<G>
70  {
71  public:
74 
76  typedef typename edge_id_t::value_t id_value_t;
77 
79  typedef edge_id_t id_t;
80 
82  typedef G graph_t;
83 
86  edge();
87  explicit edge(const G& g);
88  edge(const G& g, id_value_t id);
89  edge(const G& g, const edge_id_t& id);
91 
92 
96  bool is_valid() const;
98  void invalidate();
99 
101  edge_id_t id() const;
102 
104  void update_id(const edge_id_t& id);
105 
107  operator edge_id_t() const;
108 
110  const G& graph() const;
111 
113  void change_graph(const G& g);
115 
116 
121  v_other(const vertex_id_t& id_v) const;
123 
124 
128  vertex_id_t v1() const;
129 
131  vertex_id_t v2() const;
132 
134  size_t nmax_nbh_edges() const;
135 
137  edge_id_t ith_nbh_edge(unsigned i) const;
139 
140 
141  private:
142  G g_;
143  edge_id_t id_;
144  };
145 
146 
147  template <typename G>
148  std::ostream&
149  operator<<(std::ostream& ostr, const edge<G>& p);
150 
151  template <typename G>
152  bool
153  operator==(const edge<G>& lhs, const edge<G>& rhs);
154 
155  template <typename G>
156  bool
157  operator< (const edge<G>& lhs, const edge<G>& rhs);
158 
159  } // end of namespace mln::util
160 
161 
162 
163  namespace if_possible
164  {
165  template <typename G>
166  void change_target(mln::util::edge<G>& e, const G& new_target)
167  {
168  std::cout << "YES: specialization change_target(edge, graph)" << std::endl;
169  e.change_graph(new_target);
170  }
171 
172  } // end of namespace mln::if_possible
173 
174 
175  namespace internal
176  {
177 
180 
181  template <typename G, typename E>
182  struct subject_impl< const util::edge<G>, E >
183  {
184  util::edge_id_t id() const;
185  const G& graph() const;
186 
188  v_other(const util::vertex_id_t& id_v) const;
189 
190  util::vertex_id_t v1() const;
191 
192  util::vertex_id_t v2() const;
193 
194  size_t nmax_nbh_edges() const;
195  util::edge_id_t ith_nbh_edge(unsigned i) const;
196 
197 
198  private:
199  const E& exact_() const;
200  };
201 
202  template <typename G, typename E>
203  struct subject_impl< util::edge<G>, E > :
204  subject_impl< const util::edge<G>, E >
205  {
206  void update_id(const util::edge_id_t& id);
207  void change_graph(const mlc_const(G)& g);
208  void invalidate();
209 
210  private:
211  E& exact_();
212  };
213 
215 
216  } // end of namespace mln::internal
217 
218 
219 
220 # ifndef MLN_INCLUDE_ONLY
221 
222  namespace util
223  {
224 
225  template <typename G>
226  inline
228  {
229  invalidate();
230  }
231 
232  template <typename G>
233  inline
234  edge<G>::edge(const G& g)
235  : g_(g)
236  {
237  invalidate();
238  }
239 
240  template <typename G>
241  inline
242  edge<G>::edge(const G& g, id_value_t id)
243  : g_(g), id_(id)
244  {
245  mln_precondition(g_.is_valid() && g.has_e(id));
246  }
247 
248  template <typename G>
249  inline
250  edge<G>::edge(const G& g, const edge_id_t& id)
251  : g_(g), id_(id)
252  {
253  mln_precondition(g_.is_valid() && g.has_e(id));
254  }
255 
256  template <typename G>
257  inline
258  edge_id_t
259  edge<G>::id() const
260  {
261  return id_;
262  }
263 
264  template <typename G>
265  inline
266  void
268  {
269  id_ = id;
270  }
271 
272  template <typename G>
273  inline
275  {
276  return id_;
277  }
278 
279  template <typename G>
280  inline
281  const G&
283  {
284  return g_;
285  }
286 
287  template <typename G>
288  inline
289  void
291  {
292  g_ = g;
293  }
294 
295  template <typename G>
296  inline
297  bool
299  {
300  return g_.is_valid() && id_.is_valid() && g_.has_e(id_);
301  }
302 
303  template <typename G>
304  inline
305  void
307  {
308  id_.invalidate();
309  }
310 
311 
312  template <typename G>
313  inline
315  edge<G>::v_other(const vertex_id_t& id_v) const
316  {
317  mln_precondition(v1() == id_v || v2() == id_v);
318  return g_.v_other(id_, id_v);
319  }
320 
321  template <typename G>
322  inline
324  edge<G>::v1() const
325  {
326  mln_precondition(g_.has_e(id_));
327  return g_.v1(id_);
328  }
329 
330  template <typename G>
331  inline
333  edge<G>::v2() const
334  {
335  mln_precondition(g_.has_e(id_));
336  return g_.v2(id_);
337  }
338 
339  template <typename G>
340  inline
341  size_t
343  {
344  mln_precondition(g_.has_e(id_));
345  return g_.e_nmax_nbh_edges(id_);
346  }
347 
348  template <typename G>
349  inline
350  edge_id_t
351  edge<G>::ith_nbh_edge(unsigned i) const
352  {
353  mln_precondition(g_.has_e(id_));
354  return g_.e_ith_nbh_edge(id_, i);
355  }
356 
357  template <typename G>
358  inline
359  std::ostream&
360  operator<<(std::ostream& ostr, const edge<G>& p)
361  {
362  return ostr << "(" << p.v1() << "," << p.v2() << ")";
363  }
364 
365  template <typename G>
366  inline
367  bool
368  operator==(const edge<G>& lhs, const edge<G>& rhs)
369  {
370  return lhs.id() == rhs.id()
371  && (lhs.graph().is_subgraph_of(rhs.graph())
372  || rhs.graph().is_subgraph_of(lhs.graph()));
373  }
374 
375  template <typename G>
376  inline
377  bool
378  operator<(const edge<G>& lhs, const edge<G>& rhs)
379  {
380  return lhs.id() < rhs.id();
381  }
382 
383  } // end of namespace mln::util
384 
385 
386 
387  namespace internal
388  {
389 
390  /*-----------------------------------------.
391  | subject_impl< const util::edge<G>, E >. |
392  `-----------------------------------------*/
393 
394  template <typename G, typename E>
395  inline
396  const E&
397  subject_impl< const util::edge<G>, E >::exact_() const
398  {
399  return internal::force_exact<const E>(*this);
400  }
401 
402  template <typename G, typename E>
403  inline
404  util::edge_id_t
405  subject_impl< const util::edge<G>, E >::id() const
406  {
407  return exact_().get_subject().id();
408  }
409 
410  template <typename G, typename E>
411  inline
412  const G&
413  subject_impl< const util::edge<G>, E >::graph() const
414  {
415  return exact_().get_subject().graph();
416  }
417 
418  template <typename G, typename E>
419  inline
421  subject_impl< const util::edge<G>, E >::v_other(const util::vertex_id_t& id_v) const
422  {
423  return exact_().get_subject().v_other(id_v);
424  }
425 
426  template <typename G, typename E>
427  inline
429  subject_impl< const util::edge<G>, E >::v1() const
430  {
431  return exact_().get_subject().v1();
432  }
433 
434  template <typename G, typename E>
435  inline
437  subject_impl< const util::edge<G>, E >::v2() const
438  {
439  return exact_().get_subject().v2();
440  }
441 
442  template <typename G, typename E>
443  inline
444  size_t
445  subject_impl< const util::edge<G>, E >::nmax_nbh_edges() const
446  {
447  return exact_().get_subject().nmax_nbh_edges();
448  }
449 
450  template <typename G, typename E>
451  inline
452  util::edge_id_t
453  subject_impl< const util::edge<G>, E >::ith_nbh_edge(unsigned i) const
454  {
455  return exact_().get_subject().ith_nbh_edge(i);
456  }
457 
458 
459  /*-----------------------------------.
460  | subject_impl< util::edge<G>, E >. |
461  `-----------------------------------*/
462 
463  template <typename G, typename E>
464  inline
465  void
466  subject_impl< util::edge<G>, E >::update_id(const util::edge_id_t& id)
467  {
468  return exact_().get_subject().update_id(id);
469  }
470 
471  template <typename G, typename E>
472  inline
473  void
474  subject_impl< util::edge<G>, E >::change_graph(const mlc_const(G)& g)
475  {
476  return exact_().get_subject().change_graph(g);
477  }
478 
479  template <typename G, typename E>
480  inline
481  void
482  subject_impl< util::edge<G>, E >::invalidate()
483  {
484  return exact_().get_subject().invalidate();
485  }
486 
487  } // end of namespace mln::internal
488 
489 # endif // ! MLN_INCLUDE_ONLY
490 
491 } // end of namespace mln
492 
493 
494 #endif // ! MLN_UTIL_EDGE_HH