1
2
3 /*
4 A* -------------------------------------------------------------------
5 B* This file contains source code for the PyMOL computer program
6 C* Copyright (c) Schrodinger, LLC.
7 D* -------------------------------------------------------------------
8 E* It is unlawful to modify or remove this copyright notice.
9 F* -------------------------------------------------------------------
10 G* Please see the accompanying LICENSE file for further information.
11 H* -------------------------------------------------------------------
12 I* Additional authors of this source file include:
13 -*
14 -*
15 -*
16 Z* -------------------------------------------------------------------
17 */
18 #ifndef _H_MemoryDebug
19 #define _H_MemoryDebug
20
21 #include <vector>
22
23 #include "os_std.h"
24 #include "PyMOLGlobals.h"
25
26
27 /* ================================================================
28 * Don't touch below unless you know what you are doing */
29
30 typedef struct VLARec {
31 ov_size size, unit_size;
32 float grow_factor;
33 bool auto_zero;
34 } VLARec;
35
36
37 /* NOTE: in VLACheck, rec is a zero based array index, not a record count */
38 #define VLACheck(ptr,type,rec) VLACheck2<type>(ptr, rec)
39
40 #define VLAlloc(type,init_size) (type*)VLAMalloc(init_size,sizeof(type),5,0)
41 #define VLACalloc(type,init_size) (type*)VLAMalloc(init_size,sizeof(type),5,1)
42 #define VLASize(ptr,type,size) VLASize2<type>(ptr,size)
43 #define VLASizeForSure(ptr,type,size) VLASizeForSure2<type>(ptr,size)
44
45 #define VLACopy(ptr,type) (type*)VLANewCopy(ptr);
46 #define VLAInsert(ptr,type,index,count) {ptr=(type*)VLAInsertRaw(ptr,index,count);}
47 #define VLADelete(ptr,type,index,count) {ptr=(type*)VLADeleteRaw(ptr,index,count);}
48
49 namespace pymol
50 {
51 using ::free;
52
53 struct default_free {
operatordefault_free54 void operator()(void* ptr) const { free(ptr); }
55 };
56
malloc(size_t num)57 template <typename T> T* malloc(size_t num)
58 {
59 return (T*) ::malloc(num * sizeof(T));
60 }
61
calloc(size_t num)62 template <typename T> T* calloc(size_t num)
63 {
64 return (T*) ::calloc(num, sizeof(T));
65 }
66
realloc(T * ptr,size_t num)67 template <typename T> T* realloc(T* ptr, size_t num)
68 {
69 return (T*) ::realloc(ptr, num * sizeof(T));
70 }
71 } // namespace pymol
72
73 #define FreeP(ptr) {if(ptr) {mfree(ptr);ptr=NULL;}}
74 #define DeleteP(ptr) {if(ptr) {delete ptr;ptr=NULL;}}
75 #define DeleteAP(ptr) {if(ptr) {delete[] ptr;ptr=NULL;}}
76
77 void *VLAExpand(void *ptr, ov_size rec); /* NOTE: rec is index (total-1) */
78 void *MemoryReallocForSure(void *ptr, size_t newSize);
79 void *MemoryReallocForSureSafe(void *ptr, size_t newSize, size_t oldSize);
80
81 void *VLADeleteRaw(void *ptr, int index, unsigned int count);
82 void *VLAInsertRaw(void *ptr, int index, unsigned int count);
83
84 void *VLAMalloc(ov_size init_size, ov_size unit_size, unsigned int grow_factor, int auto_zero); /*growfactor 1-10 */
85
86 void VLAFree(void *ptr);
87 void *VLASetSize(void *ptr, size_t newSize);
88 void *VLASetSizeForSure(void *ptr, size_t newSize);
89
90 size_t VLAGetSize(const void *ptr);
91 void *VLANewCopy(const void *ptr);
92 void MemoryZero(char *p, char *q);
93
94
95 #define mfree pymol::free
96 #define mstrdup strdup
97 #define ReallocForSure(ptr,type,size) (type*)MemoryReallocForSure(ptr,sizeof(type)*(size))
98
99
VLAGetByteSize(const void * ptr)100 inline size_t VLAGetByteSize(const void *ptr) {
101 const VLARec *vla = ((const VLARec *) ptr) - 1;
102 return vla->size * vla->unit_size;
103 }
104
105 /*
106 * Templated version of the `VLACopy` macro
107 */
108 template <typename T>
VLACopy2(const T * vla)109 T * VLACopy2(const T * vla) {
110 return VLACopy((void*)vla, T);
111 }
112
113 /*
114 * @brief std::vector version of VLACheck. Checks to see if index i is valid for insertion.
115 * If not, a resize will be attempted.
116 * @param vec: vector whose size will be check for valid insertion at index i
117 * @param i: index for position where an element may be inserted into vec
118 * Note: Use of this function should be limited. Used for safe replacement of VLACheck
119 * Note: This function can throw.
120 */
121 template <typename T>
VecCheck(std::vector<T> & vec,std::size_t i)122 void VecCheck(std::vector<T> &vec, std::size_t i){
123 if(i >= vec.size()){
124 vec.resize(i + 1);
125 }
126 }
127
128 /**
129 * @brief Similar to VecCheck but constructs objects with arguments. Useful when
130 * no default constructor available.
131 * @tparam T type of elements in vector and also created during resize
132 * @tparam Ts types of T's constructor arguments
133 * @param vec: vector whose size will be check for valid insertion at index i
134 * @param i: index for position where an element may be inserted into vec
135 * @param args: constructor arguments of T
136 */
137 template <typename T, typename... Ts>
VecCheckEmplace(std::vector<T> & vec,std::size_t i,Ts...args)138 void VecCheckEmplace(std::vector<T>& vec, std::size_t i, Ts... args)
139 {
140 vec.reserve(i + 1);
141 for (auto s = vec.size(); s <= i; s++) {
142 vec.emplace_back(args...);
143 }
144 }
145
146 template <typename T>
VLACheck2(T * & ptr,size_t pos)147 T* VLACheck2(T*& ptr, size_t pos) {
148 if (pos >= ((VLARec*) ptr)[-1].size) {
149 ptr = static_cast<T*>(VLAExpand(ptr, pos));
150 }
151 return ptr;
152 }
153
154 template <typename T>
VLASize2(T * & ptr,size_t size)155 void VLASize2(T*& ptr, size_t size) {
156 ptr = static_cast<T*>(VLASetSize(ptr, size));
157 }
158
159 template <typename T>
VLASizeForSure2(T * & ptr,size_t size)160 void VLASizeForSure2(T*& ptr, size_t size) {
161 ptr = static_cast<T*>(VLASetSizeForSure(ptr, size));
162 }
163
164 template <typename T>
VLAFreeP(T * & ptr)165 void VLAFreeP(T*& ptr) {
166 if (ptr) {
167 VLAFree(ptr);
168 ptr = nullptr;
169 }
170 }
171
172 #endif
173
174 // vi:sw=2:expandtab
175