$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lazy_set.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_UTIL_LAZY_SET_HH
27 # define MLN_UTIL_LAZY_SET_HH
28 
34 # include <vector>
35 # include <set>
36 # include <iterator>
37 # include <algorithm>
38 
39 # include <mln/core/internal/force_exact.hh>
40 # include <mln/core/contract.hh>
41 
42 
43 namespace mln
44 {
45 
46  namespace util
47  {
48 
65  template <typename E>
66  class lazy_set_
67  {
68  public:
69 
71  typedef E value;
72 
81  lazy_set_<E>& insert(const E& elt);
82 
83 
92  lazy_set_<E>& remove(const E& elt);
93 
94 
103  const E& element(unsigned i) const;
104 
113  const E& operator[](unsigned i) const;
114 
117  unsigned nelements() const;
118 
119 
126  bool has(const E& elt) const;
127 
128 
131  bool is_empty() const;
132 
133 
143  void clear();
144 
145 
152  const std::vector<E>& vect() const;
153 
155  lazy_set_();
156 
167  void set_const_mode(bool mode);
168 
170  bool get_mode() const;
171 
172  private:
173 
179  mutable std::vector<E> v_;
180 
185  std::set<E> s_;
186 
187 
192  void update_() const;
193 
195  mutable bool needs_update_;
196 
198  bool mode_;
199  };
200 
201 
202 # ifndef MLN_INCLUDE_ONLY
203 
204  template <typename E>
205  inline
207  {
208  needs_update_ = false;
209  mode_ = false;
210  }
211 
212  template <typename E>
213  inline
214  lazy_set_<E>&
215  lazy_set_<E>::insert(const E& elt)
216  {
217  mln_assertion(!mode_);
218  s_.insert(elt);
219  if (needs_update_ == false)
220  needs_update_ = true;
221  return mln::internal::force_exact< lazy_set_<E> >(*this);
222  }
223 
224  template <typename E>
225  inline
226  lazy_set_<E>&
227  lazy_set_<E>::remove(const E& elt)
228  {
229  mln_assertion(!mode_);
230  // FIXME : doesn't compile
231  std::remove(s_.begin(), s_.end(), elt);
232  if (needs_update_ == false)
233  needs_update_ = true;
234  return mln::internal::force_exact< lazy_set_<E> >(*this);
235  }
236 
237  template <typename E>
238  inline
239  const E&
240  lazy_set_<E>::element(unsigned i) const
241  {
242  assert((!mode_ && i < s_.size())
243  || i < v_.size());
244  if (!mode_)
245  if (needs_update_)
246  update_();
247  return v_[i];
248  }
249 
250  template <typename E>
251  inline
252  const E&
253  lazy_set_<E>::operator[](unsigned i) const
254  {
255  return this->element(i);
256  }
257 
258  template <typename E>
259  inline
260  unsigned
262  {
263  if (!mode_)
264  return s_.size();
265  else
266  return v_.size();
267  }
268 
269  template <typename E>
270  inline
271  bool
272  lazy_set_<E>::has(const E& elt) const
273  {
274  if (!mode_)
275  return s_.find(elt) != s_.end();
276  else
277  return v_.find(elt) != v_.end();
278  }
279 
280  template <typename E>
281  inline
282  bool
283  lazy_set_<E>::is_empty() const
284  {
285  return nelements() == 0;
286  }
287 
288  template <typename E>
289  inline
290  void
292  {
293  v_.clear();
294  s_.clear();
295  needs_update_ = false;
296  mode_ = false;
297  mln_postcondition(is_empty());
298  }
299 
300  template <typename E>
301  inline
302  const std::vector<E>&
303  lazy_set_<E>::vect() const
304  {
305  if (!mode_)
306  if (needs_update_)
307  update_();
308  return v_;
309  }
310 
311  template <typename E>
312  inline
313  void
315  {
316  if (mode != mode_)
317  {
318  if (mode)
319  {
320  if (needs_update_)
321  update_();
322  s_.clear();
323  }
324  else
325  {
326  mln_assertion(s_.size() == 0);
327  for (typename std::vector<E>::iterator it = v_.begin();
328  it != v_.end(); it++)
329  s_.insert(*it);
330  needs_update_ = false;
331  }
332  mode_ = mode;
333  }
334  }
335 
336  template <typename E>
337  inline
338  bool
339  lazy_set_<E>::get_mode() const
340  {
341  return mode_;
342  }
343 
344  template <typename E>
345  inline
346  void
347  lazy_set_<E>::update_() const
348  {
349  mln_precondition(needs_update_ && !mode_);
350  v_.clear();
351  std::copy(s_.begin(), s_.end(), std::back_inserter(v_));
352  // no s_.clear() here:
353  // - we want to keep information up-to-date in s_
354  // - we want to save some execution time
355  needs_update_ = false;
356  }
357 
358  // FIXME : ambiguous with site_set operator <<
359  // template <typename E>
360  // std::ostream& operator<<(std::ostream& ostr,
361  // const lazy_set_<E>& s)
362  // {
363  // ostr << '[';
364  // const unsigned n = s.nelements();
365  // for (unsigned i = 0; i < n; ++i)
366  // ostr << s.element(i)
367  // << (i == s.nelements() - 1 ? ']' : ',');
368  // return ostr;
369  // }
370 
371 # endif // ! MLN_INCLUDE_ONLY
372 
373  } // end of namespace mln::util
374 
375 } // end of namespace mln
376 
377 
378 #endif // ! MLN_UTIL_LAZY_SET_HH