ARGoS  3
A parallel, multi-engine simulator for swarm robotics
set.h
Go to the documentation of this file.
1 
7 #ifndef SET_H
8 #define SET_H
9 
10 #include <cstddef>
11 #include <iterator>
12 
13 namespace argos {
14 
19  template <class T>
20  struct SSetElement {
21  T Data;
24 
25  SSetElement(const T& t_data,
26  SSetElement* ps_prev = NULL,
27  SSetElement* ps_next = NULL) :
28  Data(t_data),
29  Previous(ps_prev),
30  Next(ps_next) {}
31  };
32 
38  template<class CONTAINED_TYPE, class REFERENCED_TYPE>
39  class CSetIterator {
40 
41  public:
42 
43  typedef std::forward_iterator_tag iterator_category;
44  typedef REFERENCED_TYPE value_type;
45  typedef std::ptrdiff_t difference_type;
46  typedef REFERENCED_TYPE& reference;
47  typedef REFERENCED_TYPE* pointer;
48 
49  public:
50 
52  m_psElem(ps_elem) {}
53 
54  CSetIterator(const CSetIterator& c_it) :
55  m_psElem(c_it.m_psElem) {}
56 
58  if(this != &c_it) {
59  m_psElem = c_it.m_psElem;
60  }
61  return *this;
62  }
63 
65  return m_psElem->Data;
66  }
67 
69  return &(m_psElem->Data);
70  }
71 
74  return *this;
75  }
76 
77  bool operator==(const CSetIterator& c_it) {
78  return (m_psElem == c_it.m_psElem);
79  }
80 
81  bool operator!=(const CSetIterator& c_it) {
82  return (m_psElem != c_it.m_psElem);
83  }
84 
86 
87  };
88 
99  template <class T>
100  class CSet {
101 
102  public:
103 
105 
106  class const_iterator : public CSetIterator<T, const T> {
107  public:
108  const_iterator(const iterator& c_it) : CSetIterator<T, const T>(c_it.m_psElem) {}
111  return *this;
112  }
113  bool operator==(const iterator& c_it) { return (CSetIterator<T, const T>::m_psElem == c_it.m_psElem); }
114  bool operator!=(const iterator& c_it) { return (CSetIterator<T, const T>::m_psElem != c_it.m_psElem); }
115  };
116 
117  public:
118 
123  CSet() :
124  m_psFirst(NULL),
125  m_psLast(NULL),
126  m_unSize(0) {}
127 
133  CSet(const CSet& c_set) :
134  m_psFirst(NULL),
135  m_psLast(NULL),
136  m_unSize(0) {
137  *this = c_set;
138  }
139 
143  ~CSet() {
144  clear();
145  }
146 
152  CSet& operator=(const CSet& c_set) {
153  /* Is the passed set a different set? */
154  if(this != &c_set) {
155  /* Yes, copy from it */
156  /* First, erase this set's contents */
157  clear();
158  /* Is the other set empty? */
159  if(! c_set.empty()) {
160  /* Not empty, there's at least one element to copy */
161  /* Start by copying the size of the other set into this one */
162  m_unSize = c_set.m_unSize;
163  /* Create the first element */
164  m_psFirst = new SSetElement<T>(c_set.m_psFirst->Data);
165  /* Is the size of the other set 1? */
166  if(m_unSize == 1) {
167  /* Yes, the first element is also the last one */
168  m_psLast = m_psFirst;
169  }
170  else {
171  /* There's more than just one element */
172  /* Copy all the elements starting from the second */
173  /* Current element on other set to be copied */
174  SSetElement<T>* psCurElemOnOther = c_set.m_psFirst->Next;
175  /* Last copied element on this set */
176  SSetElement<T>* psLastElemOnThis = m_psFirst;
177  /* Current element on this set being created */
178  SSetElement<T>* psCurElemOnThis = NULL;
179  /* Go on until we hit the end of the list on the other set */
180  while(psCurElemOnOther != NULL) {
181  /* Create a new element for this set, setting as previous psLastElemOnThis */
182  psCurElemOnThis = new SSetElement<T>(psCurElemOnOther->Data, psLastElemOnThis);
183  /* Set the next of psLastElemOnThis to the element just created */
184  psLastElemOnThis->Next = psCurElemOnThis;
185  /* Advance with the last element on this */
186  psLastElemOnThis = psCurElemOnThis;
187  /* Advance with the element to copy on the other set */
188  psCurElemOnOther = psCurElemOnOther->Next;
189  }
190  /* At this point, psCurElemOnThis corresponds to the last element of the list */
191  m_psLast = psCurElemOnThis;
192  }
193  }
194  }
195  return *this;
196  }
197 
202  inline bool empty() const {
203  return m_unSize == 0;
204  }
205 
210  inline size_t size() const {
211  return m_unSize;
212  }
213 
214  inline T& first() {
215  return m_psFirst->Data;
216  }
217 
218  inline const T& first() const {
219  return m_psFirst->Data;
220  }
221 
222  inline T& last() {
223  return m_psLast->Data;
224  }
225 
226  inline const T& last() const {
227  return m_psLast->Data;
228  }
229 
235  void insert(const T& t_element) {
236  /* Is the list empty? */
237  if(m_unSize == 0) {
238  /* Yes, the first and last element coincide */
239  m_psFirst = new SSetElement<T>(t_element);
240  m_psLast = m_psFirst;
241  m_unSize = 1;
242  }
243  else {
244  /* No, we have at least 1 element */
245  /* Search for the element in the list that will be the next
246  of the element to add */
247  SSetElement<T>* psNextElem = m_psFirst;
248  while(psNextElem != NULL &&
249  psNextElem->Data < t_element) {
250  psNextElem = psNextElem->Next;
251  }
252  /* Did we get to the end of the list? */
253  if(psNextElem == NULL) {
254  /* Yes, add the new element after the last one */
255  SSetElement<T>* psNewElem = new SSetElement<T>(t_element, m_psLast);
256  m_psLast->Next = psNewElem;
257  m_psLast = psNewElem;
258  ++m_unSize;
259  return;
260  }
261  /* Is the element already present? */
262  if(psNextElem->Data == t_element) {
263  /* Yes, nothing to add */
264  return;
265  }
266  /* Is the next element the first in the list? */
267  if(psNextElem == m_psFirst) {
268  /* Yes, we must add the new element as the new first */
269  SSetElement<T>* psNewElem = new SSetElement<T>(t_element, NULL, m_psFirst);
270  m_psFirst->Previous = psNewElem;
271  m_psFirst = psNewElem;
272  ++m_unSize;
273  return;
274  }
275  /* If we get here, it's because we have to add the new element in the middle */
276  SSetElement<T>* psNewElem = new SSetElement<T>(t_element, psNextElem->Previous, psNextElem);
277  psNextElem->Previous->Next = psNewElem;
278  psNextElem->Previous = psNewElem;
279  ++m_unSize;
280  }
281  }
282 
287  void erase(const T& t_element) {
288  /* Is the list empty? */
289  if(m_unSize == 0) {
290  /* Yes, nothing to do */
291  return;
292  }
293  /* Is the list composed of a single element? */
294  if(m_unSize == 1) {
295  /* Is that the element we want to eliminate? */
296  if(m_psFirst->Data == t_element) {
297  /* Yes, erase it! */
298  delete m_psFirst;
299  m_psFirst = NULL;
300  m_psLast = NULL;
301  m_unSize = 0;
302  }
303  return;
304  }
305  /* If we get here, it's because the trivial cases
306  don't apply */
307  /* Look for the passed element */
308  SSetElement<T>* psElem = find_impl(t_element);
309  /* Did we find it? */
310  if(psElem != NULL) {
311  /* Yes, let's erase it */
312  /* Are we removing the first element? */
313  if(psElem == m_psFirst) {
314  /* Yes, we need to update m_psFirst */
315  m_psFirst = m_psFirst->Next;
316  m_psFirst->Previous = NULL;
317  delete psElem;
318  --m_unSize;
319  return;
320  }
321  /* Are we removing the last element? */
322  if(psElem == m_psLast) {
323  /* Yes, we need to update m_psLast */
324  m_psLast = m_psLast->Previous;
325  m_psLast->Next = NULL;
326  delete psElem;
327  --m_unSize;
328  return;
329  }
330  /* If we get here, it's because we need to remove
331  an element in the middle */
332  psElem->Previous->Next = psElem->Next;
333  psElem->Next->Previous = psElem->Previous;
334  delete psElem;
335  --m_unSize;
336  }
337  }
338 
343  inline void erase(iterator& c_it) {
344  erase(*c_it);
345  }
346 
350  void clear() {
351  if(m_unSize == 0) {
352  return;
353  }
354  if(m_unSize == 1) {
355  delete m_psFirst;
356  m_psFirst = NULL;
357  m_psLast = NULL;
358  m_unSize = 0;
359  return;
360  }
361  SSetElement<T>* psCurElem = m_psFirst;
362  SSetElement<T>* psNextElem = psCurElem->Next;
363  while(psCurElem != NULL) {
364  delete psCurElem;
365  psCurElem = psNextElem;
366  if(psCurElem != NULL) {
367  psNextElem = psNextElem->Next;
368  }
369  }
370  m_psFirst = NULL;
371  m_psLast = NULL;
372  m_unSize = 0;
373  }
374 
380  inline bool exists(const T& t_element) {
381  return find_impl(t_element) != NULL;
382  }
383 
388  inline iterator begin() const {
389  return iterator(m_psFirst);
390  }
391 
396  inline iterator end() const {
397  return iterator();
398  }
399 
404  inline iterator find(const T& t_element) {
405  return iterator(find_impl(t_element));
406  }
407 
408  private:
409 
410  SSetElement<T>* find_impl(const T& t_element) const {
411  if(m_psFirst == NULL) {
412  return NULL;
413  }
414  SSetElement<T>* psElem = m_psFirst;
415  while(psElem != NULL &&
416  psElem->Data < t_element) {
417  psElem = psElem->Next;
418  }
419  if(psElem == NULL) {
420  return NULL;
421  }
422  else {
423  return (psElem->Data == t_element) ? psElem : NULL;
424  }
425  }
426 
427  private:
428 
429  SSetElement<T>* m_psFirst;
430  SSetElement<T>* m_psLast;
431  size_t m_unSize;
432 
433  };
434 
435 }
436 
437 #endif
argos::CSetIterator::operator==
bool operator==(const CSetIterator &c_it)
Definition: set.h:77
argos::CSetIterator::pointer
REFERENCED_TYPE * pointer
Definition: set.h:47
argos::CSetIterator::m_psElem
SSetElement< CONTAINED_TYPE > * m_psElem
Definition: set.h:85
argos::CSetIterator::reference
REFERENCED_TYPE & reference
Definition: set.h:46
argos
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
argos::SSetElement
The data container of CSet.
Definition: set.h:20
argos::CSet::last
T & last()
Definition: set.h:222
argos::CSet::erase
void erase(iterator &c_it)
Removes the passed element from the list.
Definition: set.h:343
argos::CSet::size
size_t size() const
Returns the number of elements in the list.
Definition: set.h:210
argos::CSet::const_iterator::operator=
const_iterator & operator=(const iterator &c_it)
Definition: set.h:109
argos::CSet::erase
void erase(const T &t_element)
Removes the passed element from the list.
Definition: set.h:287
argos::CSet::clear
void clear()
Erases the contents of the list.
Definition: set.h:350
argos::CSet::CSet
CSet(const CSet &c_set)
Class copy constructor.
Definition: set.h:133
argos::CSet::exists
bool exists(const T &t_element)
Returns true if the given element is in the list.
Definition: set.h:380
argos::SSetElement::Next
SSetElement * Next
Definition: set.h:23
argos::CSet::const_iterator
Definition: set.h:106
argos::CSet::end
iterator end() const
Returns an invalid iterator.
Definition: set.h:396
argos::CSetIterator::operator=
CSetIterator & operator=(const CSetIterator &c_it)
Definition: set.h:57
argos::CSet::last
const T & last() const
Definition: set.h:226
argos::CSet::~CSet
~CSet()
Class destructor.
Definition: set.h:143
argos::CSetIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: set.h:43
argos::CSetIterator
The CSet iterator.
Definition: set.h:39
argos::SSetElement::Data
T Data
Definition: set.h:21
argos::CSetIterator::operator!=
bool operator!=(const CSetIterator &c_it)
Definition: set.h:81
argos::CSetIterator::operator*
reference operator*()
Definition: set.h:64
argos::CSet::find
iterator find(const T &t_element)
Searches for an element in the list.
Definition: set.h:404
argos::CSet::insert
void insert(const T &t_element)
Inserts an element to the list.
Definition: set.h:235
argos::SSetElement::Previous
SSetElement * Previous
Definition: set.h:22
argos::CSet::empty
bool empty() const
Returns true if the list is empty.
Definition: set.h:202
argos::CSet::first
const T & first() const
Definition: set.h:218
argos::CSet::iterator
CSetIterator< T, T > iterator
Definition: set.h:104
argos::CSet::first
T & first()
Definition: set.h:214
argos::CSetIterator::difference_type
std::ptrdiff_t difference_type
Definition: set.h:45
argos::CSet::begin
iterator begin() const
Returns an iterator to the first element.
Definition: set.h:388
argos::CSet::CSet
CSet()
Class constructor.
Definition: set.h:123
argos::CSetIterator::value_type
REFERENCED_TYPE value_type
Definition: set.h:44
argos::CSet::const_iterator::const_iterator
const_iterator(const iterator &c_it)
Definition: set.h:108
argos::CSetIterator::operator++
CSetIterator & operator++()
Definition: set.h:72
argos::CSet::const_iterator::operator==
bool operator==(const iterator &c_it)
Definition: set.h:113
argos::CSet::const_iterator::operator!=
bool operator!=(const iterator &c_it)
Definition: set.h:114
argos::SSetElement::SSetElement
SSetElement(const T &t_data, SSetElement *ps_prev=NULL, SSetElement *ps_next=NULL)
Definition: set.h:25
argos::CSetIterator::CSetIterator
CSetIterator(const CSetIterator &c_it)
Definition: set.h:54
argos::CSet::operator=
CSet & operator=(const CSet &c_set)
Assignment operator.
Definition: set.h:152
argos::CSet
Defines a very simple double-linked list that stores unique elements.
Definition: set.h:100
argos::CSetIterator::CSetIterator
CSetIterator(SSetElement< CONTAINED_TYPE > *ps_elem=NULL)
Definition: set.h:51
argos::CSetIterator::operator->
pointer operator->()
Definition: set.h:68