GCC Code Coverage Report


Directory: src/gate/
File: src/gate/memalloc.hpp
Date: 2026-06-21 00:38:37
Exec Total Coverage
Lines: 59 62 95.2%
Functions: 324 629 51.5%
Branches: 5 13 38.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, 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 struct GATE_CORE_CPP_API Catch
48 {
49 public:
50 static exception_info_t exception(IRunnable& runner) noexcept;
51 static exception_info_t exception(gate_entrypoint_t dispatcher, void* param) noexcept;
52 static exception_info_t currentException() noexcept;
53 };
54
55
56
57 /**
58 * @brief Generic memory allocation functions
59 */
60 struct GATE_CORE_CPP_API Mem
61 {
62 public:
63 static void* alloc(size_t sz) noexcept; /**< Allocates the given amount of bytes from process heap */
64 static void* realloc(void* ptr, size_t newsz) noexcept; /**< Reallocates a memory block to the given amount of bytes */
65 static void dealloc(void* ptr) noexcept; /**< Deallocates a memory block from process heap */
66 static void* copy(void* dst, void const* src, size_t sz) noexcept; /**< Copies a block of memory from a source to a destination address */
67 static void* move(void* dst, void const* src, size_t sz) noexcept; /**< Copies a block of memory by handling overlapping areas */
68 static void clear(void* ptr, size_t size) noexcept; /**< Clears all bits a given range of memory (overwrites with zero) */
69 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 */
70 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 */
71 static void reverse(void* ptr, size_t sz) noexcept; /**< Reverses all bytes in a memory block, [1,2,3] -> [3,2,1] */
72 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) */
73
74 template<class T>
75 3952 static void clear(T& dataRef) noexcept
76 {
77 3952 Mem::clear(&dataRef, sizeof(dataRef));
78 3952 }
79
80 template<class T>
81 674 static void copy(T& dst, T const& src) noexcept
82 {
83 674 Mem::copy(&dst, &src, sizeof(src));
84 674 }
85
86 template<class T>
87 1 static void move(T& dst, T const& src) noexcept
88 {
89 1 Mem::move(&dst, &src, sizeof(src));
90 1 }
91
92 template<class T>
93 static intptr_t compare(T const& ref1, T const& ref2) noexcept
94 {
95 return Mem::compare(&ref1, &ref2, sizeof(ref1));
96 }
97 };
98
99
100 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
101 template<class T>
102 2253 T&& moveRef(T& src)
103 {
104 2253 return static_cast<T&&>(src);
105 }
106
107 template<class T>
108 T&& forwardRef(T& src)
109 {
110 return static_cast<T&&>(src);
111 }
112
113 #else
114 template<class T>
115 T& moveRef(T& src)
116 {
117 return src;
118 }
119
120 template<class T>
121 T& forwardRef(T& src)
122 {
123 return src;
124 }
125 #endif
126
127 template<class T>
128 1 T const& forwardRef(T const& src)
129 {
130 1 return src;
131 }
132
133 template<class T>
134 struct TypeSwap
135 {
136 public:
137 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
138 509 static void swap(T& t1, T& t2)
139 {
140 509 T temp(moveRef(t1));
141 509 t1 = moveRef(t2);
142 509 t2 = moveRef(temp);
143 509 }
144 216 static void swapNoExcept(T& t1, T& t2) noexcept
145 {
146 216 T temp(moveRef(t1));
147 216 t1 = moveRef(t2);
148 216 t2 = moveRef(temp);
149 216 }
150 #else
151 static void swap(T& t1, T& t2)
152 {
153 T temp(t1);
154 t1 = t2;
155 t2 = temp;
156 }
157 static void swapNoExcept(T& t1, T& t2) noexcept
158 {
159 T temp(t1);
160 t1 = t2;
161 t2 = temp;
162 }
163 #endif
164
165 };
166
167 template<class T>
168 509 void swapRefs(T& t1, T& t2)
169 {
170 509 TypeSwap<T>::swap(t1, t2);
171 509 }
172
173 template<class T>
174 216 void swapRefsNoExcept(T& t1, T& t2) noexcept
175 {
176 216 TypeSwap<T>::swapNoExcept(t1, t2);
177 216 }
178
179
180
181 /**
182 * @brief Constructs a new object instance (constructor with no arguments) on a preallocated memory location
183 */
184 template<class T> T* constructType(T* destMem)
185 {
186 new (static_cast<void*>(destMem)) T;
187 return destMem;
188 }
189
190 /**
191 * @brief Constructs a new object instance by its copy-constructor on a preallocated memory location
192 */
193 123392 template<class T> T* copyConstructType(T* destMem, T const& src)
194 {
195
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
123392 new (static_cast<void*>(destMem)) T(src);
196 123392 return destMem;
197 }
198
199 /**
200 * @brief Constructs a new object instance by moving contents of another object on a preallocated memory location
201 */
202 template<class T> T* moveConstructType(T* destMem, T& src)
203 {
204 new (static_cast<void*>(destMem)) T(moveRef(src));
205 return destMem;
206 }
207
208 /**
209 * @brief Destructs an object (destructor invocation) at a specific address (no memory deallocation of the target pointer itself is performed)
210 */
211 123386 template<class T> void destructType(T* ptrMem) noexcept
212 {
213 4 ptrMem->~T();
214 123386 }
215
216
217 /**
218 * @brief Collection of C-constructor & destructor functions for C++ objects
219 * @details These functions are used in C-objects that need to construct/destruct C++ types
220 */
221 template<class T>
222 struct TypeFunctions
223 {
224 private:
225 struct ConstructionResult
226 {
227 void* targetAddress;
228 void const* sourceAddress;
229 void* resultAddress;
230
231 11184 ConstructionResult(void* target = NULL, void const* source = NULL)
232 11184 : targetAddress(target), sourceAddress(source), resultAddress(NULL)
233 {
234 11184 }
235 };
236
237 2 static result_t GATE_CALL dispatchConstruct(void* ptrConstructionResult)
238 {
239 2 ConstructionResult& constrResult = *static_cast<ConstructionResult*>(ptrConstructionResult);
240
0/3
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 void* ptrNew = static_cast<void*>(new (constrResult.targetAddress) T);
241 2 constrResult.resultAddress = ptrNew;
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 return (ptrNew == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
243 }
244
245 11182 static result_t GATE_CALL dispatchCopyConstruct(void* ptrConstructionResult)
246 {
247 11182 ConstructionResult& constrResult = *static_cast<ConstructionResult*>(ptrConstructionResult);
248 11182 T const* srcObj = static_cast<T const*>(constrResult.sourceAddress);
249
1/2
✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
11182 void* ptrNew = static_cast<void*>(new (constrResult.targetAddress) T(*srcObj));
250 11182 constrResult.resultAddress = ptrNew;
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6527 times.
11182 return (ptrNew == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
252 }
253
254 public:
255
256 /**
257 * @brief default C++ constructor encapsulation compatible with \p gate_mem_ctor_t
258 */
259 static void* GATE_CALL construct(void* destMem) noexcept
260 {
261 ConstructionResult result(destMem);
262 gate_exception_info_t xinfo = Catch::exception(&dispatchConstruct, &result);
263 if (GATE_SUCCEEDED(xinfo.result_code))
264 {
265 return result.resultAddress;
266 }
267 return NULL;
268 }
269
270 /**
271 * @brief C++ copy-constructor encapsulation compatible with \p gate_mem_copyctor_t
272 */
273 11184 static result_t GATE_CALL copyConstruct(void* destMem, void const* srcMem) noexcept
274 {
275 11184 ConstructionResult result(destMem, srcMem);
276 gate_exception_info_t xinfo;
277
2/2
✓ Branch 0 taken 6527 times.
✓ Branch 1 taken 1 times.
11184 if (srcMem)
278 {
279 11182 xinfo = Catch::exception(&dispatchCopyConstruct, &result);
280 }
281 else
282 {
283 2 xinfo = Catch::exception(&dispatchConstruct, &result);
284 }
285 11184 return xinfo.result_code;
286 }
287
288 /**
289 * @brief C++ destructor encapsulation compatible with \p gate_mem_dtor_t
290 */
291 11063 static void GATE_CALL destruct(void* dstMem) noexcept
292 {
293 11063 T* dstObj = static_cast<T*>(dstMem);
294 1087 dstObj->~T();
295 11063 }
296 };
297
298
299 } // end of namespace gate
300
301 #endif
302