Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
faces_psite.hh
1 // Copyright (C) 2008, 2009, 2011 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 
90  const target* target_() const;
92  void change_target(const target& new_target);
94 
98  const P& subj_();
100 
104  topo::n_face<N, D> face() const;
105 
107  unsigned n() const;
109  unsigned face_id() const;
111 
112  private:
116  void update_();
117  // The site corresponding to this psite.
118  P p_;
120 
121  /* FIXME: Attributes pf_ and face_ share a common information: the
122  address of their complex.
123 
124  This is both a loss of space and time (we must ensure
125  synchronization), but this design issue is not trivial: we
126  actually introduced the face handles to pack together the
127  location information (face_id) with the support (the complex),
128  to avoid what we did with graphs --- where location (edge id or
129  vertex id) is separated from the support (the graph).
130 
131  Think about it, and adjust complex_psite as well. */
132  private:
136  const target* pf_;
138  topo::n_face<N, D> face_;
140  };
141 
142 
145  /* FIXME: Shouldn't those comparisons be part of a much general
146  mechanism? */
147 
152  template <unsigned N, unsigned D, typename P>
153  bool
154  operator==(const faces_psite<N, D, P>& lhs,
155  const faces_psite<N, D, P>& rhs);
156 
157 
162  template <unsigned N, unsigned D, typename P>
163  bool
164  operator!=(const faces_psite<N, D, P>& lhs,
165  const faces_psite<N, D, P>& rhs);
166 
173  template <unsigned N, unsigned D, typename P>
174  bool
175  operator< (const faces_psite<N, D, P>& lhs,
176  const faces_psite<N, D, P>& rhs);
178 
179 
180  template <unsigned N, unsigned D, typename P>
181  inline
182  std::ostream&
183  operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p);
184 
185 
186 
187 # ifndef MLN_INCLUDE_ONLY
188 
189  template <unsigned N, unsigned D, typename P>
190  inline
191  faces_psite<N, D, P>::faces_psite()
192  : pf_(0)
193  {
194  // Ensure N is compatible with D.
195  metal::bool_< N <= D >::check();
196 
197  invalidate();
198  }
199 
200  template <unsigned N, unsigned D, typename P>
201  inline
202  faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
203  const topo::n_face<N, D>& face)
204  : pf_(&pf),
205  face_(face)
206  {
207  // Ensure N is compatible with D.
208  metal::bool_< N <= D >::check();
209  // Check arguments consistency.
210 // mln_precondition(pf.cplx() == face.cplx());
211 
212  update_();
213  }
214 
215  template <unsigned N, unsigned D, typename P>
216  inline
217  faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
218  unsigned face_id)
219  : pf_(&pf),
220  face_(pf.cplx(), face_id)
221  {
222  // Ensure N is compatible with D.
223  metal::bool_< N <= D >::check();
224 
225  update_();
226  }
227 
228  template <unsigned N, unsigned D, typename P>
229  inline
230  bool
231  faces_psite<N, D, P>::is_valid() const
232  {
233 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
234  return face_.is_valid();
235  }
236 
237  template <unsigned N, unsigned D, typename P>
238  inline
239  void
240  faces_psite<N, D, P>::invalidate()
241  {
242  return face_.invalidate();
243  }
244 
245  template <unsigned N, unsigned D, typename P>
246  inline
247  const p_faces<N, D, P>&
248  faces_psite<N, D, P>::site_set() const
249  {
250  mln_precondition(target_());
251  return *target_();
252  }
253 
254  template <unsigned N, unsigned D, typename P>
255  inline
256  const p_faces<N, D, P>*
257  faces_psite<N, D, P>::target_() const
258  {
259 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
260  return pf_;
261  }
262 
263  template <unsigned N, unsigned D, typename P>
264  inline
265  void
266  faces_psite<N, D, P>::change_target(const target& new_target)
267  {
268  // Update both pc_ and face_.
269  pf_ = &new_target;
270  face_.set_cplx(new_target.cplx());
271  invalidate();
272  }
273 
274  // FIXME: Write or extend a test to exercise this method (when the
275  // handling of P is done, i.e., when update_ is complete).
276  template <unsigned N, unsigned D, typename P>
277  inline
278  const P&
279  faces_psite<N, D, P>::subj_()
280  {
281  // FIXME: Member p_ is not updated correctly yet; do not use this
282  // method for now.
283  abort();
284  return p_;
285  }
286 
287  template <unsigned N, unsigned D, typename P>
288  inline
289  topo::n_face<N, D>
290  faces_psite<N, D, P>::face() const
291  {
292  return face_;
293  }
294 
295  template <unsigned N, unsigned D, typename P>
296  inline
297  unsigned
298  faces_psite<N, D, P>::n() const
299  {
300  return face_.n();
301  }
302 
303  template <unsigned N, unsigned D, typename P>
304  inline
305  unsigned
306  faces_psite<N, D, P>::face_id() const
307  {
308  return face_.face_id();
309  }
310 
311  template <unsigned N, unsigned D, typename P>
312  inline
313  void
314  faces_psite<N, D, P>::update_()
315  {
316  mln_precondition(is_valid());
317 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
318  // FIXME: Implement (update p_).
319  }
320 
321 
322  /*--------------.
323  | Comparisons. |
324  `--------------*/
325 
326  template <unsigned N, unsigned D, typename P>
327  bool
328  operator==(const faces_psite<N, D, P>& lhs,
329  const faces_psite<N, D, P>& rhs)
330  {
331  mln_precondition(&lhs.site_set() == &rhs.site_set());
332  return lhs.face() == rhs.face();
333  }
334 
335  template <unsigned N, unsigned D, typename P>
336  bool
337  operator!=(const faces_psite<N, D, P>& lhs,
338  const faces_psite<N, D, P>& rhs)
339  {
340  mln_precondition(&lhs.site_set() == &rhs.site_set());
341  return lhs.face() != rhs.face();
342  }
343 
344  template <unsigned N, unsigned D, typename P>
345  bool
346  operator< (const faces_psite<N, D, P>& lhs,
347  const faces_psite<N, D, P>& rhs)
348  {
349  mln_precondition(&lhs.site_set() == &rhs.site_set());
350  return lhs.face() < rhs.face();
351  }
352 
353 
354  /*------------------.
355  | Pretty-printing. |
356  `------------------*/
357 
358  template <unsigned N, unsigned D, typename P>
359  inline
360  std::ostream&
361  operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p)
362  {
363  return ostr << "(dim = " << p.n() << ", id = " << p.face_id() << ')';
364  }
365 
366 # endif // ! MLN_INCLUDE_ONLY
367 
368 } // end of mln
369 
370 #endif // ! MLN_CORE_FACES_PSITE_HH