GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef ZSERIO_UNIQUE_PTR_H_INC |
||
2 |
#define ZSERIO_UNIQUE_PTR_H_INC |
||
3 |
|||
4 |
#include <memory> |
||
5 |
#include <type_traits> |
||
6 |
#include "zserio/RebindAlloc.h" |
||
7 |
#include "zserio/AllocatorHolder.h" |
||
8 |
|||
9 |
namespace zserio |
||
10 |
{ |
||
11 |
|||
12 |
namespace detail |
||
13 |
{ |
||
14 |
|||
15 |
/** |
||
16 |
* Custom deleter to ensure proper deallocation of the unique_ptr. |
||
17 |
*/ |
||
18 |
template <class ALLOC_T> |
||
19 |
17 |
struct UniquePtrDeleter : public AllocatorHolder<ALLOC_T> |
|
20 |
{ |
||
21 |
using allocator_type = ALLOC_T; |
||
22 |
using T = typename allocator_type::value_type; |
||
23 |
|||
24 |
/** Method generated by default. */ |
||
25 |
/** \{ */ |
||
26 |
390 |
~UniquePtrDeleter() = default; |
|
27 |
|||
28 |
153 |
UniquePtrDeleter(UniquePtrDeleter&& other) = default; |
|
29 |
UniquePtrDeleter& operator=(UniquePtrDeleter&& other) = default; |
||
30 |
/** |
||
31 |
* \} |
||
32 |
*/ |
||
33 |
|||
34 |
/** |
||
35 |
* Copying is disallowed! |
||
36 |
* \{ |
||
37 |
*/ |
||
38 |
UniquePtrDeleter(const UniquePtrDeleter& other) = delete; |
||
39 |
UniquePtrDeleter& operator=(const UniquePtrDeleter& other) = delete; |
||
40 |
/** |
||
41 |
* \} |
||
42 |
*/ |
||
43 |
|||
44 |
/** |
||
45 |
* Empty constructor. |
||
46 |
*/ |
||
47 |
template <typename ALLOC_U = ALLOC_T> |
||
48 |
75 |
UniquePtrDeleter() : |
|
49 |
✓✗✓✗ |
75 |
UniquePtrDeleter(ALLOC_U()) |
50 |
{ |
||
51 |
75 |
} |
|
52 |
|||
53 |
/** |
||
54 |
* Constructor from given allocator. |
||
55 |
*/ |
||
56 |
template <typename ALLOC_U = ALLOC_T> |
||
57 |
251 |
UniquePtrDeleter(const ALLOC_U& allocator) : |
|
58 |
251 |
AllocatorHolder<ALLOC_T>(allocator) |
|
59 |
{ |
||
60 |
static_assert(std::is_same<allocator_type, RebindAlloc<ALLOC_U, T>>::value, |
||
61 |
"UniquePtrDeleter requires same allocator in constructor!"); |
||
62 |
251 |
} |
|
63 |
|||
64 |
/** |
||
65 |
* Constructor from deleter to another type. |
||
66 |
*/ |
||
67 |
template <typename ALLOC_U> |
||
68 |
29 |
UniquePtrDeleter(const UniquePtrDeleter<ALLOC_U>& deleter) : |
|
69 |
✓✗✓✗ ✗✗✗✗ |
29 |
UniquePtrDeleter(deleter.get_allocator()) |
70 |
29 |
{} |
|
71 |
|||
72 |
92 |
void operator()(T* ptr) |
|
73 |
{ |
||
74 |
✓✗✓✗ ✓✗✗✗ ✓✗✗✓ ✓✗✓✗ ✓✗✓✗ ✓✗ |
184 |
allocator_type alloc = this->get_allocator(); |
75 |
using AllocTraits = std::allocator_traits<allocator_type>; |
||
76 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
92 |
AllocTraits::destroy(alloc, std::addressof(*ptr)); |
77 |
✓✗✓✗ ✗✗✓✓ ✗ |
92 |
AllocTraits::deallocate(alloc, ptr, 1); |
78 |
92 |
} |
|
79 |
}; |
||
80 |
|||
81 |
} // namespace detail |
||
82 |
|||
83 |
/** |
||
84 |
* Typedef to std::unique_ptr provided for convenience - using std::allocator. |
||
85 |
* |
||
86 |
* Uses custom deleter to ensure proper deallocation. |
||
87 |
*/ |
||
88 |
template <typename T, typename ALLOC = std::allocator<T>> |
||
89 |
using unique_ptr = std::unique_ptr<T, detail::UniquePtrDeleter<ALLOC>>; |
||
90 |
|||
91 |
/** |
||
92 |
* Allocates memory for an object of type T using given allocator and constructs it passing args to its |
||
93 |
* constructor. |
||
94 |
* |
||
95 |
* \param allocator Allocator to use. |
||
96 |
* \param args List of elements passed to T's constructor. |
||
97 |
* |
||
98 |
* \return Object of type zserio::unique_ptr<T, ALLOC> that owns and stores a pointer to the constructed object. |
||
99 |
*/ |
||
100 |
template <typename T, typename ALLOC, class ...Args> |
||
101 |
zserio::unique_ptr<T, RebindAlloc<ALLOC, T>> |
||
102 |
93 |
allocate_unique(const ALLOC& allocator, Args&& ...args) |
|
103 |
{ |
||
104 |
using Allocator = RebindAlloc<ALLOC, T>; |
||
105 |
using AllocTraits = std::allocator_traits<Allocator>; |
||
106 |
|||
107 |
✓✗ | 186 |
Allocator typedAllocator = allocator; |
108 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
93 |
typename AllocTraits::pointer ptr = AllocTraits::allocate(typedAllocator, 1); |
109 |
try |
||
110 |
{ |
||
111 |
✗✓✓✗ ✗✓✓✗ ✓✓✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
93 |
AllocTraits::construct(typedAllocator, std::addressof(*ptr), std::forward<Args>(args)...); |
112 |
✓✗✓✗ ✓✗✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗ |
184 |
return zserio::unique_ptr<T, Allocator>(std::addressof(*ptr), typedAllocator); |
113 |
} |
||
114 |
2 |
catch (...) |
|
115 |
{ |
||
116 |
✗✗✗✗ ✗✗✗✗ ✗✗ |
1 |
AllocTraits::deallocate(typedAllocator, ptr, 1); |
117 |
1 |
throw; |
|
118 |
} |
||
119 |
} |
||
120 |
|||
121 |
} // namespace zserio |
||
122 |
|||
123 |
#endif // ZSERIO_UNIQUE_PTR_H_INC |
Generated by: GCOVR (Version 4.2) |