$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
faces_psite.hh
1 // Copyright (C) 2008, 2009, 2011, 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_FACES_PSITE_HH
28 # define MLN_CORE_FACES_PSITE_HH
29 
33 
34 # include <cstdlib>
35 
36 # include <mln/core/internal/pseudo_site_base.hh>
37 
38 # include <mln/topo/complex.hh>
39 
40 // FIXME: Factor complex_psite and faces_psite?
41 
42 // FIXME: Rename faces_psite as p_faces_psite, and move this file to
43 // core/site_set.
44 
45 namespace mln
46 {
47  // Forward declaration.
48  template <unsigned N, unsigned D, typename P> struct p_faces;
49 
50 
56  template <unsigned N, unsigned D, typename P>
57  class faces_psite
58  : public internal::pseudo_site_base_< const P&,
59  faces_psite<N, D, P> >
60  {
61  public:
62  // This associated type is important to know that this particular
63  // pseudo site knows the site set it refers to.
64  typedef p_faces<N, D, P> target;
65 
68  faces_psite();
70  faces_psite(const p_faces<N, D, P>& pf, const topo::n_face<N, D>& face);
71  faces_psite(const p_faces<N, D, P>& pf, unsigned face_id);
73 
77  bool is_valid() const;
79  void invalidate();
81 
87  const target& site_set() const;
88 
91  const target* target_() const;
93 
95  void change_target(const target& new_target);
97 
102  const P& subj_();
105 
109  topo::n_face<N, D> face() const;
110 
112  unsigned n() const;
114  unsigned face_id() const;
116 
117  private:
121  void update_();
122  // The site corresponding to this psite.
123  P p_;
125 
126  /* FIXME: Attributes pf_ and face_ share a common information: the
127  address of their complex.
128 
129  This is both a loss of space and time (we must ensure
130  synchronization), but this design issue is not trivial: we
131  actually introduced the face handles to pack together the
132  location information (face_id) with the support (the complex),
133  to avoid what we did with graphs --- where location (edge id or
134  vertex id) is separated from the support (the graph).
135 
136  Think about it, and adjust complex_psite as well. */
137  private:
141  const target* pf_;
143  topo::n_face<N, D> face_;
145  };
146 
147 
150  /* FIXME: Shouldn't those comparisons be part of a much general
151  mechanism? */
152 
157  template <unsigned N, unsigned D, typename P>
158  bool
159  operator==(const faces_psite<N, D, P>& lhs,
160  const faces_psite<N, D, P>& rhs);
161 
162 
167  template <unsigned N, unsigned D, typename P>
168  bool
169  operator!=(const faces_psite<N, D, P>& lhs,
170  const faces_psite<N, D, P>& rhs);
171 
178  template <unsigned N, unsigned D, typename P>
179  bool
180  operator< (const faces_psite<N, D, P>& lhs,
181  const faces_psite<N, D, P>& rhs);
183 
184 
185  template <unsigned N, unsigned D, typename P>
186  inline
187  std::ostream&
188  operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p);
189 
190 
191 
192 # ifndef MLN_INCLUDE_ONLY
193 
194  template <unsigned N, unsigned D, typename P>
195  inline
196  faces_psite<N, D, P>::faces_psite()
197  : pf_(0)
198  {
199  // Ensure N is compatible with D.
200  metal::bool_< N <= D >::check();
201 
202  invalidate();
203  }
204 
205  template <unsigned N, unsigned D, typename P>
206  inline
207  faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
208  const topo::n_face<N, D>& face)
209  : pf_(&pf),
210  face_(face)
211  {
212  // Ensure N is compatible with D.
213  metal::bool_< N <= D >::check();
214  // Check arguments consistency.
215 // mln_precondition(pf.cplx() == face.cplx());
216 
217  update_();
218  }
219 
220  template <unsigned N, unsigned D, typename P>
221  inline
222  faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
223  unsigned face_id)
224  : pf_(&pf),
225  face_(pf.cplx(), face_id)
226  {
227  // Ensure N is compatible with D.
228  metal::bool_< N <= D >::check();
229 
230  update_();
231  }
232 
233  template <unsigned N, unsigned D, typename P>
234  inline
235  bool
236  faces_psite<N, D, P>::is_valid() const
237  {
238 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
239  return face_.is_valid();
240  }
241 
242  template <unsigned N, unsigned D, typename P>
243  inline
244  void
245  faces_psite<N, D, P>::invalidate()
246  {
247  return face_.invalidate();
248  }
249 
250  template <unsigned N, unsigned D, typename P>
251  inline
252  const p_faces<N, D, P>&
254  {
255  mln_precondition(target_());
256  return *target_();
257  }
258 
259  template <unsigned N, unsigned D, typename P>
260  inline
261  const p_faces<N, D, P>*
262  faces_psite<N, D, P>::target_() const
263  {
264 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
265  return pf_;
266  }
267 
268  template <unsigned N, unsigned D, typename P>
269  inline
270  void
271  faces_psite<N, D, P>::change_target(const target& new_target)
272  {
273  // Update both pc_ and face_.
274  pf_ = &new_target;
275  face_.set_cplx(new_target.cplx());
276  invalidate();
277  }
278 
279  // FIXME: Write or extend a test to exercise this method (when the
280  // handling of P is done, i.e., when update_ is complete).
281  template <unsigned N, unsigned D, typename P>
282  inline
283  const P&
284  faces_psite<N, D, P>::subj_()
285  {
286  // FIXME: Member p_ is not updated correctly yet; do not use this
287  // method for now.
288  abort();
289  return p_;
290  }
291 
292  template <unsigned N, unsigned D, typename P>
293  inline
294  topo::n_face<N, D>
295  faces_psite<N, D, P>::face() const
296  {
297  return face_;
298  }
299 
300  template <unsigned N, unsigned D, typename P>
301  inline
302  unsigned
303  faces_psite<N, D, P>::n() const
304  {
305  return face_.n();
306  }
307 
308  template <unsigned N, unsigned D, typename P>
309  inline
310  unsigned
311  faces_psite<N, D, P>::face_id() const
312  {
313  return face_.face_id();
314  }
315 
316  template <unsigned N, unsigned D, typename P>
317  inline
318  void
319  faces_psite<N, D, P>::update_()
320  {
321  mln_precondition(is_valid());
322 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
323  // FIXME: Implement (update p_).
324  }
325 
326 
327  /*--------------.
328  | Comparisons. |
329  `--------------*/
330 
331  template <unsigned N, unsigned D, typename P>
332  bool
333  operator==(const faces_psite<N, D, P>& lhs,
334  const faces_psite<N, D, P>& rhs)
335  {
336  mln_precondition(&lhs.site_set() == &rhs.site_set());
337  return lhs.face() == rhs.face();
338  }
339 
340  template <unsigned N, unsigned D, typename P>
341  bool
342  operator!=(const faces_psite<N, D, P>& lhs,
343  const faces_psite<N, D, P>& rhs)
344  {
345  mln_precondition(&lhs.site_set() == &rhs.site_set());
346  return lhs.face() != rhs.face();
347  }
348 
349  template <unsigned N, unsigned D, typename P>
350  bool
351  operator< (const faces_psite<N, D, P>& lhs,
352  const faces_psite<N, D, P>& rhs)
353  {
354  mln_precondition(&lhs.site_set() == &rhs.site_set());
355  return lhs.face() < rhs.face();
356  }
357 
358 
359  /*------------------.
360  | Pretty-printing. |
361  `------------------*/
362 
363  template <unsigned N, unsigned D, typename P>
364  inline
365  std::ostream&
366  operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p)
367  {
368  return ostr << "(dim = " << p.n() << ", id = " << p.face_id() << ')';
369  }
370 
371 # endif // ! MLN_INCLUDE_ONLY
372 
373 } // end of mln
374 
375 #endif // ! MLN_CORE_FACES_PSITE_HH