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