Polygon Crucher SDK - Documentation
Documentation
All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
XMemoryMacros.h
Go to the documentation of this file.
1//! @file XMemoryMacros.h
2//! @brief definitions of macros for SDK new / delete / allocation operators.
3//
4//////////////////////////////////////////////////////////////////////////
5// Based on the file MemoryMacros.hpp by Alessandro Di Meco
6//
7// Defines allocation macros :
8// xNew, xNewParams, xDelete => allocate a single object (calling constructor and destructor)
9// xNewArray, xDeleteArray => allocate an array of object (calling constructor and destructor)
10// xAllocateArray, xDeallocateArray => allocate raw data, without any constructor or destructor calls)
11//
12// cf. Note on performance below
13
14#if !defined(CXMEMORYMACROS_INCLUDE_H)
15#define CXMEMORYMACROS_INCLUDE_H
16
17#ifdef _MSC_VER
18#pragma once
19#endif // _MSC_VER
20
21// if MOOTOOLS_USE_NEW_AND_DELETE is not defined, we use a custom allocator
22// that allows to perform callback on any allocation.
23// Otherwise we use the standard c++ new and delete allocator
24#ifndef MOOTOOLS_USE_NEW_AND_DELETE
25 #include <assert.h>
26
27 BEGIN_MOOTOOLS_NAMESPACE
28
29 //! @name Template functions for constructing and deleting objects
30 //!
31 //! @note Compiler optimization removes these functions if the calling class has no constructor or destructor.\n
32 //! This means that it does not consume any time when called on basic types (float, int...)\n
33 //! this also means that xAllocateArray / xDeallocateArray and xNewArray / xDeleteArray has similar performance for basic types.\n
34 //! Anyway xDeallocateArray has the advantage that it does not requires any count parameters.\n
35 //!
36 //! @{
37 template < typename T >
38 void xTDestroy(T* p_pointer)
39 {
40 if (p_pointer != 0)
41 p_pointer->~T();
42 }
43
44 template<typename T>
45 T* xTConstructArray(T* p_pointer, size_t p_count)
46 {
48
50 const T* endPointer = p_pointer + p_count;
51
53 {
55 }
56
58 }
59
61 void xTDestroyArray(const T* p_pointer, size_t p_count)
62 {
64 if (p_pointer == 0)
65 return;
66
67 // The while-loop uses a descending order to preserve the canonical destruction order of C++
68 const T* current = p_pointer + p_count;
69
70 while (p_count--)
71 {
72 (--current)->~T();
73 }
74 }
75
76 template <typename T, bool is_poly>
77 struct xTCast2
78 {
79 static void* cast (T* ptr) { return ptr; }
80 };
81
82 template <typename T>
83 struct xTCast2<T, true>
84 {
85 static void* cast (T* ptr) { return dynamic_cast<void*>(ptr); }
86 };
87
88 template < typename T >
89 void *xTCast(T *p_pointer)
90 {
91 return xTCast2<T, __is_polymorphic(T)>::cast(p_pointer);
92 }
93
94 //! @}
95
96 // Private macros, not to be used
97 //
98 // These macros allow additional check in debugging mode
99 // to control if xAllocate has a pending xDeallocate, xNew/xdelete, xNewArray/xDeleteArray, ...
100 #define xAllocateFunc(p_type, xfunc) \
101 (p_type *)mootools::xfunc(sizeof(p_type))
102
103 #define xDeallocateFunc(p_pointer, xfunc) \
104 mootools::xfunc(p_pointer)
105
106 #define xAllocateArrayFunc(p_type, p_count, xfunc) \
107 (p_type *)mootools::xfunc(sizeof(p_type), p_count)
108
109 #define xDeallocateArrayFunc(p_pointer, p_count, xfunc) \
110 mootools::xfunc(p_pointer, p_count)
111
112 //! @name Simple memory block allocation
113 //!
114 //! * xAllocate: Allocates memory for a single of type p_type.\n
115 //! * xAllocateArray: Allocates memory for an array of type p_type.\n
116 //! * xDeallocate: Deallocate memory pointed by p_pointer.\n
117 //! * xDeallocateArray: Deallocate an memory array pointed by p_pointer.\n
118 //!
119 //! @param p_type The type of object to allocate.
120 //!
121 //! @return A pointer to the allocated memory.
122 //!
123 //! @note xAllocation has no reallocation possibilities.\n
124 //! This introduces incompatibility when MOOTOOLS_USE_NEW_AND_DELETE is defined, because malloc / free allocation are made using a new operator\n
125 //! you can use *xmalloc*, **xfree** and **xrealloc** instead xAllocate if you want to perform standard reallocation.
126 //!
127 //! cf. note below
128 //! @{
129 #define xAllocate(p_type) \
130 xAllocateFunc(p_type, xmalloc)
131
132 #define xDeallocate(p_pointer, xfunc) \
133 xDeallocateFunc(p_type, xfree)
134
135 #define xAllocateArray(p_type, p_count) \
136 xAllocateArrayFunc(p_type, p_count, xmalloc_array)
137
138 #define xDeallocateArray(p_pointer) \
139 xDeallocateArrayFunc(p_pointer, 1, xfree_array)
140
141 //! @}
142
143 //! @name In-place constructor / destructor
144 //!
145 //! * xConstruct: Construct an object of type p_type at the specified memory location.
146 //! * xConstructParams: Construct an object of type p_type at the specified memory location and using specific parameters.
147 //! * xDestroy: Destroy an object pointed by p_pointer.
148 //! * xConstructArray: Construct an array of objects of type p_type at the specified memory location.
149 //! * xDestroyArray: Destroy an array of objects pointed by p_pointer.
150 //!
151 //! @param p_type The type of object to construct.
152 //! @param p_pointer The memory location of the object.
153 //! @param p_count Le length of the array.
154 //!
155 //! @return A pointer to the constructed object.
156 //! @{
157 #define xConstruct(p_type, p_pointer) \
158 new (p_pointer)p_type
159
160 #define xConstructParams(p_type, p_pointer, ...) \
161 new (p_pointer)p_type(__VA_ARGS__)
162
163 #define xConstructArray(p_type, p_pointer, p_count) \
164 mootools::xTConstructArray<p_type>(p_pointer, p_count)
165
166 #define xDestroyArray(p_pointer, p_count) \
167 mootools::xTDestroyArray(p_pointer, p_count)
168
169 #define xDestroy(p_pointer) \
170 mootools::xTDestroy(p_pointer)
171
172 //! @}
173
174 //! @name Memory and inheritance
175 //! xCast is used to correctly destroy the memory allocated by an object in case of multi inheritance\n
176 //! using dynamic_cast for polymorphic object only. Without that the following code fails:\n
177 //! if class AB : public A, public B\n
178 //! AB *ab = xNew(AB); \n
179 //! B *b = (B *)ab; => b points to B object. b pointer is not egal to ab which is the allocated memory\n
180 //! xDelete(b); => fails, b value was never allocated\n
181 //!
182 //! @note xCast is automatically called by xNew, xDelete, xDeleteArray, so you don't have to worry
183 #define xCast(p_pointer) \
184 mootools::xTCast(p_pointer)
185
186 //! @name New and delete operators
187 //!
188 //! * xNew: Construct an object of type p_type. Intended to be used in place of the default new operator.\n
189 //! * xNewParams: Construct an object, providing constructor parameters in place of the default new operator
190 //! * xNewArray: Creates an array of type p_type. Intended to be used in place of the default new[] operator.\n
191 //! * xDelete: Deletes an object. Intended to be used in place of the default delete operator.\n
192 //! * xDeleteArray: Deletes an array. Intended to be used in place of the default delete[] operator.\n
193 //!
194 //! @param p_type The type of object to create.\n
195 //! @param p_count The length of the array.\n
196 //!
197 //! @note If p_type is a template with multiple argument (separated by a comma)
198 //! macro expansion fails. use a typedef in this case
199 //! @{
200 #define xNew(p_type) \
201 xConstruct(p_type, (xAllocateFunc(p_type, xnew)))
202
203 #define xNewParams(p_type, ...) \
204 xConstructParams(p_type, xAllocateFunc(p_type, xnew), __VA_ARGS__)
205
206 #define xNewArray(p_type, p_count) \
207 xConstructArray(p_type, xAllocateArrayFunc(p_type, p_count, xnew_array), p_count)
208
209 #define xDelete(p_pointer) \
210 { \
211 void *dynamic_casted_ptr = xCast(p_pointer); \
212 xDestroy(p_pointer); \
213 xDeallocateFunc(dynamic_casted_ptr, xdelete); \
214 }
215
216 #define xDeleteArray(p_pointer, p_count) \
217 { \
218 void *dynamic_casted_ptr = xCast(p_pointer); \
219 xDestroyArray(p_pointer, p_count); \
220 xDeallocateArrayFunc(dynamic_casted_ptr, p_count, xdelete_array); \
221 }
222
223 //! @}
224 END_MOOTOOLS_NAMESPACE
225#else // MOOTOOLS_USE_NEW_AND_DELETE
226 // take advantage of MFC allocator if present
227 #if defined(_DEBUG) && defined(MOOTOOLS_MFC_PRODUCT_BUILD)
228 // Use MFC allocator. Cf. Note about memory leaks in XMemory.cpp
229 #define new1 DEBUG_NEW
230 #define new2 new // inplace new
231 #else
232 #define new1 new
233 #define new2 new
234 #endif
235
236 // Macros call the standard new / delete operator
237 // Note: xAllocate / xAllocateArray are allocated by new, meaning that xrealloc cannot be called
238 #define xAllocate(p_type) \
239 new1 p_type
240
241 #define xAllocateArray(p_type, p_count) \
242 new1 p_type[p_count]
243
244 #define xDeallocateArray(p_pointer) \
245 delete [] p_pointer
246
247 #define xDeallocateArraySetNull(p_pointer) \
248 { \
249 delete [] p_pointer; \
250 p_pointer = NULL; \
251 }
252
253 #define xConstruct(p_type, p_pointer) \
254 new2 (p_pointer)p_type
255
256 #define xConstructParams(p_type, p_pointer, ...) \
257 new2 (p_pointer)p_type(__VA_ARGS__)
258
259 #define xNew(p_type) \
260 new1 p_type
261
262 #define xNewParams(p_type, ...) \
263 new1 p_type(__VA_ARGS__)
264
265 #define xNewArray(p_type, p_count) \
266 new1 p_type[p_count]
267
268 #define xDelete(p_pointer) \
269 delete p_pointer
270
271 #define xDeleteSetNull(p_pointer) \
272 { \
273 delete p_pointer; \
274 p_pointer = NULL; \
275 }
276
277 #define xDeleteArray(p_pointer, p_count) \
278 delete [] p_pointer
279
280 #define xDeleteArraySetNull(p_pointer, p_count) \
281 { \
282 delete [] p_pointer; \
283 p_pointer = NULL; \
284 }
285
286#endif // MOOTOOLS_USE_NEW_AND_DELETE
287#endif // !defined(CXMEMORYMACROS_INCLUDE_H)
288
The class defines an x, y, z 3D point which can use int, float or double.
Definition 3DPoint.h:27