GCC Code Coverage Report


Directory: src/gate/
File: src/gate/memalloc.hpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 57 63 90.5%
Functions: 194 534 36.3%
Branches: 5 12 41.7%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 /** @file
30 * @brief Memory allocation and type construction/destruction functions
31 * @ingroup gatecore_cpp
32 */
33
34 #ifndef GATE_MEMALLOC_HPP_INCLUDED
35 #define GATE_MEMALLOC_HPP_INCLUDED
36
37 #include "gate/gate_core_api.hpp"
38 #include "gate/memalloc.h"
39 #include "gate/gatetypes.hpp"
40 #include "gate/results.hpp"
41 #include <new>
42
43 namespace gate
44 {
45 typedef ::gate_exception_info_t exception_info_t;
46
47
48 GATE_CORE_CPP_API extern exception_info_t catchException(IRunnable& runner) noexcept;
49 GATE_CORE_CPP_API extern exception_info_t catchException(gate_entrypoint_t dispatcher, void* param) noexcept;
50 GATE_CORE_CPP_API extern exception_info_t catchCurrentException() noexcept;
51
52
53
54 /**
55 * @brief Generic memory allocation functions
56 */
57 struct GATE_CORE_CPP_API Mem
58 {
59 public:
60 static void* alloc(size_t sz) noexcept; /**< Allocates the given amount of bytes from process heap */
61 static void* realloc(void* ptr, size_t newsz) noexcept; /**< Reallocates a memory block to the given amount of bytes */
62 static void dealloc(void* ptr) noexcept; /**< Deallocates a memory block from process heap */
63 static void* copy(void* dst, void const* src, size_t sz) noexcept; /**< Copies a block of memory from a source to a destination address */
64 static void* move(void* dst, void const* src, size_t sz) noexcept; /**< Copies a block of memory by handling overlapping areas */
65 static void clear(void* ptr, size_t size) noexcept; /**< Clears all bits a given range of memory (overwrites with zero) */
66 static void fill(void* ptr, char chr, size_t count) noexcept; /**< Fills all bytes in a given range of memory with a specific char value */
67 static intptr_t compare(void const* ptr1, void const* ptr2, size_t sz) noexcept; /**< Compares two memory blocks and returns: -1 if first is small, +1 if second is small, 0 if both are equal */
68 static void reverse(void* ptr, size_t sz) noexcept; /**< Reverses all bytes in a memory block, [1,2,3] -> [3,2,1] */
69 static void* copyReverse(void* dst, void const* src, size_t sz) noexcept;/**< Copies bytes from source to destination buffer in reverse order (dst first byte == src last byte) */
70
71 template<class T>
72 6523 static void clear(T& dataRef) noexcept
73 {
74 6523 Mem::clear(&dataRef, sizeof(dataRef));
75 6523 }
76
77 template<class T>
78 373 static void copy(T& dst, T const& src) noexcept
79 {
80 373 Mem::copy(&dst, &src, sizeof(src));
81 373 }
82
83 template<class T>
84 1 static void move(T& dst, T const& src) noexcept
85 {
86 1 Mem::move(&dst, &src, sizeof(src));
87 1 }
88
89 template<class T>
90 static intptr_t compare(T const& ref1, T const& ref2) noexcept
91 {
92 return Mem::compare(&ref1, &ref2, sizeof(ref1));
93 }
94 };
95
96
97 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
98 template<class T>
99 1227 T&& moveRef(T& src)
100 {
101 1227 return static_cast<T&&>(src);
102 }
103
104 template<class T>
105 T&& forwardRef(T& src)
106 {
107 return static_cast<T&&>(src);
108 }
109
110 #else
111 template<class T>
112 T& moveRef(T& src)
113 {
114 return src;
115 }
116
117 template<class T>
118 T& forwardRef(T& src)
119 {
120 return src;
121 }
122 #endif
123
124 template<class T>
125 T const& forwardRef(T const& src)
126 {
127 return src;
128 }
129
130 template<class T>
131 struct TypeSwap
132 {
133 public:
134 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
135 286 static void swap(T& t1, T& t2)
136 {
137 286 T temp(moveRef(t1));
138 286 t1 = moveRef(t2);
139 286 t2 = moveRef(temp);
140 286 }
141 120 static void swapNoExcept(T& t1, T& t2) noexcept
142 {
143 120 T temp(moveRef(t1));
144 120 t1 = moveRef(t2);
145 120 t2 = moveRef(temp);
146 120 }
147 #else
148 static void swap(T& t1, T& t2)
149 {
150 T temp(t1);
151 t1 = t2;
152 t2 = temp;
153 }
154 static void swapNoExcept(T& t1, T& t2) noexcept
155 {
156 T temp(t1);
157 t1 = t2;
158 t2 = temp;
159 }
160 #endif
161
162 };
163
164 template<class T>
165 286 void swapRefs(T& t1, T& t2)
166 {
167 286 TypeSwap<T>::swap(t1, t2);
168 286 }
169
170 template<class T>
171 120 void swapRefsNoExcept(T& t1, T& t2) noexcept
172 {
173 120 TypeSwap<T>::swapNoExcept(t1, t2);
174 120 }
175
176
177
178 /**
179 * @brief Constructs a new object instance (constructor with no arguments) on a preallocated memory location
180 */
181 template<class T> static T* constructType(T* destMem)
182 {
183 new (static_cast<void*>(destMem)) T;
184 return destMem;
185 }
186
187 /**
188 * @brief Constructs a new object instance by its copy-constructor on a preallocated memory location
189 */
190 2108 template<class T> static T* copyConstructType(T* destMem, T const& src)
191 {
192
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2108 new (static_cast<void*>(destMem)) T(src);
193 2108 return destMem;
194 }
195
196 /**
197 * @brief Constructs a new object instance by moving contents of another object on a preallocated memory location
198 */
199 template<class T> static T* moveConstructType(T* destMem, T& src)
200 {
201 new (static_cast<void*>(destMem)) T(moveRef(src));
202 return destMem;
203 }
204
205 /**
206 * @brief Destructs an object (destructor invocation) at a specific address (no memory deallocation of the target pointer itself is performed)
207 */
208 2102 template<class T> static void destructType(T* ptrMem) noexcept
209 {
210 2 ptrMem->~T();
211 2102 }
212
213
214 /**
215 * @brief Collection of C-constructor & destructor functions for C++ objects
216 * @details These functions are used in C-objects that need to construct/destruct C++ types
217 */
218 template<class T>
219 struct TypeFunctions
220 {
221 private:
222 struct ConstructionResult
223 {
224 void* targetAddress;
225 void const* sourceAddress;
226 void* resultAddress;
227
228 10707 ConstructionResult(void* target = NULL, void const* source = NULL)
229 10707 : targetAddress(target), sourceAddress(source), resultAddress(NULL)
230 {
231 10707 }
232 };
233
234 2 static result_t dispatchConstruct(void* ptrConstructionResult)
235 {
236 2 ConstructionResult& constrResult = *static_cast<ConstructionResult*>(ptrConstructionResult);
237
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 void* ptrNew = static_cast<void*>(new (constrResult.targetAddress) T);
238 2 constrResult.resultAddress = ptrNew;
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 return (ptrNew == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
240 }
241
242 10705 static result_t dispatchCopyConstruct(void* ptrConstructionResult)
243 {
244 10705 ConstructionResult& constrResult = *static_cast<ConstructionResult*>(ptrConstructionResult);
245 10705 T const* srcObj = static_cast<T const*>(constrResult.sourceAddress);
246
1/2
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
10705 void* ptrNew = static_cast<void*>(new (constrResult.targetAddress) T(*srcObj));
247 10705 constrResult.resultAddress = ptrNew;
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5941 times.
10705 return (ptrNew == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
249 }
250
251 public:
252
253 /**
254 * @brief default C++ constructor encapsulation compatible with \p gate_mem_ctor_t
255 */
256 static void* construct(void* destMem) noexcept
257 {
258 ConstructionResult result(destMem);
259 gate_exception_info_t xinfo = catchException(&dispatchConstruct, &result);
260 if (GATE_SUCCEEDED(xinfo.result_code))
261 {
262 return result.resultAddress;
263 }
264 return NULL;
265 }
266
267 /**
268 * @brief C++ copy-constructor encapsulation compatible with \p gate_mem_copyctor_t
269 */
270 10707 static result_t copyConstruct(void* destMem, void const* srcMem) noexcept
271 {
272 10707 ConstructionResult result(destMem, srcMem);
273 gate_exception_info_t xinfo;
274
2/2
✓ Branch 0 taken 5941 times.
✓ Branch 1 taken 1 times.
10707 if (srcMem)
275 {
276 10705 xinfo = catchException(&dispatchCopyConstruct, &result);
277 }
278 else
279 {
280 2 xinfo = catchException(&dispatchConstruct, &result);
281 }
282 10707 return xinfo.result_code;
283 }
284
285 /**
286 * @brief C++ destructor encapsulation compatible with \p gate_mem_dtor_t
287 */
288 10605 static void destruct(void* dstMem) noexcept
289 {
290 10605 T* dstObj = static_cast<T*>(dstMem);
291 1112 dstObj->~T();
292 10605 }
293 };
294
295
296 } // end of namespace gate
297
298 #endif
299