AERA
list.h
1 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 //_/_/
3 //_/_/ AERA
4 //_/_/ Autocatalytic Endogenous Reflective Architecture
5 //_/_/
6 //_/_/ Copyright (c) 2018-2023 Jeff Thompson
7 //_/_/ Copyright (c) 2018-2023 Kristinn R. Thorisson
8 //_/_/ Copyright (c) 2018-2023 Icelandic Institute for Intelligent Machines
9 //_/_/ http://www.iiim.is
10 //_/_/
11 //_/_/ Copyright (c) 2010-2012 Eric Nivel
12 //_/_/ Center for Analysis and Design of Intelligent Agents
13 //_/_/ Reykjavik University, Menntavegur 1, 102 Reykjavik, Iceland
14 //_/_/ http://cadia.ru.is
15 //_/_/
16 //_/_/ Part of this software was developed by Eric Nivel
17 //_/_/ in the HUMANOBS EU research project, which included
18 //_/_/ the following parties:
19 //_/_/
20 //_/_/ Autonomous Systems Laboratory
21 //_/_/ Technical University of Madrid, Spain
22 //_/_/ http://www.aslab.org/
23 //_/_/
24 //_/_/ Communicative Machines
25 //_/_/ Edinburgh, United Kingdom
26 //_/_/ http://www.cmlabs.com/
27 //_/_/
28 //_/_/ Istituto Dalle Molle di Studi sull'Intelligenza Artificiale
29 //_/_/ University of Lugano and SUPSI, Switzerland
30 //_/_/ http://www.idsia.ch/
31 //_/_/
32 //_/_/ Institute of Cognitive Sciences and Technologies
33 //_/_/ Consiglio Nazionale delle Ricerche, Italy
34 //_/_/ http://www.istc.cnr.it/
35 //_/_/
36 //_/_/ Dipartimento di Ingegneria Informatica
37 //_/_/ University of Palermo, Italy
38 //_/_/ http://diid.unipa.it/roboticslab/
39 //_/_/
40 //_/_/
41 //_/_/ --- HUMANOBS Open-Source BSD License, with CADIA Clause v 1.0 ---
42 //_/_/
43 //_/_/ Redistribution and use in source and binary forms, with or without
44 //_/_/ modification, is permitted provided that the following conditions
45 //_/_/ are met:
46 //_/_/ - Redistributions of source code must retain the above copyright
47 //_/_/ and collaboration notice, this list of conditions and the
48 //_/_/ following disclaimer.
49 //_/_/ - Redistributions in binary form must reproduce the above copyright
50 //_/_/ notice, this list of conditions and the following disclaimer
51 //_/_/ in the documentation and/or other materials provided with
52 //_/_/ the distribution.
53 //_/_/
54 //_/_/ - Neither the name of its copyright holders nor the names of its
55 //_/_/ contributors may be used to endorse or promote products
56 //_/_/ derived from this software without specific prior
57 //_/_/ written permission.
58 //_/_/
59 //_/_/ - CADIA Clause: The license granted in and to the software
60 //_/_/ under this agreement is a limited-use license.
61 //_/_/ The software may not be used in furtherance of:
62 //_/_/ (i) intentionally causing bodily injury or severe emotional
63 //_/_/ distress to any person;
64 //_/_/ (ii) invading the personal privacy or violating the human
65 //_/_/ rights of any person; or
66 //_/_/ (iii) committing or preparing for any act of war.
67 //_/_/
68 //_/_/ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
69 //_/_/ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
70 //_/_/ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
71 //_/_/ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 //_/_/ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
73 //_/_/ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74 //_/_/ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
75 //_/_/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
76 //_/_/ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77 //_/_/ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
78 //_/_/ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
79 //_/_/ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 //_/_/ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
81 //_/_/ OF SUCH DAMAGE.
82 //_/_/
83 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
84 
85 #ifndef r_code_list_h
86 #define r_code_list_h
87 
88 #include <vector>
89 #include "../submodules/CoreLibrary/CoreLibrary/types.h"
90 
91 
92 using namespace core;
93 
94 namespace r_code {
95 
96 // Minimalist list implemented as a vector.
97 // Possible optimization: get rid of the std::vector and manage allocation oneself.
98 // Insertion not needed for now; not implemented.
99 template<typename T> class list {
100 protected:
101  static const int32 null_ = -1;
102 
103  class cell { // int32: to be robust WRT realloc(); this means that Ts can hold a cell index to speed up erasure.
104  public:
105  int32 next_;
106  int32 prev_;
107  T data_;
108  cell() : next_(null_), prev_(null_) {}
109  };
110 
111  std::vector<cell> cells_;
112 
113  int32 used_cells_head_;
114  int32 used_cells_tail_;
115  int32 free_cells_; // backward links unused.
116  uint32 used_cell_count_;
117  uint32 free_cell_count_;
118 
119  void push_back_free_cell(const T &t) {
120 
121  int32 free = free_cells_;
122  free_cells_ = cells_[free_cells_].next_;
123  --free_cell_count_;
124  cells_[free].data_ = t;
125  cells_[free].next_ = null_;
126  cells_[free].prev_ = used_cells_tail_;
127  used_cells_tail_ = free;
128  }
129 
130  void push_back_new_cell(const T &t) {
131 
132  cell c;
133  c.data_ = t;
134  c.next_ = null_;
135  c.prev_ = used_cells_tail_;
136  cells_.push_back(c);
137  used_cells_tail_ = cells_.size() - 1;
138  }
139 
140  void update_used_cells_tail_state() {
141 
142  if (cells_[used_cells_tail_].prev_ != null_)
143  cells_[cells_[used_cells_tail_].prev_].next_ = used_cells_tail_;
144  if (used_cells_head_ == null_)
145  used_cells_head_ = used_cells_tail_;
146  ++used_cell_count_;
147  }
148 
149  void push_front_free_cell(const T &t) {
150 
151  int32 free = free_cells_;
152  free_cells_ = cells_[free_cells_].next_;
153  --free_cell_count_;
154  cells_[free].data_ = t;
155  cells_[free].next_ = used_cells_head_;
156  cells_[free].prev_ = null_;
157  used_cells_head_ = free;
158  }
159 
160  void push_front_new_cell(const T &t) {
161 
162  cell c;
163  c.data_ = t;
164  c.next_ = used_cells_head_;
165  c.prev_ = null_;
166  cells_.push_back(c);
167  used_cells_head_ = cells_.size() - 1;
168  }
169 
170  void update_used_cells_head_state() {
171 
172  if (cells_[used_cells_head_].next_ != null_)
173  cells_[cells_[used_cells_head_].next_].prev_ = used_cells_head_;
174  if (used_cells_tail_ == null_)
175  used_cells_tail_ = used_cells_head_;
176  ++used_cell_count_;
177  }
178 
179  void __erase(int32 c) {
180 
181  if (cells_[c].prev_ != null_)
182  cells_[cells_[c].prev_].next_ = cells_[c].next_;
183  else
184  used_cells_head_ = cells_[c].next_;
185  if (cells_[c].next_ != null_)
186  cells_[cells_[c].next_].prev_ = cells_[c].prev_;
187  else
188  used_cells_tail_ = cells_[c].prev_;
189  cells_[c].next_ = free_cells_;
190  free_cells_ = c;
191  ++free_cell_count_;
192  --used_cell_count_;
193  }
194  int32 _erase(int32 c) {
195 
196  int32 next_ = cells_[c].next_;
197  __erase(c);
198  return next_;
199  }
200 public:
201  list() : used_cells_head_(null_), used_cells_tail_(null_), free_cells_(null_), used_cell_count_(0), free_cell_count_(0) {}
202 
203  uint32 size() const { return used_cell_count_; }
204  void reserve(uint32 size) { cells_.reserve(size); }
205  void clear() {
206 
207  used_cells_head_ = used_cells_tail_ = free_cells_ = null_;
208  used_cell_count_ = free_cell_count_ = 0;
209  cells_.clear();
210  }
211  void push_back(const T &t) {
212 
213  if (free_cell_count_)
214  push_back_free_cell(t);
215  else
216  push_back_new_cell(t);
217  update_used_cells_tail_state();
218  }
219  void push_back(const T &t, int32 &location) {
220 
221  if (free_cell_count_) {
222 
223  location = free_cells_;
224  push_back_free_cell(t);
225  } else {
226 
227  push_back_new_cell(t);
228  location = used_cells_tail_;
229  }
230  update_used_cells_tail_state();
231  }
232  void push_front(const T &t) {
233 
234  if (free_cell_count_)
235  push_front_free_cell(t);
236  else
237  push_front_new_cell(t);
238  update_used_cells_head_state();
239  }
240  void push_front(const T &t, int32 &location) {
241 
242  if (free_cell_count_) {
243 
244  location = free_cells_;
245  push_front_free_cell(t);
246  } else {
247 
248  push_front_new_cell(t);
249  location = used_cells_tail_;
250  }
251  update_used_cells_head_state();
252  }
253 
254  class _iterator {
255  protected:
256  int32 cell_;
257  _iterator(int32 c) : cell_(c) {}
258  _iterator() : cell_(null_) {}
259  public:
260  bool operator ==(const _iterator &i) const { return cell_ == i.cell_; }
261  bool operator !=(const _iterator &i) const { return cell_ != i.cell_; }
262  };
263 
264  class iterator;
266  public _iterator {
267  friend class list;
268  private:
269  const list *list_;
270  const_iterator(const list *l, int32 c) : _iterator(c), list_(l) {}
271  public:
272  const_iterator() : _iterator(), list_(NULL) {}
273  const T &operator *() const { return list_->cells_[cell_].data_; }
274  const T *operator ->() const { return &(list_->cells_[cell_].data_); }
275  const_iterator &operator ++() {
276 
277  cell_ = list_->cells_[cell_].next_;
278  return *this;
279  }
280  const_iterator &operator =(const const_iterator &i) {
281 
282  list_ = i.list_;
283  cell_ = i.cell_;
284  return *this;
285  }
286  const_iterator &operator =(const iterator &i) {
287 
288  list_ = i.list_;
289  cell_ = i.cell_;
290  return *this;
291  }
292  };
293 
294  class iterator :
295  public _iterator {
296  friend class list;
297  friend class const_iterator;
298  protected:
299  list *list_;
300  iterator(list *l, int32 c) : _iterator(c), list_(l) {}
301  public:
302  iterator() : _iterator(), list_(NULL) {}
303  T &operator *() const { return list_->cells_[cell_].data_; }
304  T *operator ->() const { return &(list_->cells_[cell_].data_); }
305  iterator &operator ++() {
306 
307  cell_ = list_->cells_[cell_].next_;
308  return *this;
309  }
310  iterator &operator =(const iterator &i) {
311 
312  list_ = i.list_;
313  cell_ = i.cell_;
314  return *this;
315  }
316  };
317 private:
318  static const_iterator end_iterator_;
319 public:
320  iterator begin() { return iterator(this, used_cells_head_); }
321  const_iterator begin() const { return const_iterator(this, used_cells_head_); }
322  const_iterator &end() const { return end_iterator_; }
323  iterator erase(iterator &i) { return iterator(this, _erase(i.cell_)); } // no check for i.cell_==null_.
324  const_iterator erase(const_iterator &i) { return const_iterator(this, _erase(i.cell_)); } // no check for i.cell_==null_.
325  void erase(int32 c) { __erase(c); } // use for random object deletion.
326  void remove(const T &t) {
327 
328  const_iterator i(this, used_cells_head_);
329  for (; i != end_iterator_; ++i) {
330 
331  if ((*i) == t) {
332 
333  erase(i);
334  return;
335  }
336  }
337  }
338  T &front() { return cells_[used_cells_head_].data_; }
339  T &back() { return cells_[used_cells_tail_].data_; }
340 };
341 
342 template<typename T> typename list<T>::const_iterator list<T>::end_iterator_;
343 }
344 
345 
346 #endif
r_code::list::const_iterator
Definition: list.h:266
r_code::list::_iterator
Definition: list.h:254
r_code::list::cell
Definition: list.h:103
r_code::list::iterator
Definition: list.h:295
r_code::list
Definition: list.h:99