Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
set_of.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_INTERNAL_SET_OF_HH
27 # define MLN_CORE_INTERNAL_SET_OF_HH
28 
32 
33 # include <vector>
34 # include <set>
35 # include <iterator>
36 # include <algorithm>
37 
38 # include <mln/core/contract.hh>
39 # include <mln/core/internal/force_exact.hh>
40 
41 
42 namespace mln
43 {
44 
45  namespace internal
46  {
47 
58  template <typename E>
59  class set_of_
60  {
61  public:
62 
63 
72  set_of_<E>& insert(const E& elt);
73 
74 
83  set_of_<E>& remove(const E& elt);
84 
85 
94  const E& element(unsigned i) const;
95 
96 
99  unsigned nelements() const;
100 
101 
108  bool has(const E& elt) const;
109 
110 
113  bool is_empty() const;
114 
115 
123  void clear();
124 
125 
132  const std::vector<E>& vect() const;
133 
134  protected:
135 
137  set_of_();
138 
139  private:
140 
146  mutable std::vector<E> v_;
147 
148  protected:
153  std::set<E> s_;
154 
155  private:
160  void update_() const;
161 
163  mutable bool needs_update_;
164  };
165 
166 
177  // FIXME : ambiguous with site_set operator <<
178  // template <typename E>
179  // std::ostream& operator<<(std::ostream& ostr, const set_of_<E>& s);
180 
181 
182 
183 # ifndef MLN_INCLUDE_ONLY
184 
185  template <typename E>
186  inline
187  set_of_<E>::set_of_()
188  {
189  needs_update_ = false;
190  }
191 
192  template <typename E>
193  inline
194  set_of_<E>&
195  set_of_<E>::insert(const E& elt)
196  {
197  s_.insert(elt);
198  if (needs_update_ == false)
199  needs_update_ = true;
200  return internal::force_exact< set_of_<E> >(*this);
201  }
202 
203  template <typename E>
204  inline
205  set_of_<E>&
206  set_of_<E>::remove(const E& elt)
207  {
208  s_.erase(elt);
209  if (needs_update_ == false)
210  needs_update_ = true;
211  return internal::force_exact< set_of_<E> >(*this);
212  }
213 
214  template <typename E>
215  inline
216  const E&
217  set_of_<E>::element(unsigned i) const
218  {
219  if (needs_update_)
220  update_();
221  mln_precondition(i < v_.size());
222  return v_[i];
223  }
224 
225  template <typename E>
226  inline
227  unsigned
228  set_of_<E>::nelements() const
229  {
230  if (needs_update_)
231  update_();
232  return v_.size();
233  }
234 
235  template <typename E>
236  inline
237  bool
238  set_of_<E>::has(const E& elt) const
239  {
240  return s_.find(elt) != s_.end();
241  }
242 
243  template <typename E>
244  inline
245  bool
246  set_of_<E>::is_empty() const
247  {
248  return nelements() == 0;
249  }
250 
251  template <typename E>
252  inline
253  void
254  set_of_<E>::clear()
255  {
256  v_.clear();
257  s_.clear();
258  needs_update_ = false;
259  mln_postcondition(is_empty());
260  }
261 
262  template <typename E>
263  inline
264  const std::vector<E>&
265  set_of_<E>::vect() const
266  {
267  if (needs_update_)
268  update_();
269  return v_;
270  }
271 
272  template <typename E>
273  inline
274  void
275  set_of_<E>::update_() const
276  {
277  mln_precondition(needs_update_);
278  v_.clear();
279  std::copy(s_.begin(), s_.end(), std::back_inserter(v_));
280  // no s_.clear() here:
281  // - we want to keep information up-to-date in s_
282  // - we want to save some execution time
283  needs_update_ = false;
284  }
285 
286  // FIXME : ambiguous with site_set operator <<
287  // template <typename E>
288  // std::ostream& operator<<(std::ostream& ostr,
289  // const set_of_<E>& s)
290  // {
291  // ostr << '[';
292  // const unsigned n = s.nelements();
293  // for (unsigned i = 0; i < n; ++i)
294  // ostr << s.element(i)
295  // << (i == s.nelements() - 1 ? ']' : ',');
296  // return ostr;
297  // }
298 
299 # endif // ! MLN_INCLUDE_ONLY
300 
301  } // end of namespace mln::internal
302 
303 } // end of namespace mln
304 
305 
306 #endif // ! MLN_CORE_INTERNAL_SET_OF_HH