Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
graph_psite_base.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
2 // (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_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
28 # define MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
29 
36 
37 # include <mln/core/internal/pseudo_site_base.hh>
38 
39 
40 
41 namespace mln
42 {
43 
44  namespace internal
45  {
46 
47  template <typename S, typename E>
48  class graph_psite_base : public internal::pseudo_site_base_< const mln_site(S)&,
49  E >
50  {
51  public:
52 
53  // This associated type is important to know that this particular
54  // pseudo site knows the site set it refers to.
55  typedef S target;
56 
57  // As a Proxy:
58  const mln_site(S)& subj_();
59 
60  typedef typename S::graph_element::id_t id_t;
61 
65  void change_target(const S& new_target);
68  void update_id(unsigned elt_id);
70 
74  const S* target_() const; // Hook to the target.
75 
77  const S& site_set() const;
78 
80  const typename S::graph_t& graph() const;
81 
83  id_t id() const;
84 
86 
88  bool is_valid() const;
90  void invalidate();
91 
93  operator unsigned () const;
94 
96  operator typename S::graph_element::id_t () const;
97 
99  operator const typename S::graph_element&() const;
100 
102  const typename S::graph_element& element() const;
103 
105  const typename S::graph_element& p_hook_() const;
106 
107  protected:
108 
110 
112  graph_psite_base();
115  graph_psite_base(const S& s);
119  graph_psite_base(const S& , unsigned id);
121 
122  const S* s_;
123  mln_site(S) site_;
124  typename S::graph_element elt_;
125  };
126 
127 
128  /* FIXME: Shouldn't those comparisons be part of a much general
129  mechanism? */
130 
137  template <typename S, typename E>
138  bool
139  operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
140 
145  template <typename S, typename E>
146  bool
147  operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
148 
155  template <typename S, typename E>
156  bool
157  operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
159 
160 
163  template <typename S, typename P, typename E>
164  struct subject_impl< const graph_psite_base<S,P>&, E >
165  {
166  const S* target_() const;
167  const S& site_set() const;
168  const typename S::graph_t& graph() const;
169  unsigned id() const;
170  bool is_valid() const;
171  // operator unsigned() const;
172  // operator const typename S::graph_element&() const;
173  const typename S::graph_element& element() const;
174  const typename S::graph_element& p_hook_() const;
175 
176  private:
177  const E& exact_() const;
178  };
179 
180  template <typename S, typename P, typename E>
181  struct subject_impl< graph_psite_base<S,P>&, E > :
182  subject_impl< const graph_psite_base<S,P>&, E >
183  {
184  void change_target(const S& new_target);
185  void update_id(unsigned elt_id);
186  void invalidate();
187 
188  private:
189  E& exact_();
190  };
192 
193 
194 
195 # ifndef MLN_INCLUDE_ONLY
196 
197 
198  template <typename S, typename E>
199  inline
200  graph_psite_base<S,E>::graph_psite_base()
201  : s_(0)
202  {
203  }
204 
205  template <typename S, typename E>
206  inline
207  graph_psite_base<S,E>::graph_psite_base(const S& s)
208  {
209  change_target(s);
210  }
211 
212  template <typename S, typename E>
213  inline
214  graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
215  {
216  change_target(s);
217  update_id(id);
218  }
219 
220  // The lines below are dedicated/local to this file.
221  template <typename E, typename S, typename G>
222  inline
223  void local_change_graph(E& elt_, S& site_, const G& g)
224  {
225  (void) site_;
226  elt_.change_graph(g);
227  }
228  template <typename E, typename G>
229  inline
230  void local_change_graph(E& elt_, E& site_, const G& g)
231  {
232  elt_.change_graph(g);
233  site_.change_graph(g);
234  }
235  // End of local stuff.
236 
237  template <typename S, typename E>
238  inline
239  void
240  graph_psite_base<S,E>::change_target(const S& new_target)
241  {
242  s_ = & new_target;
243  local_change_graph(elt_, site_, new_target.graph());
244  }
245 
246  template <typename S, typename E>
247  inline
248  void
249  graph_psite_base<S,E>::update_id(unsigned id)
250  {
251  mln_precondition(s_ != 0);
252  elt_.update_id(id);
253  site_ = s_->function()(elt_.id());
254  }
255 
256  template <typename S, typename E>
257  inline
258  const S*
259  graph_psite_base<S,E>::target_() const
260  {
261  return s_;
262  }
263 
264  template <typename S, typename E>
265  inline
266  const S&
267  graph_psite_base<S,E>::site_set() const
268  {
269  mln_precondition(s_ != 0);
270  return *s_;
271  }
272 
273  template <typename S, typename E>
274  inline
275  const typename S::graph_t&
276  graph_psite_base<S,E>::graph() const
277  {
278  mln_precondition(s_ != 0);
279  return s_->graph();
280  }
281 
282  template <typename S, typename E>
283  inline
284  typename graph_psite_base<S,E>::id_t
285  graph_psite_base<S,E>::id() const
286  {
287  return elt_.id();
288  }
289 
290  template <typename S, typename E>
291  inline
292  bool
293  graph_psite_base<S,E>::is_valid() const
294  {
295  return s_ != 0 && s_->is_valid() && elt_.is_valid();
296  }
297 
298  template <typename S, typename E>
299  inline
300  void
301  graph_psite_base<S,E>::invalidate()
302  {
303  s_ = 0;
304  elt_.invalidate();
305  }
306 
307  template <typename S, typename E>
308  inline
309  const mln_site(S)&
310  graph_psite_base<S,E>::subj_()
311  {
312  /*FIXME: we may like to enable the following precondition, however, we
313  ** can't do that since neighb_*_niters update the psite target after having
314  ** taken the adress of the subject.
315  */
316  // mln_precondition(is_valid());
317  return site_;
318  }
319 
320  template <typename S, typename E>
321  inline
322  graph_psite_base<S,E>::operator unsigned () const
323  {
324  mln_precondition(is_valid());
325  return elt_.id();
326  }
327 
328  template <typename S, typename E>
329  inline
330  graph_psite_base<S,E>::operator typename S::graph_element::id_t () const
331  {
332  mln_precondition(is_valid());
333  return elt_.id();
334  }
335 
336  template <typename S, typename E>
337  inline
338  graph_psite_base<S,E>::operator const typename S::graph_element&() const
339  {
340  //mln_precondition(is_valid());
341  return elt_;
342  }
343 
344  template <typename S, typename E>
345  inline
346  const typename S::graph_element&
347  graph_psite_base<S,E>::element() const
348  {
349  /*FIXME: we may like to enable the following precondition, however, we
350  ** can't do that since neighb_*_niters update the psite target after having
351  ** taken the adress of the subject.
352  */
353  // mln_precondition(is_valid());
354  return elt_;
355  }
356 
357  template <typename S, typename E>
358  inline
359  const typename S::graph_element&
360  graph_psite_base<S,E>::p_hook_() const
361  {
362  return elt_;
363  }
364 
365 
366  template <typename S, typename P, typename E>
367  inline
368  const E&
369  subject_impl< const graph_psite_base<S,P>&, E >::exact_() const
370  {
371  return internal::force_exact<const E>(*this);
372  }
373 
374  template <typename S, typename P, typename E>
375  inline
376  const S*
377  subject_impl< const graph_psite_base<S,P>&, E >::target_() const
378  {
379  return exact_().get_subject().target();
380  }
381 
382  template <typename S, typename P, typename E>
383  inline
384  const S&
385  subject_impl< const graph_psite_base<S,P>&, E >::site_set() const
386  {
387  return exact_().get_subject().site_set();
388  }
389 
390 
391  template <typename S, typename P, typename E>
392  inline
393  const typename S::graph_t&
394  subject_impl< const graph_psite_base<S,P>&, E >::graph() const
395  {
396  return exact_().get_subject().graph();
397  }
398 
399  template <typename S, typename P, typename E>
400  inline
401  unsigned
402  subject_impl< const graph_psite_base<S,P>&, E >::id() const
403  {
404  return exact_().get_subject().id();
405  };
406 
407  template <typename S, typename P, typename E>
408  inline
409  bool
410  subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const
411  {
412  return exact_().get_subject().is_valid();
413  }
414 
415  template <typename S, typename P, typename E>
416  inline
417  const typename S::graph_element&
418  subject_impl< const graph_psite_base<S,P>&, E >::element() const
419  {
420  return exact_().get_subject().element();
421  }
422 
423  template <typename S, typename P, typename E>
424  inline
425  const typename S::graph_element&
426  subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const
427  {
428  return exact_().get_subject().p_hook_();
429  }
430 
431 
432  template <typename S, typename P, typename E>
433  inline
434  E&
435  subject_impl< graph_psite_base<S,P>&, E >::exact_()
436  {
437  return internal::force_exact<E>(*this);
438  }
439 
440  template <typename S, typename P, typename E>
441  inline
442  void
443  subject_impl< graph_psite_base<S,P>&, E >::change_target(const S& new_target)
444  {
445  exact_().get_subject().change_target(new_target);
446  }
447 
448  template <typename S, typename P, typename E>
449  inline
450  void
451  subject_impl< graph_psite_base<S,P>&, E >::update_id(unsigned id)
452  {
453  exact_().get_subject().update_id(id);
454  };
455 
456  template <typename S, typename P, typename E>
457  inline
458  void
459  subject_impl< graph_psite_base<S,P>&, E >::invalidate()
460  {
461  exact_().get_subject().invalidate();
462  }
463 
464 # endif // ! MLN_INCLUDE_ONLY
465 
466  } // end of namespace internal
467 
468 } // end of namespace mln
469 
470 
471 #endif // ! MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH