$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
complex_psite.hh
1 // Copyright (C) 2008, 2009, 2013 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_CORE_SITE_SET_COMPLEX_PSITE_HH
28 # define MLN_CORE_SITE_SET_COMPLEX_PSITE_HH
29 
33 
34 # include <mln/core/internal/pseudo_site_base.hh>
35 
36 # include <mln/topo/complex.hh>
37 
38 // FIXME: There's a circular dependency issue between complex_psite
39 // and p_complex (likewise for faces_psite and p_faces): they have to
40 // know their interfaces one another. I have disabled some
41 // preconditions and invariants to have the code compile, but we must
42 // find a real solution.
43 
44 // FIXME: Factor complex_psite and faces_psite?
45 
46 // FIXME: Rename complex_psite as p_complex_psite, and move this file to
47 // core/site_set.
48 
49 
50 namespace mln
51 {
52  // Forward declaration.
53  template <unsigned D, typename G> class p_complex;
54 
55 
60  template <unsigned D, typename G>
62  : public internal::pseudo_site_base_< const mln_site(G)&, complex_psite<D, G> >
63  {
64  public:
65  // This associated type is important to know that this particular
66  // pseudo site knows the site set it refers to.
68 
69  typedef p_complex<D, G> target_t; // To please g++-2.95.
70 
71  // FIXME: Document.
74  complex_psite();
77  const topo::face<D>& face);
78  complex_psite(const p_complex<D, G>& pc, unsigned n, unsigned face_id);
80 
84  bool is_valid() const;
86  void invalidate();
88 
94  const target& site_set() const;
95 
98  const target* target_() const;
100 
102  void change_target(const target& new_target);
104 
109  const mln_site(G)& subj_();
112 
116  const topo::face<D>& face() const;
117 
119  unsigned n() const;
121  unsigned face_id() const;
123 
124  private:
128  void update_();
129  // The site corresponding to this psite.
130  mln_site(G) p_;
132 
133  /* FIXME: Attributes pc_ and face_ share a common information: the
134  address of their complex.
135 
136  This is both a loss of space and time (we must ensure
137  synchronization), but this design issue is not trivial: we
138  actually introduced (any-)face handles to pack together the
139  location information (n, face_id) with the support (the
140  complex), to avoid what we did with graphs --- where location
141  (edge id or vertex id) is separated from the support (the
142  graph).
143 
144  Think about it, and adjust faces_psite as well. */
145  private:
149  const target* pc_;
151  topo::face<D> face_;
153  };
154 
155 
158  /* FIXME: Shouldn't those comparisons be part of a much general
159  mechanism? */
160 
166  /* FIXME: We probably want to relax this precondition: p_complex
167  equality is too strong; prefer complex equality. */
168  template <unsigned D, typename G>
169  bool
170  operator==(const complex_psite<D, G>& lhs,
171  const complex_psite<D, G>& rhs);
172 
178  /* FIXME: We probably want to relax this precondition: p_complex
179  equality is too strong; prefer complex equality. */
180  template <unsigned D, typename G>
181  bool
182  operator!=(const complex_psite<D, G>& lhs,
183  const complex_psite<D, G>& rhs);
184 
192  /* FIXME: We probably want to relax this precondition: p_complex
193  equality is too strong; prefer complex equality. */
194  template <unsigned D, typename G>
195  bool
196  operator< (const complex_psite<D, G>& lhs,
197  const complex_psite<D, G>& rhs);
199 
201  template <unsigned D, typename G>
202  inline
203  std::ostream&
204  operator<<(std::ostream& ostr, const complex_psite<D, G>& p);
205 
206 
207 
208 # ifndef MLN_INCLUDE_ONLY
209 
210  template <unsigned D, typename G>
211  inline
213  : pc_(0)
214  {
215  invalidate();
216  }
217 
218  template <unsigned D, typename G>
219  inline
221  const topo::face<D>& face)
222  : pc_(&pc),
223  face_(face)
224  {
225  // Check arguments consistency.
226  // FIXME: Re-enable when the cyclic dependencies are fixed.
227 #if 0
228  mln_precondition(pc.cplx() == face.cplx());
229 #endif
230  if (is_valid())
231  update_();
232  }
233 
234  template <unsigned D, typename G>
235  inline
236  complex_psite<D, G>::complex_psite(const p_complex<D, G>& pc,
237  unsigned n, unsigned face_id)
238  : pc_(&pc),
239  face_(pc.cplx(), n, face_id)
240  {
241  if (is_valid())
242  update_();
243  }
244 
245  template <unsigned D, typename G>
246  inline
247  bool
249  {
250  // FIXME: Re-enable when the cyclic dependencies are fixed.
251 #if 0
252  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
253 #endif
254  return face_.is_valid();
255  }
256 
257  template <unsigned D, typename G>
258  inline
259  void
261  {
262  return face_.invalidate();
263  }
264 
265  template <unsigned D, typename G>
266  inline
267  const p_complex<D, G>&
269  {
270  mln_precondition(target_());
271  return *target_();
272  }
273 
274  template <unsigned D, typename G>
275  inline
276  const p_complex<D, G>*
278  {
279  // FIXME: Re-enable when the cyclic dependencies are fixed.
280 #if 0
281  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
282 #endif
283  return pc_;
284  }
285 
286  template <unsigned D, typename G>
287  inline
288  void
289  complex_psite<D, G>::change_target(const target& new_target)
290  {
291  // Update both pc_ and face_.
292  pc_ = &new_target;
293  face_.set_cplx(new_target.cplx());
294  invalidate();
295  }
296 
297  // FIXME: Write or extend a test to exercise this method (when the
298  // handling of G is done, i.e., when update_ is complete).
299  template <unsigned D, typename G>
300  inline
301  const mln_site(G)&
303  {
304  return p_;
305  }
306 
307  template <unsigned D, typename G>
308  inline
309  const topo::face<D>&
311  {
312  return face_;
313  }
314 
315  template <unsigned D, typename G>
316  inline
317  unsigned
318  complex_psite<D, G>::n() const
319  {
320  return face_.n();
321  }
322 
323  template <unsigned D, typename G>
324  inline
325  unsigned
327  {
328  return face_.face_id();
329  }
330 
331  template <unsigned D, typename G>
332  inline
333  void
334  complex_psite<D, G>::update_()
335  {
336  mln_precondition(is_valid());
337  // FIXME: Re-enable when the cyclic dependencies are fixed.
338 #if 0
339  mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
340 #endif
341  // FIXME: Simplify? (I.e., add accessors to shorten the following
342  // line?)
343  p_ = site_set().geom()(face_);
344  }
345 
346 
347  /*--------------.
348  | Comparisons. |
349  `--------------*/
350 
351  template <unsigned D, typename G>
352  bool
353  operator==(const complex_psite<D, G>& lhs,
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  template <unsigned D, typename G>
370  bool
371  operator< (const complex_psite<D, G>& lhs,
372  const complex_psite<D, G>& rhs)
373  {
374  mln_precondition(&lhs.site_set() == &rhs.site_set());
375  return lhs.face() < rhs.face();
376  }
377 
378 
379  /*------------------.
380  | Pretty-printing. |
381  `------------------*/
382 
383  template <unsigned D, typename G>
384  inline
385  std::ostream&
386  operator<<(std::ostream& ostr, const complex_psite<D, G>& p)
387  {
388  return ostr << p.face();
389  }
390 
391 # endif // ! MLN_INCLUDE_ONLY
392 
393 } // end of mln
394 
395 #endif // ! MLN_CORE_SITE_SET_COMPLEX_PSITE_HH