Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
complex_psite.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_CORE_SITE_SET_COMPLEX_PSITE_HH
27 # define MLN_CORE_SITE_SET_COMPLEX_PSITE_HH
28 
32 
33 # include <mln/core/internal/pseudo_site_base.hh>
34 
35 # include <mln/topo/complex.hh>
36 
37 // FIXME: There's a circular dependency issue between complex_psite
38 // and p_complex (likewise for faces_psite and p_faces): they have to
39 // know their interfaces one another. I have disabled some
40 // preconditions and invariants to have the code compile, but we must
41 // find a real solution.
42 
43 // FIXME: Factor complex_psite and faces_psite?
44 
45 // FIXME: Rename complex_psite as p_complex_psite, and move this file to
46 // core/site_set.
47 
48 
49 namespace mln
50 {
51  // Forward declaration.
52  template <unsigned D, typename G> class p_complex;
53 
54 
59  template <unsigned D, typename G>
61  : public internal::pseudo_site_base_< const mln_site(G)&, complex_psite<D, G> >
62  {
63  public:
64  // This associated type is important to know that this particular
65  // pseudo site knows the site set it refers to.
66  typedef p_complex<D, G> target;
67 
68  typedef p_complex<D, G> target_t; // To please g++-2.95.
69 
70  // FIXME: Document.
73  complex_psite();
76  const topo::face<D>& face);
77  complex_psite(const p_complex<D, G>& pc, unsigned n, unsigned face_id);
79 
83  bool is_valid() const;
85  void invalidate();
87 
93  const target& site_set() const;
94 
96  const target* target_() const;
98  void change_target(const target& new_target);
100 
104  const mln_site(G)& subj_();
106 
110  const topo::face<D>& face() const;
111 
113  unsigned n() const;
115  unsigned face_id() const;
117 
118  private:
122  void update_();
123  // The site corresponding to this psite.
124  mln_site(G) p_;
126 
127  /* FIXME: Attributes pc_ and face_ share a common information: the
128  address of their complex.
129 
130  This is both a loss of space and time (we must ensure
131  synchronization), but this design issue is not trivial: we
132  actually introduced (any-)face handles to pack together the
133  location information (n, face_id) with the support (the
134  complex), to avoid what we did with graphs --- where location
135  (edge id or vertex id) is separated from the support (the
136  graph).
137 
138  Think about it, and adjust faces_psite as well. */
139  private:
143  const target* pc_;
145  topo::face<D> face_;
147  };
148 
149 
152  /* FIXME: Shouldn't those comparisons be part of a much general
153  mechanism? */
154 
159  /* FIXME: We probably want to relax this precondition: p_complex
160  equality is too strong; prefer complex equality. */
161  template <unsigned D, typename G>
162  bool
163  operator==(const complex_psite<D, G>& lhs,
164  const complex_psite<D, G>& rhs);
165 
170  /* FIXME: We probably want to relax this precondition: p_complex
171  equality is too strong; prefer complex equality. */
172  template <unsigned D, typename G>
173  bool
174  operator!=(const complex_psite<D, G>& lhs,
175  const complex_psite<D, G>& rhs);
176 
183  /* FIXME: We probably want to relax this precondition: p_complex
184  equality is too strong; prefer complex equality. */
185  template <unsigned D, typename G>
186  bool
187  operator< (const complex_psite<D, G>& lhs,
188  const complex_psite<D, G>& rhs);
190 
191 
192  template <unsigned D, typename G>
193  inline
194  std::ostream&
195  operator<<(std::ostream& ostr, const complex_psite<D, G>& p);
196 
197 
198 
199 # ifndef MLN_INCLUDE_ONLY
200 
201  template <unsigned D, typename G>
202  inline
204  : pc_(0)
205  {
206  invalidate();
207  }
208 
209  template <unsigned D, typename G>
210  inline
212  const topo::face<D>& face)
213  : pc_(&pc),
214  face_(face)
215  {
216  // Check arguments consistency.
217  // FIXME: Re-enable when the cyclic dependencies are fixed.
218 #if 0
219  mln_precondition(pc.cplx() == face.cplx());
220 #endif
221  if (is_valid())
222  update_();
223  }
224 
225  template <unsigned D, typename G>
226  inline
228  unsigned n, unsigned face_id)
229  : pc_(&pc),
230  face_(pc.cplx(), n, face_id)
231  {
232  if (is_valid())
233  update_();
234  }
235 
236  template <unsigned D, typename G>
237  inline
238  bool
240  {
241  // FIXME: Re-enable when the cyclic dependencies are fixed.
242 #if 0
243  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
244 #endif
245  return face_.is_valid();
246  }
247 
248  template <unsigned D, typename G>
249  inline
250  void
252  {
253  return face_.invalidate();
254  }
255 
256  template <unsigned D, typename G>
257  inline
258  const p_complex<D, G>&
260  {
261  mln_precondition(target_());
262  return *target_();
263  }
264 
265  template <unsigned D, typename G>
266  inline
267  const p_complex<D, G>*
269  {
270  // FIXME: Re-enable when the cyclic dependencies are fixed.
271 #if 0
272  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
273 #endif
274  return pc_;
275  }
276 
277  template <unsigned D, typename G>
278  inline
279  void
281  {
282  // Update both pc_ and face_.
283  pc_ = &new_target;
284  face_.set_cplx(new_target.cplx());
285  invalidate();
286  }
287 
288  // FIXME: Write or extend a test to exercise this method (when the
289  // handling of G is done, i.e., when update_ is complete).
290  template <unsigned D, typename G>
291  inline
292  const mln_site(G)&
294  {
295  return p_;
296  }
297 
298  template <unsigned D, typename G>
299  inline
300  const topo::face<D>&
302  {
303  return face_;
304  }
305 
306  template <unsigned D, typename G>
307  inline
308  unsigned
310  {
311  return face_.n();
312  }
313 
314  template <unsigned D, typename G>
315  inline
316  unsigned
318  {
319  return face_.face_id();
320  }
321 
322  template <unsigned D, typename G>
323  inline
324  void
326  {
327  mln_precondition(is_valid());
328  // FIXME: Re-enable when the cyclic dependencies are fixed.
329 #if 0
330  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
331 #endif
332  // FIXME: Simplify? (I.e., add accessors to shorten the following
333  // line?)
334  p_ = site_set().geom()(face_);
335  }
336 
337 
338  /*--------------.
339  | Comparisons. |
340  `--------------*/
341 
342  template <unsigned D, typename G>
343  bool
344  operator==(const complex_psite<D, G>& lhs,
345  const complex_psite<D, G>& rhs)
346  {
347  mln_precondition(&lhs.site_set() == &rhs.site_set());
348  return lhs.face() == rhs.face();
349  }
350 
351  template <unsigned D, typename G>
352  bool
354  const complex_psite<D, G>& rhs)
355  {
356  mln_precondition(&lhs.site_set() == &rhs.site_set());
357  return lhs.face() != rhs.face();
358  }
359 
360  template <unsigned D, typename G>
361  bool
362  operator< (const complex_psite<D, G>& lhs,
363  const complex_psite<D, G>& rhs)
364  {
365  mln_precondition(&lhs.site_set() == &rhs.site_set());
366  return lhs.face() < rhs.face();
367  }
368 
369 
370  /*------------------.
371  | Pretty-printing. |
372  `------------------*/
373 
374  template <unsigned D, typename G>
375  inline
376  std::ostream&
377  operator<<(std::ostream& ostr, const complex_psite<D, G>& p)
378  {
379  return ostr << p.face();
380  }
381 
382 # endif // ! MLN_INCLUDE_ONLY
383 
384 } // end of mln
385 
386 #endif // ! MLN_CORE_SITE_SET_COMPLEX_PSITE_HH