$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
util/set.hh
1 // Copyright (C) 2007, 2008, 2009 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_UTIL_SET_HH
28 # define MLN_UTIL_SET_HH
29 
37 
38 # include <vector>
39 # include <set>
40 # include <iterator>
41 # include <algorithm>
42 # include <iostream>
43 
44 # include <mln/core/concept/proxy.hh>
45 # include <mln/util/ord.hh>
46 
47 
48 namespace mln
49 {
50 
51  namespace util
52  {
53 
54  // Forward declarations.
55  template <typename T> class set_fwd_iter;
56  template <typename T> class set_bkd_iter;
57 
58 
79  //
80  template <typename T>
81  class set : public Object< mln::util::set<T> >
82  {
83  public:
84 
86  typedef T element;
87 
88 
91 
94 
96  typedef fwd_eiter eiter;
97 
98 
107  set<T>& insert(const T& elt);
108 
109 
116  template <typename U>
117  set<T>& insert(const set<U>& other);
118 
119 
128  set<T>& remove(const T& elt);
129 
130 
138  void clear();
139 
140 
143  unsigned nelements() const;
144 
145 
148  bool is_empty() const;
149 
150 
151 
160  const T& operator[](unsigned i) const;
161 
164  const T first_element() const;
165 
168  const T last_element() const;
169 
170 
177  bool has(const T& elt) const;
178 
179 
188  const std::vector<T>& std_vector() const;
189 
190 
192  set();
193 
194 
196  std::size_t memory_size() const;
197 
199  bool is_frozen_() const;
200 
201  private:
202 
208  mutable std::vector<T> v_;
209 
214  mutable std::set< T, util::ord<T> > s_;
215 
216 
220  void freeze_() const;
221 
224  void unfreeze_() const;
225 
227  mutable bool frozen_;
228 
229 
230  // Used in method has(elt) when v_ holds data.
231  bool v_has_(const T& elt) const;
232  unsigned dicho_(const T& elt, unsigned beg, unsigned end) const;
233  };
234 
235 
236  template <typename T>
237  bool operator == (const set<T>& lhs, const set<T>& rhs);
238 
239 
240  template <typename T>
241  bool operator < (const set<T>& lhs, const set<T>& rhs);
242 
243 
244  template <typename T>
245  bool operator <= (const set<T>& lhs, const set<T>& rhs);
246 
247 
248 
249  // set_fwd_iter<T>
250 
251  template <typename T>
252  class set_fwd_iter : public Proxy< set_fwd_iter<T> >,
253  public mln::internal::proxy_impl< const T&, set_fwd_iter<T> >
254  {
255  public:
256 
258  set_fwd_iter();
259 
261  set_fwd_iter(const set<T>& s);
262 
264  void change_target(const set<T>& s);
265 
267  void start();
268 
270  void next();
271 
273  bool is_valid() const;
274 
276  void invalidate();
277 
279  const T& element() const;
280 
281  // As a Proxy.
282  const T& subj_();
283 
285  unsigned index_() const;
286 
287  protected:
288  unsigned i_;
289  const set<T>* s_;
290  };
291 
292 
293 
294 
295  // set_bkd_iter<T>
296 
297  template <typename T>
298  class set_bkd_iter : public Proxy< set_bkd_iter<T> >,
299  public mln::internal::proxy_impl< const T&, set_bkd_iter<T> >
300  {
301  public:
302 
304  set_bkd_iter();
305 
307  set_bkd_iter(const set<T>& s);
308 
310  void change_target(const set<T>& s);
311 
313  void start();
314 
316  void next();
317 
319  bool is_valid() const;
320 
322  void invalidate();
323 
325  const T& element() const;
326 
327  // As a Proxy.
328  const T& subj_();
329 
331  unsigned index_() const;
332 
333  protected:
334  unsigned i_;
335  const set<T>* s_;
336  };
337 
338 
339 
340 # ifndef MLN_INCLUDE_ONLY
341 
342 
343  // util::set<T>
344 
345 
346  template <typename T>
347  inline
348  set<T>::set()
349  {
350  frozen_ = false;
351  }
352 
353  template <typename T>
354  inline
355  set<T>&
356  set<T>::insert(const T& elt)
357  {
358  if (frozen_) unfreeze_();
359  s_.insert(elt);
360  return *this;
361  }
362 
363  template <typename T>
364  template <typename U>
365  inline
366  set<T>&
367  set<T>::insert(const set<U>& other)
368  {
369  if (other.is_empty())
370  // No-op.
371  return *this;
372  if (frozen_) unfreeze_();
373  s_.insert(other.std_vector().begin(), other.std_vector().end());
374  return *this;
375  }
376 
377  template <typename T>
378  inline
379  set<T>&
380  set<T>::remove(const T& elt)
381  {
382  if (frozen_) unfreeze_();
383  s_.erase(elt);
384  return *this;
385  }
386 
387  template <typename T>
388  inline
389  void
390  set<T>::clear()
391  {
392  if (frozen_)
393  {
394  mln_invariant(s_.empty());
395  v_.clear();
396  frozen_ = false;
397  }
398  else
399  {
400  mln_invariant(v_.empty());
401  s_.clear();
402  }
403  mln_postcondition(is_empty());
404  }
405 
406  template <typename T>
407  inline
408  unsigned
409  set<T>::nelements() const
410  {
411  return frozen_ ? v_.size() : s_.size();
412  }
413 
414  template <typename T>
415  inline
416  const T&
417  set<T>::operator[](unsigned i) const
418  {
419  mln_precondition(i < nelements());
420  if (! frozen_) freeze_();
421  return v_[i];
422  }
423 
424  template <typename T>
425  inline
426  const T
427  set<T>::first_element() const
428  {
429  mln_precondition(! is_empty());
430  return frozen_ ? *v_.begin() : *s_.begin();
431  }
432 
433  template <typename T>
434  inline
435  const T
436  set<T>::last_element() const
437  {
438  mln_precondition(! is_empty());
439  return frozen_ ? *v_.rbegin() : *s_.rbegin();
440  }
441 
442  template <typename T>
443  inline
444  bool
445  set<T>::has(const T& elt) const
446  {
447  return frozen_ ? v_has_(elt) : s_.find(elt) != s_.end();
448  }
449 
450  template <typename T>
451  inline
452  bool
453  set<T>::is_empty() const
454  {
455  return nelements() == 0;
456  }
457 
458  template <typename T>
459  inline
460  const std::vector<T>&
461  set<T>::std_vector() const
462  {
463  if (! frozen_) freeze_();
464  return v_;
465  }
466 
467  template <typename T>
468  inline
469  void
470  set<T>::freeze_() const
471  {
472  mln_precondition(frozen_ == false);
473  mln_invariant(v_.empty());
474  std::copy(s_.begin(), s_.end(), std::back_inserter(v_));
475  s_.clear();
476  frozen_ = true;
477  }
478 
479  template <typename T>
480  inline
481  void
482  set<T>::unfreeze_() const
483  {
484  mln_precondition(frozen_ == true);
485  mln_invariant(s_.empty());
486  s_.insert(v_.begin(), v_.end());
487  v_.clear();
488  frozen_ = false;
489  }
490 
491  template <typename T>
492  inline
493  std::size_t
494  set<T>::memory_size() const
495  {
496  return nelements() * sizeof(T);
497  }
498 
499  template <typename T>
500  inline
501  bool
502  set<T>::is_frozen_() const
503  {
504  return frozen_;
505  }
506 
507  template <typename T>
508  inline
509  bool
510  set<T>::v_has_(const T& elt) const
511  {
512  mln_precondition(frozen_);
513  if (is_empty() ||
514  util::ord_strict(elt, v_[0]) ||
515  util::ord_strict(v_[nelements() - 1], elt))
516  return false;
517  return v_[dicho_(elt, 0, nelements())] == elt;
518  }
519 
520  template <typename T>
521  inline
522  unsigned
523  set<T>::dicho_(const T& elt, unsigned beg, unsigned end) const
524  {
525  mln_precondition(frozen_);
526  mln_precondition(beg <= end);
527  if (end - beg <= 1)
528  return beg;
529  unsigned med = (beg + end) / 2;
530  return util::ord_strict(elt, v_[med])
531  ? dicho_(elt, beg, med)
532  : dicho_(elt, med, end);
533  }
534 
535 
536 
537  // util::set_fwd_iter<T>
538 
539 
540  template <typename T>
541  inline
543  {
544  s_ = 0;
545  }
546 
547  template <typename T>
548  inline
549  set_fwd_iter<T>::set_fwd_iter(const set<T>& s)
550  {
551  change_target(s);
552  }
553 
554  template <typename T>
555  inline
556  void
557  set_fwd_iter<T>::change_target(const set<T>& s)
558  {
559  s_ = &s;
560  invalidate();
561  }
562 
563  template <typename T>
564  inline
565  void
567  {
568  mln_precondition(s_ != 0);
569  i_ = 0;
570  }
571 
572  template <typename T>
573  inline
574  void
576  {
577  mln_precondition(is_valid());
578  ++i_;
579  }
580 
581  template <typename T>
582  inline
583  bool
585  {
586  return s_ != 0 && i_ != s_->nelements();
587  }
588 
589  template <typename T>
590  inline
591  void
593  {
594  if (s_ != 0)
595  i_ = s_->nelements();
596  mln_postcondition(! is_valid());
597  }
598 
599  template <typename T>
600  inline
601  const T&
603  {
604  mln_precondition(is_valid());
605  return s_->operator[](i_);
606  }
607 
608  template <typename T>
609  inline
610  const T&
612  {
613  mln_precondition(is_valid());
614  return s_->operator[](i_);
615  }
616 
617  template <typename T>
618  inline
619  unsigned
621  {
622  return i_;
623  }
624 
625 
626 
627  // util::set_bkd_iter<T>
628 
629 
630  template <typename T>
631  inline
633  {
634  s_ = 0;
635  }
636 
637  template <typename T>
638  inline
639  set_bkd_iter<T>::set_bkd_iter(const set<T>& s)
640  {
641  change_target(s);
642  }
643 
644  template <typename T>
645  inline
646  void
647  set_bkd_iter<T>::change_target(const set<T>& s)
648  {
649  s_ = &s;
650  invalidate();
651  }
652 
653  template <typename T>
654  inline
655  void
657  {
658  mln_precondition(s_ != 0);
659  if (! s_->is_empty())
660  i_ = s_->nelements() - 1;
661  }
662 
663  template <typename T>
664  inline
665  void
667  {
668  mln_precondition(is_valid());
669  if (i_ == 0)
670  invalidate();
671  else
672  --i_;
673  }
674 
675  template <typename T>
676  inline
677  bool
679  {
680  return s_ != 0 && i_ != s_->nelements();
681  }
682 
683  template <typename T>
684  inline
685  void
687  {
688  if (s_ != 0)
689  i_ = s_->nelements();
690  mln_postcondition(! is_valid());
691  }
692 
693  template <typename T>
694  inline
695  const T&
697  {
698  mln_precondition(is_valid());
699  return s_->operator[](i_);
700  }
701 
702  template <typename T>
703  inline
704  const T&
706  {
707  mln_precondition(is_valid());
708  return s_->operator[](i_);
709  }
710 
711  template <typename T>
712  inline
713  unsigned
715  {
716  return i_;
717  }
718 
719 
720 
721  // Operators.
722 
723  template <typename T>
724  std::ostream& operator<<(std::ostream& ostr,
725  const mln::util::set<T>& s)
726  {
727  ostr << '{';
728  const unsigned n = s.nelements();
729  for (unsigned i = 0; i < n; ++i)
730  {
731  ostr << s[i];
732  if (i != n - 1)
733  ostr << ", ";
734  }
735  ostr << '}';
736  return ostr;
737  }
738 
739  template <typename T>
740  bool operator == (const set<T>& lhs, const set<T>& rhs)
741  {
742  const unsigned n = lhs.nelements();
743  if (rhs.nelements() != n)
744  return false;
745  for (unsigned i = 0; i < n; ++i)
746  if (lhs[i] != rhs[i])
747  return false;
748  return true;
749  }
750 
751  template <typename T>
752  bool operator < (const set<T>& lhs, const set<T>& rhs)
753  {
754  return lhs.nelements() < rhs.nelements() && lhs <= rhs;
755  }
756 
757  template <typename T>
758  bool operator <= (const set<T>& lhs, const set<T>& rhs)
759  {
760  const unsigned
761  nl = lhs.nelements(),
762  nr = rhs.nelements();
763  if (nl > nr)
764  return false;
765  // Every element of lhs can be found in rhs.
766  for (unsigned l = 0, r = 0; l < nl; ++l, ++r)
767  {
768  while (rhs[r] != lhs[l] && r < nr)
769  ++r;
770  if (r == nr)
771  return false; // lhs[l] has not been found in rhs.
772  }
773  return true;
774  }
775 
776 # endif // ! MLN_INCLUDE_ONLY
777 
778  } // end of namespace mln::util
779 
780 } // end of namespace mln
781 
782 
783 #endif // ! MLN_UTIL_SET_HH