$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
operators.hh
1 // Copyright (C) 2007, 2008, 2009, 2012 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_OPERATORS_HH
28 # define MLN_CORE_SITE_SET_OPERATORS_HH
29 
35 
36 
37 # include <algorithm>
38 # include <mln/core/concept/site_set.hh>
39 
40 
41 
42 namespace mln
43 {
44 
45  // Forward declarations.
46  template <typename E> struct Box;
47  namespace set { template <typename S> unsigned card(const Site_Set<S>& s); }
48 
49 
50  template <typename Sl, typename Sr>
51  Sl&
53 
54 
62  template <typename Sl, typename Sr>
63  bool
64  operator==(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs);
65 
66 
67 
75  template <typename Sl, typename Sr>
76  bool
77  operator<=(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs);
78 
79 
80 
89  template <typename Sl, typename Sr>
90  bool
91  operator<(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs);
92 
93 
94 
105  template <typename S>
106  std::ostream&
107  operator<<(std::ostream& ostr, const Site_Set<S>& set);
108 
109 
110 
111 # ifndef MLN_INCLUDE_ONLY
112 
113 
114  namespace internal
115  {
116 
117  template <typename Sl, typename Sr>
118  inline
119  std::set< mln_site(Sl), util::ord<mln_site(Sl)> >
120  sym_diff_std_set(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
121  {
122  typedef mln_site(Sl) P;
123  mlc_converts_to(mln_psite(Sr), P)::check();
124  std::set< P, util::ord<P> > sl, sr, sd;
125  from_to_(lhs, sl);
126  from_to_(rhs, sr);
127  std::set_symmetric_difference(sl.begin(), sl.end(),
128  sr.begin(), sr.end(),
129  std::inserter(sd, sd.begin()),
130  util::ord<P>());
131  return sd;
132  }
133 
134  template <typename S>
135  inline
136  std::set< mln_site(S), util::ord<mln_site(S)> >
137  to_std_set(const Site_Set<S>& s)
138  {
139  std::set< mln_site(S), util::ord<mln_site(S)> > std_s;
140  from_to_(s, std_s);
141  return std_s;
142  }
143 
144  template <typename Sl, typename Sr>
145  inline
146  bool
147  leq_std_set(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
148  {
149  typedef mln_site(Sl) P;
150  mlc_converts_to(mln_psite(Sr), P)::check();
151  std::set< P, util::ord<P> > sl, sr;
152  from_to_(lhs, sl);
153  from_to_(rhs, sr);
154  return std::includes(sr.begin(), sr.end(),
155  sl.begin(), sl.end(),
156  util::ord<P>());
157  }
158 
159 
160  // card.
161 
162  template <typename S>
163  inline
164  unsigned set_card_dispatch_(mln::trait::site_set::nsites::any,
165  const S& s)
166  {
167  unsigned n = 0;
168  mln_piter(S) p(s);
169  for_all(p)
170  ++n;
171  return n;
172  }
173 
174  template <typename S>
175  inline
176  unsigned set_card_dispatch_(mln::trait::site_set::nsites::known,
177  const S& s)
178  {
179  return s.nsites();
180  }
181 
182  template <typename S>
183  inline
184  unsigned set_card(const Site_Set<S>& s)
185  {
186  return set_card_dispatch_(mln_trait_site_set_nsites(S)(),
187  exact(s));
188  }
189 
190  } // end of namespace mln::internal
191 
192 
193  namespace impl
194  {
195 
196  // Implementations for "operator ==" between site sets.
197 
198  template <typename Bl, typename Br>
199  inline
200  bool
201  operator_equal_boxes(const Box<Bl>& lhs_, const Box<Br>& rhs_)
202  {
203  const Bl& lhs = exact(lhs_);
204  const Br& rhs = exact(rhs_);
205  if (lhs.is_empty() != rhs.is_empty())
206  return false;
207  if (lhs.is_empty() && rhs.is_empty())
208  return true;
209  return lhs.pmin() == rhs.pmin() && lhs.pmax() == rhs.pmax();
210  }
211 
212  template <typename Sl, typename Sr>
213  inline
214  bool
215  operator_equal_uniques(const Site_Set<Sl>& lhs,
216  const Site_Set<Sr>& rhs)
217  {
218  if (internal::set_card(lhs) != internal::set_card(rhs))
219  return false;
220  return mln::internal::sym_diff_std_set(lhs, rhs).empty();
221  }
222 
223  template <typename Sl, typename Sr>
224  inline
225  bool
226  operator_equal_unique_multiple(const Site_Set<Sl>& lhs,
227  const Site_Set<Sr>& rhs)
228  {
229  if (internal::set_card(lhs) != internal::set_card(rhs))
230  return false;
231  return mln::internal::to_std_set(lhs) == mln::internal::to_std_set(rhs);
232  }
233 
234  template <typename Sl, typename Sr>
235  inline
236  bool
237  operator_equal_multiples(const Site_Set<Sl>& lhs,
238  const Site_Set<Sr>& rhs)
239  {
240  // FIXME: Approximate code...
241  if (internal::set_card(lhs) != internal::set_card(rhs))
242  return false;
243  return mln::internal::to_std_set(lhs) == mln::internal::to_std_set(rhs);
244  }
245 
246 
247  // Implementations for "operator <" between site sets.
248 
249  template <typename Bl, typename Br>
250  inline
251  bool
252  operator_less_boxes(const Box<Bl>& lhs_, const Box<Br>& rhs_)
253  {
254  const Bl& lhs = exact(lhs_);
255  const Br& rhs = exact(rhs_);
256  if (rhs.is_empty())
257  return false; // We cannot have "lhs < empty_set".
258  // From this line, rhs is not empty.
259  if (lhs.is_empty())
260  return true; // We have "empty set < a non empty set".
261  // From here, both lhs and rhs are not empty.
262  if (internal::set_card(lhs) >= internal::set_card(rhs))
263  return false;
264  return lhs.crop_wrt(rhs) == lhs;
265  }
266 
267  template <typename Sl, typename Sr>
268  inline
269  bool
270  operator_less_uniques(const Site_Set<Sl>& lhs,
271  const Site_Set<Sr>& rhs)
272  {
273  if (internal::set_card(lhs) >= internal::set_card(rhs))
274  return false;
275  return mln::internal::leq_std_set(lhs, rhs);
276  }
277 
278  template <typename Sl, typename Sr>
279  inline
280  bool
281  operator_less_unique_multiple(const Site_Set<Sl>& lhs,
282  const Site_Set<Sr>& rhs)
283  {
284  if (internal::set_card(lhs) >= internal::set_card(rhs))
285  return false;
286  return mln::internal::leq_std_set(lhs, rhs);
287  }
288 
289  template <typename Sl, typename Sr>
290  inline
291  bool
292  operator_less_multiples(const Site_Set<Sl>& lhs,
293  const Site_Set<Sr>& rhs)
294  {
295  // FIXME: Approximate code...
296  if (internal::set_card(lhs) >= internal::set_card(rhs))
297  return false;
298  return mln::internal::leq_std_set(lhs, rhs);
299  }
300 
301  } // end of namespace mln::impl
302 
303 
304 
305 
306  namespace internal
307  {
308 
309  // Dispatch for "operator ==" between site sets.
310 
311  template <typename Sl, typename Sr>
312  inline
313  bool
314  operator_equal_dispatch(trait::site_set::arity::unique,
315  const Box<Sl>& lhs,
316  trait::site_set::arity::unique,
317  const Box<Sr>& rhs)
318  {
319  return impl::operator_equal_boxes(lhs, rhs);
320  }
321 
322  template <typename Sl, typename Sr>
323  inline
324  bool
325  operator_equal_dispatch(trait::site_set::arity::unique,
326  const Site_Set<Sl>& lhs,
327  trait::site_set::arity::unique,
328  const Site_Set<Sr>& rhs)
329  {
330  return impl::operator_equal_uniques(lhs, rhs);
331  }
332 
333  template <typename Sl, typename Sr>
334  inline
335  bool
336  operator_equal_dispatch(trait::site_set::arity::unique,
337  const Site_Set<Sl>& lhs,
338  trait::site_set::arity::multiple,
339  const Site_Set<Sr>& rhs)
340  {
341  return impl::operator_equal_unique_multiple(lhs, rhs);
342  }
343 
344  template <typename Sl, typename Sr>
345  inline
346  bool
347  operator_equal_dispatch(trait::site_set::arity::multiple,
348  const Site_Set<Sl>& lhs,
349  trait::site_set::arity::unique,
350  const Site_Set<Sr>& rhs)
351  {
352  return impl::operator_equal_unique_multiple(rhs, lhs);
353  }
354 
355  template <typename Sl, typename Sr>
356  inline
357  bool
358  operator_equal_dispatch(trait::site_set::arity::multiple,
359  const Site_Set<Sl>& lhs,
360  trait::site_set::arity::multiple,
361  const Site_Set<Sr>& rhs)
362  {
363  return impl::operator_equal_multiples(lhs, rhs);
364  }
365 
366  template <typename Sl, typename Sr>
367  inline
368  bool
369  operator_equal_dispatch(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
370  {
371  return operator_equal_dispatch(mln_trait_site_set_arity(Sl)(), exact(lhs),
372  mln_trait_site_set_arity(Sr)(), exact(rhs));
373  }
374 
375 
376  // Dispatch for "operator <" between site sets.
377 
378  template <typename Sl, typename Sr>
379  inline
380  bool
381  operator_less_dispatch(trait::site_set::arity::unique,
382  const Box<Sl>& lhs,
383  trait::site_set::arity::unique,
384  const Box<Sr>& rhs)
385  {
386  return impl::operator_less_boxes(lhs, rhs);
387  }
388 
389  template <typename Sl, typename Sr>
390  inline
391  bool
392  operator_less_dispatch(trait::site_set::arity::unique,
393  const Site_Set<Sl>& lhs,
394  trait::site_set::arity::unique,
395  const Site_Set<Sr>& rhs)
396  {
397  return impl::operator_less_uniques(lhs, rhs);
398  }
399 
400  template <typename Sl, typename Sr>
401  inline
402  bool
403  operator_less_dispatch(trait::site_set::arity::unique,
404  const Site_Set<Sl>& lhs,
405  trait::site_set::arity::multiple,
406  const Site_Set<Sr>& rhs)
407  {
408  return impl::operator_less_unique_multiple(lhs, rhs);
409  }
410 
411  template <typename Sl, typename Sr>
412  inline
413  bool
414  operator_less_dispatch(trait::site_set::arity::multiple,
415  const Site_Set<Sl>& lhs,
416  trait::site_set::arity::unique,
417  const Site_Set<Sr>& rhs)
418  {
419  return impl::operator_less_unique_multiple(rhs, lhs);
420  }
421 
422  template <typename Sl, typename Sr>
423  inline
424  bool
425  operator_less_dispatch(trait::site_set::arity::multiple,
426  const Site_Set<Sl>& lhs,
427  trait::site_set::arity::multiple,
428  const Site_Set<Sr>& rhs)
429  {
430  return impl::operator_less_multiples(lhs, rhs);
431  }
432 
433  template <typename Sl, typename Sr>
434  inline
435  bool
436  operator_less_dispatch(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
437  {
438  return operator_less_dispatch(mln_trait_site_set_arity(Sl)(), exact(lhs),
439  mln_trait_site_set_arity(Sr)(), exact(rhs));
440  }
441 
442  } // end of namespace mln::internal
443 
444 
445  // Operator +=.
446 
447  template <typename Sl, typename Sr>
448  inline
449  Sl&
450  operator+=(Site_Set<Sl>& lhs_, const Site_Set<Sr>& rhs)
451  {
452  mlc_is( mln_trait_site_set_contents(Sl),
453  mln::trait::site_set::contents::dynamic )::check();
454  mlc_equal(mln_site(Sr), typename Sl::i_element)::check();
455  Sl& lhs = exact(lhs_);
456  mln_fwd_piter(Sr) p(exact(rhs));
457  for_all(p)
458  lhs.insert(p);
459  return lhs;
460  }
461 
462 
463  // Operator ==.
464 
465  template <typename Sl, typename Sr>
466  inline
467  bool
468  operator==(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
469  {
470  mlc_equal(mln_site(Sl), mln_site(Sr))::check();
471  return internal::operator_equal_dispatch(lhs, rhs);
472  }
473 
474 
475  // Operator <.
476 
477  template <typename Sl, typename Sr>
478  inline
479  bool
480  operator<(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
481  {
482  mlc_equal(mln_site(Sl), mln_site(Sr))::check();
483  return internal::operator_less_dispatch(lhs, rhs);
484  }
485 
486 
487  // Operator <=.
488 
489  template <typename Sl, typename Sr>
490  inline
491  bool
492  operator<=(const Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs)
493  {
494  mlc_equal(mln_site(Sl), mln_site(Sr))::check();
495  if (internal::set_card(lhs) > internal::set_card(rhs))
496  return false;
497  return lhs < rhs || lhs == rhs;
498  }
499 
500 
501  // Operator <<.
502 
503  template <typename S>
504  inline
505  std::ostream&
506  operator<<(std::ostream& ostr, const Site_Set<S>& set_)
507  {
508  const S& set = exact(set_);
509  ostr << '{';
510  mln_piter(S) p(set);
511  for_all(p)
512  ostr << p;
513  return ostr << '}';
514  }
515 
516 # endif // ! MLN_INCLUDE_ONLY
517 
518 } // end of namespace mln
519 
520 
521 #endif // ! MLN_CORE_SITE_SET_OPERATORS_HH