Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file lib.UniquePointer.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef LIB_UNIQUEPOINTER_HPP_ | ||
7 | #define LIB_UNIQUEPOINTER_HPP_ | ||
8 | |||
9 | #include "lib.Object.hpp" | ||
10 | #include "api.SmartPointer.hpp" | ||
11 | #include "lib.SmartPointerDeleter.hpp" | ||
12 | |||
13 | namespace eoos | ||
14 | { | ||
15 | namespace lib | ||
16 | { | ||
17 | |||
18 | #ifdef EOOS_ENABLE_DYNAMIC_HEAP_MEMORY | ||
19 | |||
20 | /** | ||
21 | * @class UniquePointer<T,D,A> | ||
22 | * @brief Unique pointer. | ||
23 | * | ||
24 | * @tparam T Data type of an owning object. | ||
25 | * @tparam D Deleter type for an owning object. | ||
26 | * @tparam A Heap memory allocator class. | ||
27 | */ | ||
28 | template <typename T, class D = SmartPointerDeleter<T>, class A = Allocator> | ||
29 | class UniquePointer : public Object<A>, public api::SmartPointer<T> | ||
30 | { | ||
31 | typedef UniquePointer<T,D,A> Self; | ||
32 | typedef Object<A> Parent; | ||
33 | |||
34 | public: | ||
35 | |||
36 | /** | ||
37 | * @brief Constructor of an empty unique object. | ||
38 | */ | ||
39 | 9 | UniquePointer() | |
40 | : Object<A>() | ||
41 | , api::SmartPointer<T>() | ||
42 | 9 | , pointer_ (NULLPTR) { | |
43 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | bool_t const isConstructed( construct() ); |
44 | 9 | setConstructed(isConstructed); | |
45 | 9 | } | |
46 | |||
47 | /** | ||
48 | * @brief Constructor. | ||
49 | * | ||
50 | * @note If the unique object is not able to be constructed, an object passed by the pointer will be deleted. | ||
51 | * | ||
52 | * @param pointer A pointer to get ownership. | ||
53 | */ | ||
54 | 252 | explicit UniquePointer(T* const pointer) | |
55 | : Object<A>() | ||
56 | , api::SmartPointer<T>() | ||
57 | 252 | , pointer_ (NULLPTR) { | |
58 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
252 | bool_t const isConstructed( construct(pointer) ); |
59 | 252 | setConstructed(isConstructed); | |
60 | 252 | } | |
61 | |||
62 | /** | ||
63 | * @brief Destructor. | ||
64 | */ | ||
65 | 310 | virtual ~UniquePointer() | |
66 | { | ||
67 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 6 times.
|
308 | if( isConstructed() ) |
68 | { | ||
69 |
1/2✓ Branch 1 taken 109 times.
✗ Branch 2 not taken.
|
296 | releasePointer(); |
70 | } | ||
71 | } | ||
72 | |||
73 | #if EOOS_CPP_STANDARD >= 2011 | ||
74 | |||
75 | /** | ||
76 | * @copydoc eoos::Object::Object(Object&&) | ||
77 | */ | ||
78 | 1 | UniquePointer(UniquePointer&& obj) noexcept | |
79 | 1 | : Object<A>( move(obj) ) | |
80 | , api::SmartPointer<T>() | ||
81 | 1 | , pointer_ (obj.pointer_) { | |
82 | 1 | } | |
83 | |||
84 | /** | ||
85 | * @copydoc eoos::Object::operator=(Object&&) | ||
86 | */ | ||
87 | 5 | UniquePointer& operator=(UniquePointer&& obj) & noexcept | |
88 | { | ||
89 |
5/6✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 1 times.
|
5 | if( this != &obj && isConstructed() ) |
90 | { | ||
91 | 4 | releasePointer(); | |
92 | 4 | pointer_ = obj.pointer_; | |
93 | 4 | Parent::operator=( move(obj) ); | |
94 | } | ||
95 | 5 | return *this; | |
96 | } | ||
97 | |||
98 | #endif // EOOS_CPP_STANDARD >= 2011 | ||
99 | |||
100 | /** | ||
101 | * @copydoc eoos::api::Object::isConstructed() | ||
102 | */ | ||
103 | 1482 | virtual bool_t isConstructed() const ///< SCA MISRA-C++:2008 Justified Rule 10-3-1 and Defected Rule 9-3-3 | |
104 | { | ||
105 | 1482 | return Parent::isConstructed(); | |
106 | } | ||
107 | |||
108 | /** | ||
109 | * @brief Casts to boolean data type comparing if the stored pointer does not equal to null. | ||
110 | * | ||
111 | * @return Comparation the stored pointer does not equal to null. | ||
112 | */ | ||
113 | 3 | operator bool_t() const | |
114 | { | ||
115 | 3 | return get() != NULLPTR; | |
116 | } | ||
117 | |||
118 | /** | ||
119 | * @brief Returns the result of dereferencing the stored pointer. | ||
120 | * | ||
121 | * @return The dereferenced stored pointer. | ||
122 | */ | ||
123 | 1 | T& operator*() const | |
124 | { | ||
125 | 1 | return *get(); | |
126 | } | ||
127 | |||
128 | /** | ||
129 | * @brief Returns the stored pointer. | ||
130 | * | ||
131 | * @return The stored pointer or NULLPTR if no pointer stored. | ||
132 | */ | ||
133 | 192 | T* operator->() const | |
134 | { | ||
135 | 192 | return get(); | |
136 | } | ||
137 | |||
138 | /** | ||
139 | * @brief Returns an element of the stored array. | ||
140 | * | ||
141 | * @param index An element index. | ||
142 | * @return An element. | ||
143 | */ | ||
144 | 9 | T& operator[](uint32_t const index) const | |
145 | { | ||
146 | 9 | T* const pointer( get() ); | |
147 | 9 | return pointer[index]; | |
148 | } | ||
149 | |||
150 | /** | ||
151 | * @copydoc eoos::api::SmartPointer::get() | ||
152 | */ | ||
153 | 523 | virtual T* get() const | |
154 | { | ||
155 | 523 | T* pointer( NULLPTR ); | |
156 |
2/2✓ Branch 1 taken 292 times.
✓ Branch 2 taken 3 times.
|
523 | if( isConstructed() ) |
157 | { | ||
158 | 517 | pointer = pointer_; | |
159 | } | ||
160 | 523 | return pointer; | |
161 | } | ||
162 | |||
163 | /** | ||
164 | * @copydoc eoos::api::SmartPointer::reset() | ||
165 | */ | ||
166 | 13 | virtual void reset() | |
167 | { | ||
168 | 13 | reset(NULLPTR); | |
169 | 13 | } | |
170 | |||
171 | /** | ||
172 | * @copydoc eoos::api::SmartPointer::reset(T*) | ||
173 | */ | ||
174 | 15 | virtual void reset(T* ptr) | |
175 | { | ||
176 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
15 | if (get() != ptr) |
177 | { | ||
178 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
15 | Self temp(ptr); |
179 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
15 | swap(temp); |
180 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
15 | } |
181 | 15 | } | |
182 | |||
183 | /** | ||
184 | * @copydoc eoos::api::SmartPointer::getCount() | ||
185 | */ | ||
186 | 108 | virtual int32_t getCount() const | |
187 | { | ||
188 | 108 | int32_t counter( 0 ); | |
189 |
6/6✓ Branch 1 taken 48 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 34 times.
✓ Branch 6 taken 20 times.
|
108 | if( isConstructed() && (pointer_ != NULLPTR) ) |
190 | { | ||
191 | 68 | counter = 1; | |
192 | } | ||
193 | 108 | return counter; | |
194 | } | ||
195 | |||
196 | /** | ||
197 | * @copydoc eoos::api::SmartPointer::isNull() | ||
198 | */ | ||
199 | 229 | virtual bool_t isNull() const | |
200 | { | ||
201 | 229 | return get() == NULLPTR; | |
202 | } | ||
203 | |||
204 | /** | ||
205 | * @copydoc eoos::api::SmartPointer::isUnique() | ||
206 | */ | ||
207 | 52 | virtual bool_t isUnique() const | |
208 | { | ||
209 | 52 | return getCount() == 1; | |
210 | } | ||
211 | |||
212 | /** | ||
213 | * @brief Swaps this managed object with an object managed by given smart object. | ||
214 | * | ||
215 | * @param obj A smart object to swap managed objects. | ||
216 | */ | ||
217 | 19 | void swap(UniquePointer& obj) | |
218 | { | ||
219 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
19 | if( isConstructed() ) |
220 | { | ||
221 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
19 | if( obj.isConstructed() ) |
222 | { | ||
223 | 19 | T* const pointer( pointer_ ); | |
224 | 19 | pointer_ = obj.pointer_; | |
225 | 19 | obj.pointer_ = pointer; | |
226 | } | ||
227 | } | ||
228 | 19 | } | |
229 | |||
230 | /** | ||
231 | * @brief Releases ownership of the managed object. | ||
232 | * | ||
233 | * @return Released raw pointer. | ||
234 | */ | ||
235 | 175 | T* release() | |
236 | { | ||
237 | 175 | T* pointer( pointer_ ); | |
238 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
175 | if( isConstructed() ) |
239 | { | ||
240 | 175 | pointer_ = NULLPTR; | |
241 | } | ||
242 | 175 | return pointer; | |
243 | } | ||
244 | |||
245 | protected: | ||
246 | |||
247 | using Parent::setConstructed; | ||
248 | |||
249 | private: | ||
250 | |||
251 | /** | ||
252 | * @brief Constructs this object. | ||
253 | * | ||
254 | * @param pointer A pointer to get ownership. | ||
255 | * @return True if this object has been constructed successfully. | ||
256 | */ | ||
257 | 270 | bool_t construct(T* const pointer = NULLPTR) | |
258 | { | ||
259 | 270 | bool_t res( false ); | |
260 | do | ||
261 | { | ||
262 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 153 times.
|
270 | if( !isConstructed() ) |
263 | { ///< UT Justified Branch: HW dependency | ||
264 | ✗ | D::free(pointer); | |
265 | ✗ | break; | |
266 | } | ||
267 | 270 | pointer_ = pointer; | |
268 | 270 | res = true; | |
269 | } while(false); | ||
270 | 270 | return res; | |
271 | } | ||
272 | |||
273 | /** | ||
274 | * @brief Releases the managed object by control block. | ||
275 | */ | ||
276 | 268 | void releasePointer() | |
277 | { | ||
278 | 268 | D::free(pointer_); | |
279 | 268 | pointer_ = NULLPTR; | |
280 | 268 | } | |
281 | |||
282 | #if EOOS_CPP_STANDARD < 2011 | ||
283 | |||
284 | /** | ||
285 | * @copydoc eoos::Object::Object(Object const&) | ||
286 | */ | ||
287 | UniquePointer(UniquePointer const&); | ||
288 | |||
289 | /** | ||
290 | * @copydoc eoos::Object::operator=(Object const&) | ||
291 | */ | ||
292 | UniquePointer& operator=(UniquePointer const&); | ||
293 | |||
294 | #endif // EOOS_CPP_STANDARD < 2011 | ||
295 | |||
296 | /** | ||
297 | * @brief Pointer to the managed object. | ||
298 | */ | ||
299 | T* pointer_; | ||
300 | |||
301 | }; | ||
302 | |||
303 | /** | ||
304 | * @brief Comparison operator to equal. | ||
305 | * | ||
306 | * @param obj1 Reference to object. | ||
307 | * @param obj2 Reference to object. | ||
308 | * @return True if objects are equal. | ||
309 | */ | ||
310 | template <typename T, class D, class A> | ||
311 | 2 | inline bool_t operator==(UniquePointer<T,D,A> const& obj1, UniquePointer<T,D,A> const& obj2) | |
312 | { | ||
313 | 2 | return obj1.get() == obj2.get(); | |
314 | } | ||
315 | |||
316 | /** | ||
317 | * @brief Comparison operator to unequal. | ||
318 | * | ||
319 | * @param obj1 Reference to object. | ||
320 | * @param obj2 Reference to object. | ||
321 | * @return True if objects are not equal. | ||
322 | */ | ||
323 | template <typename T, class D, class A> | ||
324 | 2 | inline bool_t operator!=(UniquePointer<T,D,A> const& obj1, UniquePointer<T,D,A> const& obj2) | |
325 | { | ||
326 | 2 | return obj1.get() != obj2.get(); | |
327 | } | ||
328 | |||
329 | #endif // EOOS_ENABLE_DYNAMIC_HEAP_MEMORY | ||
330 | |||
331 | } // namespace lib | ||
332 | } // namespace eoos | ||
333 | #endif // LIB_UNIQUEPOINTER_HPP_ | ||
334 |