Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / CDTestFramework / Opcode / Ice / IceMemoryMacros.h
1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 /**
3  *      Contains all memory macros.
4  *      \file           IceMemoryMacros.h
5  *      \author         Pierre Terdiman
6  *      \date           April, 4, 2000
7  */
8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 // Include Guard
12 #ifndef ICEMEMORYMACROS_H
13 #define ICEMEMORYMACROS_H
14
15 #undef ZeroMemory
16 #undef CopyMemory
17 #undef MoveMemory
18 #undef FillMemory
19
20         //!     Clears a buffer.
21         //!     \param          addr    [in] buffer address
22         //!     \param          size    [in] buffer length
23         //!     \see            FillMemory
24         //!     \see            StoreDwords
25         //!     \see            CopyMemory
26         //!     \see            MoveMemory
27         inline_ void ZeroMemory(void* addr, regsize size)                                       { memset(addr, 0, size);                }
28
29         //!     Fills a buffer with a given byte.
30         //!     \param          addr    [in] buffer address
31         //!     \param          size    [in] buffer length
32         //!     \param          val             [in] the byte value
33         //!     \see            StoreDwords
34         //!     \see            ZeroMemory
35         //!     \see            CopyMemory
36         //!     \see            MoveMemory
37         inline_ void FillMemory(void* dest, regsize size, ubyte val)                    { memset(dest, val, size);              }
38
39         //!     Fills a buffer with a given dword.
40         //!     \param          addr    [in] buffer address
41         //!     \param          nb              [in] number of dwords to write
42         //!     \param          value   [in] the dword value
43         //!     \see            FillMemory
44         //!     \see            ZeroMemory
45         //!     \see            CopyMemory
46         //!     \see            MoveMemory
47         //!     \warning        writes nb*4 bytes !
48         inline_ void StoreDwords(udword* dest, udword nb, udword value)
49         {
50                 // The asm code below **SHOULD** be equivalent to one of those C versions
51                 // or the other if your compiled is good: (checked on VC++ 6.0)
52                 //
53                 //      1) while(nb--)  *dest++ = value;
54                 //
55                 //      2) for(udword i=0;i<nb;i++)     dest[i] = value;
56                 //
57                 _asm push eax
58                 _asm push ecx
59                 _asm push edi
60                 _asm mov edi, dest
61                 _asm mov ecx, nb
62                 _asm mov eax, value
63                 _asm rep stosd
64                 _asm pop edi
65                 _asm pop ecx
66                 _asm pop eax
67         }
68
69         //!     Copies a buffer.
70         //!     \param          addr    [in] destination buffer address
71         //!     \param          addr    [in] source buffer address
72         //!     \param          size    [in] buffer length
73         //!     \see            ZeroMemory
74         //!     \see            FillMemory
75         //!     \see            StoreDwords
76         //!     \see            MoveMemory
77         inline_ void CopyMemory(void* dest, const void* src, regsize size)      { memcpy(dest, src, size);              }
78
79         //!     Moves a buffer.
80         //!     \param          addr    [in] destination buffer address
81         //!     \param          addr    [in] source buffer address
82         //!     \param          size    [in] buffer length
83         //!     \see            ZeroMemory
84         //!     \see            FillMemory
85         //!     \see            StoreDwords
86         //!     \see            CopyMemory
87         inline_ void MoveMemory(void* dest, const void* src, regsize size)      { memmove(dest, src, size);             }
88
89         //!     Flexible buffer copy
90         //!     \param          src                     [in] source buffer address
91         //!     \param          dst                     [in] destination buffer address
92         //!     \param          nb_elem         [in] number of elements to copy
93         //!     \param          elem_size       [in] size of an element
94         //!     \param          stride          [in] stride in bytes, including size of element
95         inline_ void FlexiCopy(const void* src, void* dst, udword nb_elem, regsize elem_size, udword stride)
96         {
97                 ubyte* d = (ubyte*)dst;
98                 const ubyte* s = (const ubyte*)src;
99                 const ubyte* Last = s + stride*nb_elem;
100                 while(s!=Last)
101                 {
102                         CopyMemory(d, s, elem_size);
103                         d += elem_size;
104                         s += stride;
105                 }
106         }
107
108         //! Gives the size of current object. This avoids some mistakes (e.g. "sizeof(this)").
109         #define SIZEOFOBJECT            sizeof(*this)
110
111         //! Clears current object. Laziness is my business! HANDLE WITH CARE. ### Removed, too dangerous, cleared too many v-tables
112         //#define CLEAROBJECT           { memset(this, 0, SIZEOFOBJECT);        }
113
114         // The two macros below are here for several reasons:
115         // - sometimes we write "delete x" instead of "delete []x" just because we don't pay attention. Using the macro forces you
116         //   to think about what you're deleting, just because you have to write the macro's name (SINGLE or ARRAY).
117         // - always clearing the pointer afterwards prevents some double-deletion in various situations.
118         // - deleting null is a valid operation according to the standard, yet some lame memory managers don't like it. In sake of
119         //   robustness, we avoid trying.
120
121         //! Deletes an instance of a class.
122         #define DELETESINGLE(x)         if (x) { delete x;                              x = null; }
123         //! Deletes an array.
124         #define DELETEARRAY(x)          if (x) { delete []x;                    x = null; }
125
126         //! Safe D3D-style release
127         #define SAFE_RELEASE(x)         if (x) { (x)->Release();                (x) = null; }
128
129         //! Safe ICE-style release
130         #define SAFE_DESTRUCT(x)        if (x) { (x)->SelfDestruct();   (x) = null; }
131
132 #ifdef ICEERROR_H
133         //! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE.
134         #define CHECKALLOC(x)           if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY);
135 #else
136         #define CHECKALLOC(x)           if(!x) return false;
137 #endif
138
139         //! Standard allocation cycle
140         #define SAFE_ALLOC(ptr, type, count)            DELETEARRAY(ptr);       ptr = new type[count];          CHECKALLOC(ptr);
141         #define SAFE_ICE_ALLOC(ptr, type, count)        DELETEARRAY(ptr);       ptr = ICE_NEW(type)[count];     CHECKALLOC(ptr);
142
143         //! Don't use inline for alloca !!!
144 #ifdef WIN32
145         #define StackAlloc(x)   _alloca(x)
146 #elif LINUX
147         #define StackAlloc(x)   alloca(x)
148 #elif defined(__APPLE__)
149         #define StackAlloc(x)   alloca(x)
150 #elif defined(_XBOX)
151         #define StackAlloc(x)   _alloca(x)
152 #endif
153
154 #ifdef _DEBUG
155 //      #define ICE_ALLOC_TMP(x)                GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP)
156 //      #define ICE_ALLOC(x)                    GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT)
157         #define ICE_ALLOC_TMP(x)                GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP)
158         #define ICE_ALLOC(x)                    GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT)
159         #define ICE_ALLOC_TMP2(x, y)    GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP)
160         #define ICE_ALLOC2(x, y)                GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT)
161 #else
162         #define ICE_ALLOC_TMP(x)                GetAllocator()->malloc(x, MEMORY_TEMP)
163         #define ICE_ALLOC(x)                    GetAllocator()->malloc(x, MEMORY_PERSISTENT)
164 #endif
165         #define ICE_FREE(x)                             if(x)   { GetAllocator()->free(x); x = null;    }
166
167 #ifdef DONT_TRACK_MEMORY_LEAKS
168         #ifdef _DEBUG
169                 #define ICE_NEW_TMP(x)          new(__FILE__, __LINE__, #x, MEMORY_TEMP) x
170                 #define ICE_NEW(x)                      new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x
171         #else
172                 #define ICE_NEW_TMP(x)          new(MEMORY_TEMP) x
173                 #define ICE_NEW(x)                      new(MEMORY_PERSISTENT) x
174         #endif
175 #else
176         #define ICE_NEW_TMP(x)                  new x
177         #define ICE_NEW(x)                              new     x
178 #endif
179
180 #endif // ICEMEMORYMACROS_H