$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
algebraic_face.hh
1 // Copyright (C) 2008, 2009, 2010 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_TOPO_ALGEBRAIC_FACE_HH
28 # define MLN_TOPO_ALGEBRAIC_FACE_HH
29 
33 
34 #include <mln/topo/face.hh>
35 #include <mln/topo/algebraic_n_face.hh>
36 
37 
38 namespace mln
39 {
40 
41  namespace topo
42  {
43 
44  // Forward declarations.
45  template <unsigned D> class complex;
46  template <unsigned N, unsigned D> class n_face;
47  template <unsigned N, unsigned D> class face_data;
48 
49 
50  /*-------.
51  | Face. |
52  `-------*/
53 
59  template <unsigned D>
60  class algebraic_face : public face<D>
61  {
62  typedef face<D> super_;
63 
64  public:
65  // The type of the complex this handle points to.
67 
71  algebraic_face(complex<D>& complex, unsigned n, unsigned face_id,
72  bool sign);
74  algebraic_face(const face<D>& f, bool sign);
75 
77  template <unsigned N>
79 
83  bool sign() const;
85  void set_sign(bool sign);
87 
88  private:
90  bool sign_;
91  };
92 
93 
95  template <unsigned D>
97  make_algebraic_face(const face<D>& f, bool sign);
98 
99 
102  template <unsigned D>
104  operator-(const face<D>& f);
105 
106  template <unsigned D>
108  operator-(const algebraic_face<D>& f);
110 
111 
114 
119  template <unsigned D>
120  bool operator==(const algebraic_face<D>& lhs,
121  const algebraic_face<D>& rhs);
122 
127  template <unsigned D>
128  bool operator!=(const algebraic_face<D>& lhs,
129  const algebraic_face<D>& rhs);
130 
139  template <unsigned D>
140  bool operator< (const algebraic_face<D>& lhs,
141  const algebraic_face<D>& rhs);
142 
144 
145 
147  template <unsigned D>
148  std::ostream&
149  operator<<(std::ostream& ostr, const algebraic_face<D>& f);
150 
151 
152 
153 # ifndef MLN_INCLUDE_ONLY
154 
155  template <unsigned D>
156  inline
158  : super_(), sign_(true)
159  {
160  }
161 
162  template <unsigned D>
163  inline
164  algebraic_face<D>::algebraic_face(complex<D>& c, unsigned n,
165  unsigned face_id, bool sign)
166  : super_(c, n, face_id), sign_(sign)
167  {
168  // Ensure N is compatible with D.
169  mln_precondition(n <= D);
170  }
171 
172  template <unsigned D>
173  inline
174  algebraic_face<D>::algebraic_face(const face<D>& f, bool sign)
175  : super_(f), sign_(sign)
176  {
177  // Ensure N is compatible with D.
178  mln_precondition(f.n() <= D);
179  }
180 
181  template <unsigned D>
182  template <unsigned N>
183  inline
184  algebraic_face<D>::algebraic_face(const algebraic_n_face<N, D>& f)
185  : super_(f), sign_(f.sign())
186  {
187  // Ensure N is compatible with D.
188  metal::bool_< N <= D >::check();
189  }
190 
191 
192  template <unsigned D>
193  inline
194  bool
196  {
197  return sign_;
198  }
199 
200  template <unsigned D>
201  inline
202  void
203  algebraic_face<D>::set_sign(bool sign)
204  {
205  sign_ = sign;
206  }
207 
208 
209  template <unsigned D>
211  make_algebraic_face(const face<D>& f, bool sign)
212  {
213  return algebraic_face<D>(f, sign);
214  }
215 
216 
217  template <unsigned D>
219  operator-(const face<D>& f)
220  {
221  return algebraic_face<D>(f, false);
222  }
223 
224  template <unsigned D>
226  operator-(const algebraic_face<D>& f)
227  {
228  algebraic_face<D> f2(f);
229  f2.set_sign(!f.sign());
230  return f2;
231  }
232 
233 
234  template <unsigned D>
235  inline
236  bool
238  {
239  // Ensure LHS and RHS belong to the same complex.
240  mln_precondition(lhs.cplx() == rhs.cplx());
241  return
242  lhs.n() == rhs.n() &&
243  lhs.face_id() == rhs.face_id() &&
244  lhs.sign() == rhs.sign();
245  }
246 
247  template <unsigned D>
248  inline
249  bool
250  operator!=(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
251  {
252  // Ensure LHS and RHS belong to the same complex.
253  mln_precondition(lhs.cplx() == rhs.cplx());
254  return !(lhs == rhs);
255  }
256 
257  template <unsigned D>
258  inline
259  bool
260  operator< (const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
261  {
262  // Ensure LHS and RHS belong to the same complex.
263  mln_precondition(lhs.cplx() == rhs.cplx());
264  // Ensure LHS and RHS have the same dimension.
265  mln_precondition(lhs.n() == rhs.n());
266  return lhs.face_id() < rhs.face_id();
267  }
268 
269 
270  template <unsigned D>
271  inline
272  std::ostream&
273  operator<<(std::ostream& ostr, const algebraic_face<D>& f)
274  {
275  return
276  ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
277  << ", id = " << f.face_id() << ", sign = " << f.sign()<< ')';
278  }
279 
280 
281  /*-----------------------------------------------.
282  | Helpers for face<D>::lower_dim_adj_faces() and |
283  | face<D>::higher_dim_adj_faces(). |
284  `-----------------------------------------------*/
285 
286  /* FIXME: This is way too complicated; should disappear when the
287  implementation of complexes is simplified (see
288  https://trac.lrde.org/olena/ticket/168). */
289 
290  namespace internal
291  {
292 
293  template <unsigned N, unsigned D>
294  std::vector< algebraic_face<D> >
295  lower_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
296  {
297  metal::bool_< (N <= D) >::check();
298  metal::bool_< (N > 1) >::check();
299 
300  if (face.n() == N)
301  {
302  face_data<N, D>& data = face.template data<N>();
303  std::vector< algebraic_n_face<N - 1, D> > lower_dim_faces =
304  data.lower_dim_faces_;
305  std::vector< topo::algebraic_face<D> > result;
306  for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator f =
307  lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
308  result.push_back(*f);
309  return result;
310  }
311  else
312  return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
313  }
314 
315  template <unsigned D>
316  std::vector< algebraic_face<D> >
317  lower_dim_adj_faces_if_dim_matches_<1, D>::operator()(const face<D>& face)
318  {
321  mln_precondition(face.n() == 1);
322  face_data<1, D>& data = face.template data<1>();
323  std::vector< algebraic_n_face<0, D> > lower_dim_faces =
324  data.lower_dim_faces_;
325  std::vector< topo::algebraic_face<D> > result;
326  for (typename std::vector< algebraic_n_face<0, D> >::const_iterator f =
327  lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
328  result.push_back(*f);
329  return result;
330  }
331 
332  template <unsigned N, unsigned D>
333  std::vector< algebraic_face<D> >
334  higher_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
335  {
336  metal::bool_< (N < D) >::check();
337 
338  if (face.n() == N)
339  {
340  face_data<N, D>& data = face.template data<N>();
341  std::vector< algebraic_n_face<N + 1, D> > higher_dim_faces =
342  data.higher_dim_faces_;
343  std::vector< topo::algebraic_face<D> > result;
344  for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator f =
345  higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
346  result.push_back(*f);
347  return result;
348  }
349  else
350  return
351  internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
352  }
353 
354  template <unsigned D>
355  std::vector< algebraic_face<D> >
356  higher_dim_adj_faces_if_dim_matches_<0, D>::operator()(const face<D>& face)
357  {
360  mln_precondition(face.n() == 0);
361  face_data<0, D>& data = face.template data<0>();
362  std::vector< algebraic_n_face<1, D> > higher_dim_faces =
363  data.higher_dim_faces_;
364  std::vector< topo::algebraic_face<D> > result;
365  for (typename std::vector< algebraic_n_face<1, D> >::const_iterator f =
366  higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
367  result.push_back(*f);
368  return result;
369  }
370 
371  } // end of namespace mln::topo::internal
372 
373 
374 # endif // ! MLN_INCLUDE_ONLY
375 
376  } // end of namespace mln::topo
377 
378 } // end of namespace mln
379 
380 #endif // ! MLN_TOPO_ALGEBRAIC_FACE_HH