Devel Lib
MutexVector.h
1 #pragma once
2 
3 #include <functional>
4 #include <vector>
5 
6 #include "Threading/Mutex/Mutex.h"
7 #include "Core/Exceptions.h"
8 
13 #define MutexVectorLockGuard(x) RecursiveLockGuard(x.mutex())
14 
19 #define MutexVectorLock(x) RecursiveLockGuard(x.mutex().lock())
24 #define MutexVectorUnlock(x) RecursiveLockGuard(x.mutex().unlock())
25 
28 namespace Devel::Threading {
64  template<typename T>
65  class CMutexVector {
66 #define InClassLock() RecursiveLockGuard(this->m_oMutex)
67  public:
69  CMutexVector() = default;
70 
72  explicit CMutexVector(std::vector<T> &i_oVector) {
73  this->operator=(i_oVector);
74  }
75 
77  explicit CMutexVector(std::vector<T> &&i_oVector) {
78  this->operator=(std::move(i_oVector));
79  }
80 
82  CMutexVector(const CMutexVector<T> &i_oVector) {
83  this->operator=(i_oVector);
84  }
85 
87  CMutexVector(CMutexVector<T> &&i_oVector)
88  noexcept {
89  this->operator=(std::move(i_oVector));
90  }
91 
93  virtual ~CMutexVector() = default;
94 
95  public:
96  typedef std::function<bool(const T &)> FnMatch;
97 
101  bool removeAll(FnMatch i_fnMatch) {
102  bool fWasSuccessful = false;
103 
104  InClassLock();
105  for (size_t i = 0, nSize = this->size(); i < nSize;) {
106  if (i_fnMatch(this->m_atVector[i])) {
107  nSize--;
108  this->removeAt(i);
109  fWasSuccessful = true;
110  } else {
111  i++;
112  }
113  }
114 
115  return fWasSuccessful;
116  }
117 
121  bool removeOne(FnMatch i_fnMatch) {
122  InClassLock();
123  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
124  if (i_fnMatch(this->m_atVector[i])) {
125  this->removeAt(i);
126  return true;
127  }
128  }
129 
130  return false;
131  }
132 
136  bool remove(FnMatch i_fnMatch) {
137  return this->removeOne(i_fnMatch);
138  }
139 
144  T find(FnMatch i_fnMatch) const {
145  InClassLock();
146  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
147  if (i_fnMatch(this->m_atVector[i])) {
148  return this->m_atVector[i];
149  }
150  }
151 
152  throw NoEntryFoundException;
153  }
154 
159  T get(FnMatch i_fnMatch) const {
160  return this->find(i_fnMatch);
161  }
162 
166  std::vector<T> findAll(FnMatch i_fnMatch) const {
167  std::vector<T> atData;
168 
169  InClassLock();
170  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
171  if (i_fnMatch(this->m_atVector[i])) {
172  atData.push_back(this->m_atVector[i]);
173  }
174  }
175 
176  return atData;
177  }
178 
182  std::vector<T> getAll(FnMatch i_fnMatch) const {
183  return this->findAll(i_fnMatch);
184  }
185 
190  size_t findIndex(FnMatch i_fnMatch) const {
191  InClassLock();
192  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
193  if (i_fnMatch(this->m_atVector[i])) {
194  return i;
195  }
196  }
197 
198  return (~0);
199  }
200 
205  size_t indexOf(FnMatch i_fnMatch) const {
206  return this->findIndex(i_fnMatch);
207  }
208 
212  std::vector<size_t> findIndexAll(FnMatch i_fnMatch) const {
213  std::vector<size_t> anIndexes;
214 
215  InClassLock();
216  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
217  if (i_fnMatch(this->m_atVector[i])) {
218  anIndexes.push_back(i);
219  }
220  }
221 
222  return anIndexes;
223  }
224 
228  std::vector<size_t> indexOfAll(FnMatch i_fnMatch) const {
229  return this->findIndexAll(i_fnMatch);
230  }
231 
236  T take(FnMatch i_fnMatch) const {
237  InClassLock();
238  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
239  if (i_fnMatch(this->m_atVector[i])) {
240  T tData = this->m_atVector[i];
241  this->removeAt(i);
242  return tData;
243  }
244  }
245 
246  throw NoEntryFoundException;
247  }
248 
252  std::vector<T> takeAll(FnMatch i_fnMatch) const {
253  std::vector<T> atData;
254 
255  InClassLock();
256  for (size_t i = 0, nSize = this->size(); i < nSize;) {
257  if (i_fnMatch(this->m_atVector[i])) {
258  atData.push_back(this->m_atVector[i]);
259  this->removeAt(i);
260  nSize--;
261  } else {
262  i++;
263  }
264  }
265 
266  return atData;
267  }
268 
269  public:
272  const CMutex &mutex() const {
273  return this->m_oMutex;
274  }
275 
278  const std::vector<T> &rawVector() const {
279  return this->m_atVector;
280  }
281 
284  auto begin() const {
285  return this->m_atVector.begin();
286  }
287 
290  auto end() const {
291  return this->m_atVector.end();
292  }
293 
296  auto cbegin() const {
297  return this->m_atVector.cbegin();
298  }
299 
302  auto cend() const {
303  return this->m_atVector.cend();
304  }
305 
308  size_t size() const {
309  return this->m_atVector.size();
310  }
311 
314  bool isEmpty() const {
315  return this->m_atVector.empty();
316  }
317 
320  T &first() {
321  return *this->m_atVector.begin();
322  }
323 
326  T &last() {
327  return *(this->end() - 1);
328  }
329 
333  T &at(const size_t i_nIndex) {
334  return this->operator[](i_nIndex);
335  }
336 
339  std::vector<T> toStdVector() const {
340  return this->m_atVector;
341  }
342 
346  bool contains(const T &i_oValue) const {
347  InClassLock();
348  for (const T &tValue: this->m_atVector) {
349  if (tValue == i_oValue) {
350  return true;
351  }
352  }
353 
354  return false;
355  }
356 
357  public:
360  void resize(const size_t i_nSize) {
361  InClassLock();
362  return this->m_atVector.resize(i_nSize);
363  }
364 
367  void reserve(const size_t i_nSize) {
368  InClassLock();
369  return this->m_atVector.reserve(i_nSize);
370  }
371 
374  void push_back(const T &i_oValue) {
375  InClassLock();
376  return this->m_atVector.push_back(i_oValue);
377  }
378 
381  void push_back(T &&i_oValue) {
382  InClassLock();
383  return this->m_atVector.push_back(std::move(i_oValue));
384  }
385 
388  void push_back(const std::vector<T> &i_atValue) {
389  for (const T &oItem: i_atValue) {
390  this->push_back(oItem);
391  }
392  }
393 
396  void push_back(std::vector<T> &&i_atValue) {
397  for (const T &oItem: i_atValue) {
398  this->push_back(std::move(oItem));
399  }
400  }
401 
404  void push_back(const CMutexVector<T> &i_atValue) {
405  MutexVectorLockGuard(i_atValue);
406  return this->push_back(i_atValue.rawVector());
407  }
408 
411  void push_back(CMutexVector<T> &&i_atValue) {
412  return this->push_back(std::move(i_atValue.rawVector()));
413  }
414 
415  public:
419  bool removeAt(const size_t i_nIndex) {
420  InClassLock();
421  if (i_nIndex > this->size()) {
422  return false;
423  }
424 
425  this->m_atVector.erase(this->begin() + i_nIndex);
426 
427  return true;
428  }
429 
433  bool remove(const T &i_oValue) {
434  InClassLock();
435  for (size_t i = 0, nSize = this->size(); i < nSize; i++) {
436  if (this->m_atVector[i] == i_oValue) {
437  this->removeAt(i);
438  return true;
439  }
440  }
441  return false;
442  }
443 
445  void clear() {
446  InClassLock();
447  this->m_atVector.clear();
448  }
449 
450  public:
454  CMutexVector &operator=(const std::vector<T> &i_tOther) {
455  InClassLock();
456  this->m_atVector = i_tOther;
457  return *this;
458  }
459 
463  CMutexVector &operator=(std::vector<T> &&i_tOther) {
464  InClassLock();
465  this->m_atVector = std::move(i_tOther);
466  return *this;
467  }
468 
472  virtual CMutexVector &operator=(const CMutexVector<T> &i_tOther) {
473  InClassLock();
474  MutexVectorLockGuard(i_tOther);
475  this->operator=(i_tOther.rawVector());
476  return *this;
477  }
478 
483  noexcept {
484  InClassLock();
485  MutexVectorLockGuard(i_tOther);
486  this->operator=(std::move(i_tOther.rawVector()));
487  return *this;
488  }
489 
493  T &operator[](const size_t i_nIndex) {
494  if (i_nIndex >= this->size()) {
495  throw IndexOutOfRangeException;
496  }
497 
498  return this->m_atVector[i_nIndex];
499  }
500 
504  const T &operator[](const size_t i_nIndex) const {
505  if (i_nIndex >= this->size()) {
506  throw IndexOutOfRangeException;
507  }
508 
509  return this->m_atVector[i_nIndex];
510  }
511 
512  private:
515  CMutex m_oMutex;
516 
519  std::vector<T> m_atVector;
520  };
521 }
A class for thread-safe handling of vectors.
Definition: MutexVector.h:65
void clear()
Removes all elements from the vector.
Definition: MutexVector.h:445
auto begin() const
Returns an iterator to the beginning of the vector.
Definition: MutexVector.h:284
std::vector< size_t > findIndexAll(FnMatch i_fnMatch) const
Finds all indexes of the elements in the vector that match the given condition.
Definition: MutexVector.h:212
CMutexVector(const CMutexVector< T > &i_oVector)
Copy constructor that takes a const reference to another CMutexVector.
Definition: MutexVector.h:82
void push_back(std::vector< T > &&i_atValue)
Moves a vector of elements to the end of the vector.
Definition: MutexVector.h:396
CMutexVector & operator=(std::vector< T > &&i_tOther)
Assignment operator that moves a std::vector<T> to the CMutexVector.
Definition: MutexVector.h:463
T & at(const size_t i_nIndex)
Returns a reference to the element at the specified index.
Definition: MutexVector.h:333
T find(FnMatch i_fnMatch) const
Finds the first element in the vector that matches the given condition.
Definition: MutexVector.h:144
bool contains(const T &i_oValue) const
Checks if the vector contains the specified value.
Definition: MutexVector.h:346
bool removeOne(FnMatch i_fnMatch)
Removes the first element from the vector that matches the given condition.
Definition: MutexVector.h:121
bool remove(const T &i_oValue)
Removes the first occurrence of the specified value from the vector.
Definition: MutexVector.h:433
CMutexVector()=default
Default constructor for CMutexVector.
void push_back(CMutexVector< T > &&i_atValue)
Moves another CMutexVector to the end of the vector.
Definition: MutexVector.h:411
T get(FnMatch i_fnMatch) const
Alias for find(FnMatch).
Definition: MutexVector.h:159
T & first()
Returns a reference to the first element in the vector.
Definition: MutexVector.h:320
std::vector< size_t > indexOfAll(FnMatch i_fnMatch) const
Alias for findIndexAll(FnMatch).
Definition: MutexVector.h:228
virtual ~CMutexVector()=default
Destructor for CMutexVector.
T & last()
Returns a reference to the last element in the vector.
Definition: MutexVector.h:326
void push_back(const CMutexVector< T > &i_atValue)
Appends another CMutexVector to the end of the vector.
Definition: MutexVector.h:404
auto cend() const
Returns a const iterator to the end of the vector.
Definition: MutexVector.h:302
auto cbegin() const
Returns a const iterator to the beginning of the vector.
Definition: MutexVector.h:296
bool removeAll(FnMatch i_fnMatch)
Removes all elements from the vector that match the given condition.
Definition: MutexVector.h:101
size_t findIndex(FnMatch i_fnMatch) const
Finds the index of the first element in the vector that matches the given condition.
Definition: MutexVector.h:190
CMutexVector & operator=(const std::vector< T > &i_tOther)
Assignment operator that copies a std::vector<T> to the CMutexVector.
Definition: MutexVector.h:454
bool isEmpty() const
Checks if the vector is empty.
Definition: MutexVector.h:314
CMutexVector(std::vector< T > &&i_oVector)
Move constructor that takes an rvalue reference to a vector.
Definition: MutexVector.h:77
virtual CMutexVector & operator=(CMutexVector< T > &&i_tOther) noexcept
Assignment operator that moves another CMutexVector to the CMutexVector.
Definition: MutexVector.h:482
void push_back(T &&i_oValue)
Moves a new element to the end of the vector.
Definition: MutexVector.h:381
bool remove(FnMatch i_fnMatch)
Removes the first element from the vector that matches the given condition.
Definition: MutexVector.h:136
auto end() const
Returns an iterator to the end of the vector.
Definition: MutexVector.h:290
void reserve(const size_t i_nSize)
Reserves memory for the specified number of elements.
Definition: MutexVector.h:367
void push_back(const T &i_oValue)
Appends a new element to the end of the vector.
Definition: MutexVector.h:374
size_t size() const
Returns the size of the vector.
Definition: MutexVector.h:308
void resize(const size_t i_nSize)
Resizes the vector to the specified size.
Definition: MutexVector.h:360
std::vector< T > findAll(FnMatch i_fnMatch) const
Finds all elements in the vector that match the given condition.
Definition: MutexVector.h:166
void push_back(const std::vector< T > &i_atValue)
Appends a vector of elements to the end of the vector.
Definition: MutexVector.h:388
std::vector< T > toStdVector() const
Converts the CMutexVector to a standard vector.
Definition: MutexVector.h:339
const T & operator[](const size_t i_nIndex) const
Const access operator that returns a const reference to the element at the specified index.
Definition: MutexVector.h:504
CMutexVector(std::vector< T > &i_oVector)
Copy constructor that takes a non-const reference to a vector.
Definition: MutexVector.h:72
std::vector< T > takeAll(FnMatch i_fnMatch) const
Takes all elements from the vector that match the given condition and removes them from the vector.
Definition: MutexVector.h:252
std::vector< T > getAll(FnMatch i_fnMatch) const
Alias for findAll(FnMatch).
Definition: MutexVector.h:182
T take(FnMatch i_fnMatch) const
Takes the first element from the vector that matches the given condition and removes it from the vect...
Definition: MutexVector.h:236
virtual CMutexVector & operator=(const CMutexVector< T > &i_tOther)
Assignment operator that copies another CMutexVector to the CMutexVector.
Definition: MutexVector.h:472
bool removeAt(const size_t i_nIndex)
Removes the element at the specified index from the vector.
Definition: MutexVector.h:419
T & operator[](const size_t i_nIndex)
Access operator that returns a reference to the element at the specified index.
Definition: MutexVector.h:493
const CMutex & mutex() const
Returns a reference to the underlying mutex of the CMutexVector.
Definition: MutexVector.h:272
const std::vector< T > & rawVector() const
Returns a reference to the underlying vector.
Definition: MutexVector.h:278
size_t indexOf(FnMatch i_fnMatch) const
Alias for findIndex(FnMatch).
Definition: MutexVector.h:205
A class for handling recursive mutexes.
Definition: Mutex.h:47
The namespace encapsulating threading related classes and functions in the Devel framework.