|
6 | 6 | #include <stdexcept>
|
7 | 7 | #include <vector>
|
8 | 8 | #include <memory>
|
| 9 | +#include <type_traits> |
9 | 10 |
|
10 | 11 | #include "DeprecationUtils.h"
|
11 | 12 |
|
|
17 | 18 | */
|
18 | 19 | namespace pcpp
|
19 | 20 | {
|
| 21 | + namespace internal |
| 22 | + { |
| 23 | + /** |
| 24 | + * @brief A helper struct to facilitate the creation of a copy of an object. |
| 25 | + * @tparam T The type of object to copy. |
| 26 | + * @tparam Enable Helper parameter for SFINAE. |
| 27 | + */ |
| 28 | + template <class T, class Enable = void> struct Copier |
| 29 | + { |
| 30 | + std::unique_ptr<T> operator()(const T& obj) const |
| 31 | + { |
| 32 | + return std::unique_ptr<T>(new T(obj)); |
| 33 | + } |
| 34 | + }; |
| 35 | + |
| 36 | + /** |
| 37 | + * @brief A specialization of Copier to facilitate the safe copying of polymorphic objects via clone() method. |
| 38 | + * @tparam T The type of object to copy. |
| 39 | + */ |
| 40 | + template <class T> struct Copier<T, typename std::enable_if<std::is_polymorphic<T>::value>::type> |
| 41 | + { |
| 42 | + std::unique_ptr<T> operator()(const T& obj) const |
| 43 | + { |
| 44 | + // Clone can return unique_ptr or raw pointer. |
| 45 | + return std::unique_ptr<T>(std::move(obj.clone())); |
| 46 | + } |
| 47 | + }; |
| 48 | + } // namespace internal |
20 | 49 |
|
21 | 50 | /**
|
22 | 51 | * @class PointerVector
|
@@ -343,21 +372,16 @@ namespace pcpp
|
343 | 372 | static std::vector<T*> deepCopyUnsafe(std::vector<T*> const& origin)
|
344 | 373 | {
|
345 | 374 | std::vector<T*> copyVec;
|
| 375 | + // Allocate the vector initially to ensure no exceptions are thrown during push_back. |
| 376 | + copyVec.reserve(origin.size()); |
346 | 377 |
|
347 | 378 | try
|
348 | 379 | {
|
349 | 380 | for (const auto iter : origin)
|
350 | 381 | {
|
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 |
| - } |
| 382 | + std::unique_ptr<T> objCopy = internal::Copier<T>()(*iter); |
| 383 | + // There shouldn't be a memory leak as the vector is reserved. |
| 384 | + copyVec.push_back(objCopy.release()); |
361 | 385 | }
|
362 | 386 | }
|
363 | 387 | catch (const std::exception&)
|
|
0 commit comments