PcapPlusPlus  24.09
PointerVector.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstddef>
4 #include <stdio.h>
5 #include <stdint.h>
6 #include <stdexcept>
7 #include <vector>
8 #include <memory>
9 
10 #include "DeprecationUtils.h"
11 
13 
18 namespace pcpp
19 {
20 
28  template <typename T> class PointerVector
29  {
30  public:
34  using VectorIterator = typename std::vector<T*>::iterator;
35 
39  using ConstVectorIterator = typename std::vector<T*>::const_iterator;
40 
45  {}
46 
54  PointerVector(const PointerVector& other) : m_Vector(deepCopyUnsafe(other.m_Vector))
55  {}
56 
61  PointerVector(PointerVector&& other) noexcept : m_Vector(std::move(other.m_Vector))
62  {
63  other.m_Vector.clear();
64  }
65 
70  {
71  freeVectorUnsafe(m_Vector);
72  }
73 
81  {
82  // Saves a copy of the old pointer to defer cleanup.
83  auto oldValues = m_Vector;
84  try
85  {
86  m_Vector = deepCopyUnsafe(other.m_Vector);
87  }
88  // If an exception is thrown during the copy operation, restore old values and rethrow.
89  catch (const std::exception&)
90  {
91  m_Vector = std::move(oldValues);
92  throw;
93  }
94  // Free old values as the new ones have been successfully assigned.
95  freeVectorUnsafe(oldValues);
96  return *this;
97  }
98 
106  {
107  // Releases all current elements.
108  clear();
109  // Moves the elements of the other vector.
110  m_Vector = std::move(other.m_Vector);
111  // Explicitly clear the other vector as the standard only guarantees an unspecified valid state after move.
112  other.m_Vector.clear();
113  return *this;
114  }
115 
119  void clear()
120  {
121  freeVectorUnsafe(m_Vector);
122  m_Vector.clear();
123  }
124 
128  void pushBack(std::nullptr_t element, bool freeElementOnError = true) = delete;
129 
136  void pushBack(T* element, bool freeElementOnError = true)
137  {
138  if (element == nullptr)
139  {
140  throw std::invalid_argument("Element is nullptr");
141  }
142 
143  try
144  {
145  m_Vector.push_back(element);
146  }
147  catch (const std::exception&)
148  {
149  if (freeElementOnError)
150  {
151  delete element;
152  }
153  throw;
154  }
155  }
156 
163  void pushBack(std::unique_ptr<T> element)
164  {
165  if (!element)
166  {
167  throw std::invalid_argument("Element is nullptr");
168  }
169 
170  // Release is called after the raw pointer is already inserted into the vector to prevent
171  // a memory leak if push_back throws.
172  // cppcheck-suppress danglingLifetime
173  m_Vector.push_back(element.get());
174  element.release();
175  }
176 
182  {
183  return m_Vector.begin();
184  }
185 
191  {
192  return m_Vector.begin();
193  }
194 
200  {
201  return m_Vector.end();
202  }
203 
209  {
210  return m_Vector.end();
211  }
212 
217  size_t size() const
218  {
219  return m_Vector.size();
220  }
221 
225  T* front()
226  {
227  return m_Vector.front();
228  }
229 
233  T const* front() const
234  {
235  return m_Vector.front();
236  }
237 
241  T* back()
242  {
243  return m_Vector.back();
244  }
245 
246  /*
247  * @return A pointer to the last element in the vector.
248  */
249  T const* back() const
250  {
251  return m_Vector.back();
252  }
253 
261  {
262  delete (*position);
263  return m_Vector.erase(position);
264  }
265 
274  PCPP_DEPRECATED("Please use the memory safe 'getAndDetach' instead.")
276  {
277  T* result = *position;
278  position = m_Vector.erase(position);
279  return result;
280  }
281 
287  std::unique_ptr<T> getAndDetach(size_t index)
288  {
289  return getAndDetach(m_Vector.begin() + index);
290  }
291 
298  std::unique_ptr<T> getAndDetach(VectorIterator& position)
299  {
300  std::unique_ptr<T> result(*position);
301  position = m_Vector.erase(position);
302  return result;
303  }
304 
310  std::unique_ptr<T> getAndDetach(VectorIterator const& position)
311  {
312  std::unique_ptr<T> result(*position);
313  m_Vector.erase(position);
314  return result;
315  }
316 
322  T* at(int index)
323  {
324  return m_Vector.at(index);
325  }
326 
332  const T* at(int index) const
333  {
334  return m_Vector.at(index);
335  }
336 
337  private:
343  static std::vector<T*> deepCopyUnsafe(std::vector<T*> const& origin)
344  {
345  std::vector<T*> copyVec;
346 
347  try
348  {
349  for (const auto iter : origin)
350  {
351  T* objCopy = new T(*iter);
352  try
353  {
354  copyVec.push_back(objCopy);
355  }
356  catch (const std::exception&)
357  {
358  delete objCopy;
359  throw;
360  }
361  }
362  }
363  catch (const std::exception&)
364  {
365  for (auto obj : copyVec)
366  {
367  delete obj;
368  }
369  throw;
370  }
371 
372  return copyVec;
373  }
374 
381  static void freeVectorUnsafe(std::vector<T*> const& origin)
382  {
383  for (auto& obj : origin)
384  {
385  delete obj;
386  }
387  }
388 
389  std::vector<T*> m_Vector;
390  };
391 
392 } // namespace pcpp
Definition: PointerVector.h:29
VectorIterator begin()
Definition: PointerVector.h:181
PointerVector()
Definition: PointerVector.h:44
ConstVectorIterator end() const
Definition: PointerVector.h:208
typename std::vector< T * >::const_iterator ConstVectorIterator
Definition: PointerVector.h:39
std::unique_ptr< T > getAndDetach(size_t index)
Definition: PointerVector.h:287
T * getAndRemoveFromVector(VectorIterator &position)
Definition: PointerVector.h:275
void pushBack(std::unique_ptr< T > element)
Definition: PointerVector.h:163
VectorIterator erase(VectorIterator position)
Definition: PointerVector.h:260
PointerVector(const PointerVector &other)
Definition: PointerVector.h:54
PointerVector & operator=(const PointerVector &other)
Definition: PointerVector.h:80
std::unique_ptr< T > getAndDetach(VectorIterator const &position)
Definition: PointerVector.h:310
~PointerVector()
Definition: PointerVector.h:69
T const * front() const
Definition: PointerVector.h:233
void pushBack(T *element, bool freeElementOnError=true)
Definition: PointerVector.h:136
T * back()
Definition: PointerVector.h:241
T * at(int index)
Definition: PointerVector.h:322
size_t size() const
Definition: PointerVector.h:217
const T * at(int index) const
Definition: PointerVector.h:332
T * front()
Definition: PointerVector.h:225
PointerVector(PointerVector &&other) noexcept
Definition: PointerVector.h:61
void pushBack(std::nullptr_t element, bool freeElementOnError=true)=delete
ConstVectorIterator begin() const
Definition: PointerVector.h:190
typename std::vector< T * >::iterator VectorIterator
Definition: PointerVector.h:34
void clear()
Definition: PointerVector.h:119
PointerVector & operator=(PointerVector &&other) noexcept
Definition: PointerVector.h:105
std::unique_ptr< T > getAndDetach(VectorIterator &position)
Definition: PointerVector.h:298
VectorIterator end()
Definition: PointerVector.h:199
The main namespace for the PcapPlusPlus lib.