My Project
unordered_ref_array.h
1 #pragma once
2 #include <vector>
3 
11 template <typename T>
13 {
14 public:
15  // ------------------------------------------
16  // Iterators
17  // ------------------------------------------
18  typedef std::vector<T> base_class_type;
19  typedef typename base_class_type::iterator iterator;
20  typedef typename base_class_type::const_iterator const_iterator;
21 
22  typedef typename base_class_type::reverse_iterator reverse_iterator;
23  typedef typename base_class_type::const_reverse_iterator const_reverse_iterator;
24 
25  iterator begin() { return m_data.begin(); }
26  const_iterator begin() const { return m_data.begin(); }
27 
28  iterator end() { return m_data.end(); }
29  const_iterator end() const { return m_data.end(); }
30 
31  const_iterator cbegin() const { return m_data.cbegin(); }
32  const_iterator cend() const { return m_data.cend(); }
33 
34  reverse_iterator rbegin() { return m_data.rbegin(); }
35  const_reverse_iterator rbegin() const { return m_data.rbegin(); }
36 
37  reverse_iterator rend() { return m_data.rend(); }
38  const_reverse_iterator rend() const { return m_data.rend(); }
39 
40  const_reverse_iterator crbegin() const { return m_data.crbegin(); }
41  const_reverse_iterator crend() const { return m_data.crend(); }
42 
45  : m_data()
46  {
47  }
48 
51  : m_data()
52  {
54  }
55 
58  {
59  clear();
60  }
61 
64  {
65  m_data = other.m_data;
67  }
68 
71  {
72  m_data = std::move(other._data);
73  }
74 
77  {
78  if (this != &other) {
79  clear();
80  m_data = other.m_data;
82  }
83  return *this;
84  }
85 
88  {
89  if (this != &other) {
90  clear();
91  m_data = std::move(other._data);
92  }
93  return *this;
94  }
95 
101  void reserve(size_t n)
102  {
103  m_data.reserve(n);
104  }
105 
111  size_t capacity() const
112  {
113  return m_data.capacity();
114  }
115 
120  size_t size() const
121  {
122  return m_data.size();
123  }
124 
128  bool empty() const
129  {
130  return m_data.empty();
131  }
132 
134  size_t max_size() const
135  {
136  return m_data.max_size();
137  }
138 
140  size_t getIndex(T object) const
141  {
142  auto iter = std::find(m_data.begin(), m_data.end(), object);
143  if (iter != m_data.end())
144  return iter - m_data.begin();
145 
146  return -1;
147  }
148 
153  const_iterator find(T object) const
154  {
155  return std::find(m_data.begin(), m_data.end(), object);
156  }
157 
158  iterator find(T object)
159  {
160  return std::find(m_data.begin(), m_data.end(), object);
161  }
162 
164  T at(size_t index) const
165  {
166  PE_ASSERT(index >= 0 && index < size());
167  return m_data[index];
168  }
169 
171  T front() const
172  {
173  return m_data.front();
174  }
175 
177  T back() const
178  {
179  return m_data.back();
180  }
181 
183  bool contains(T object) const
184  {
185  return(std::find(m_data.begin(), m_data.end(), object) != m_data.end());
186  }
187 
189  bool equals(const unordered_ref_array<T> &other)
190  {
191  size_t s = this->size();
192  if (s != other.size())
193  return false;
194 
195  for (size_t i = 0; i < s; i++)
196  {
197  if (this->at(i) != other.at(i))
198  {
199  return false;
200  }
201  }
202  return true;
203  }
204 
205  // Adds objects
206 
212  void push_back(T object)
213  {
214  PE_ASSERT(object != nullptr);
215  m_data.push_back(object);
216  object->addref();
217  }
218 
221  {
222  for (const auto &obj : other) {
223  m_data.push_back(obj);
224  obj->addref();
225  }
226  }
227 
234  void insert(size_t index, T object)
235  {
236  PE_ASSERT(index >= 0 && index <= size());
237  PE_ASSERT(object != nullptr);
238  m_data.insert((std::begin(m_data) + index), object);
239  object->addref();
240  }
241 
242  // Removes Objects
243 
247  void pop_back()
248  {
249  PE_ASSERT(!m_data.empty());
250  auto last = m_data.back();
251  m_data.pop_back();
252  last->Release();
253  }
254 
260  void eraseObject(T object, bool removeAll = false)
261  {
262  PE_ASSERT(object != nullptr);
263 
264  if (removeAll)
265  {
266  for (auto iter = m_data.begin(); iter != m_data.end();)
267  {
268  if ((*iter) == object)
269  {
270  iter = m_data.erase(iter);
271  object->Release();
272  }
273  else
274  {
275  ++iter;
276  }
277  }
278  }
279  else
280  {
281  auto iter = std::find(m_data.begin(), m_data.end(), object);
282  if (iter != m_data.end())
283  {
284  m_data.erase(iter);
285  object->Release();
286  }
287  }
288  }
289 
295  iterator erase(iterator position)
296  {
297  PE_ASSERT(position >= m_data.begin() && position < m_data.end());
298  (*position)->Release();
299  size_t nIndex = position - m_data.begin();
300  // move the last element to current position.
301  *position = m_data.back();
302  m_data.pop_back();
303 
304  return !m_data.empty() ? (m_data.begin()+nIndex) : m_data.end();
305  }
306 
313  iterator erase(iterator first, iterator last)
314  {
315  for (auto iter = first; iter != last; ++iter)
316  {
317  (*iter)->Release();
318  }
319 
320  return m_data.erase(first, last);
321  }
322 
328  iterator erase(size_t index)
329  {
330  PE_ASSERT(!m_data.empty() && index >= 0 && index < size());
331  auto it = std::next(begin(), index);
332  (*it)->Release();
333  *it = m_data.back();
334  m_data.pop_back();
335  return !m_data.empty() ? (m_data.begin()+index) : m_data.end();
336  }
337 
341  void clear()
342  {
343  for (auto it = std::begin(m_data); it != std::end(m_data); ++it) {
344  (*it)->Release();
345  }
346  m_data.clear();
347  }
348 
349  // Rearranging Content
350 
352  void swap(T object1, T object2)
353  {
354  size_t idx1 = getIndex(object1);
355  size_t idx2 = getIndex(object2);
356 
357  PE_ASSERT(idx1 >= 0 && idx2 >= 0);
358 
359  std::swap(m_data[idx1], m_data[idx2]);
360  }
361 
363  void swap(size_t index1, size_t index2)
364  {
365  PE_ASSERT(index1 >= 0 && index1 < size() && index2 >= 0 && index2 < size());
366 
367  std::swap(m_data[index1], m_data[index2]);
368  }
369 
371  void replace(size_t index, T object)
372  {
373  PE_ASSERT(index >= 0 && index < size());
374  PE_ASSERT(object != nullptr);
375 
376  m_data[index]->Release();
377  m_data[index] = object;
378  object->addref();
379  }
380 
382  void reverse()
383  {
384  std::reverse(std::begin(m_data), std::end(m_data));
385  }
386 
389  {
390  m_data.shrink_to_fit();
391  }
392 
393 protected:
394 
397  {
398  for (const auto &obj : m_data) {
399  obj->addref();
400  }
401  }
402 
403  base_class_type m_data;
404 };
405 
bool contains(T object) const
Returns a Boolean value that indicates whether object is present in vector.
Definition: unordered_ref_array.h:183
const_iterator find(T object) const
Find the object in the vector.
Definition: unordered_ref_array.h:153
void shrink_to_fit()
Shrinks the vector so the memory footprint corresponds with the number of items.
Definition: unordered_ref_array.h:388
T at(size_t index) const
Returns the element at position &#39;index&#39; in the vector.
Definition: unordered_ref_array.h:164
void pop_back()
Removes the last element in the vector, effectively reducing the container size by one...
Definition: unordered_ref_array.h:247
size_t capacity() const
Returns the size of the storage space currently allocated for the array, expressed in terms of elemen...
Definition: unordered_ref_array.h:111
T back() const
Returns the last element of the vector.
Definition: unordered_ref_array.h:177
bool empty() const
Returns whether the vector is empty (i.e.
Definition: unordered_ref_array.h:128
unordered_ref_array< T > & operator=(unordered_ref_array< T > &&other)
Move assignment operator.
Definition: unordered_ref_array.h:87
void swap(size_t index1, size_t index2)
Swap two elements with certain indexes.
Definition: unordered_ref_array.h:363
size_t max_size() const
Returns the maximum number of elements that the vector can hold.
Definition: unordered_ref_array.h:134
iterator erase(size_t index)
Removes from the vector with an index.
Definition: unordered_ref_array.h:328
void replace(size_t index, T object)
Replace object at index with another object.
Definition: unordered_ref_array.h:371
void insert(size_t index, T object)
Insert a certain object at a certain index.
Definition: unordered_ref_array.h:234
similar to unordered array except that it will automatically call addref/Release when obj is added/re...
Definition: unordered_ref_array.h:12
void swap(T object1, T object2)
Swap two elements.
Definition: unordered_ref_array.h:352
void reverse()
reverses the vector
Definition: unordered_ref_array.h:382
iterator erase(iterator position)
Removes from the vector with an iterator.
Definition: unordered_ref_array.h:295
void push_back(T object)
Adds a new element at the end of the vector, after its current last element.
Definition: unordered_ref_array.h:212
void push_back(const unordered_ref_array< T > &other)
Push all elements of an existing vector to the end of current vector.
Definition: unordered_ref_array.h:220
bool equals(const unordered_ref_array< T > &other)
Returns true if the two vectors are equal.
Definition: unordered_ref_array.h:189
T front() const
Returns the first element in the vector.
Definition: unordered_ref_array.h:171
void reserve(size_t n)
Request a change in capacity.
Definition: unordered_ref_array.h:101
size_t size() const
Returns the number of elements in the vector.
Definition: unordered_ref_array.h:120
unordered_ref_array< T > & operator=(const unordered_ref_array< T > &other)
Copy assignment operator.
Definition: unordered_ref_array.h:76
size_t getIndex(T object) const
Returns index of a certain object, return UINT_MAX if doesn&#39;t contain the object. ...
Definition: unordered_ref_array.h:140
void eraseObject(T object, bool removeAll=false)
Remove a certain object in Vector.
Definition: unordered_ref_array.h:260
iterator erase(iterator first, iterator last)
Removes from the vector with a range of elements ( [first, last) ).
Definition: unordered_ref_array.h:313
void addRefForAllObjects()
addrefs all the objects in the vector
Definition: unordered_ref_array.h:396
void clear()
Removes all elements from the vector (which are destroyed), leaving the container with a size of 0...
Definition: unordered_ref_array.h:341