|
|
1.1.2.1 paf 1: /** @file
2: Parser: memory reference counting classes decls.
3:
4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
7: */
8:
9: #ifndef PA_MEMORY_H
10: #define PA_MEMORY_H
11:
1.1.2.9 ! paf 12: static const char* IDENT_MEMORY_H="$Date: 2003/03/06 16:15:25 $";
! 13:
! 14: #define PA_DEBUG_REFERENCES
1.1.2.1 paf 15:
16: // include
17:
18: #include "pa_config_includes.h"
19:
20: #ifdef XML
21: # include "gdome.h"
22: // for xmlChar
23: # include "libxml/tree.h"
24: #endif
25:
26: // forwards
27:
1.1.2.2 paf 28: void *pa_fail_alloc(char *what, size_t size);
29:
30: // inlines
31:
32: inline void *pa_malloc(size_t size) {
33: if(void *result=malloc(size))
34: return result;
35:
36: return pa_fail_alloc("allocate", size);
37: }
38:
39: inline void *pa_calloc(size_t size) {
40: if(void *result=calloc(1, size))
41: return result;
42:
43: return pa_fail_alloc("allocate clean", size);
44: }
45: inline void pa_free(void *ptr) {
46: free(ptr);
47: }
48:
49: inline void *pa_realloc(void *ptr, size_t size) {
50: if(void *result=realloc(ptr, size))
51: return result;
52:
53: return pa_fail_alloc("reallocate to", size);
54: }
1.1.2.1 paf 55:
56: template<typename T> class object_ptr {
57: T *ptr;
58: public:
59: typedef T element_type;
60:
61: explicit object_ptr(T *ptr = 0) {
62: this->ptr=ptr;
63: if(ptr)
64: ptr->ref();
65: }
66: template<class B> object_ptr(const object_ptr<B>& src) {
67: this->ptr=src.get();
68: if(ptr)
69: ptr->ref();
70: }
71: object_ptr(const object_ptr<T>& src) {
72: ptr=src.get();
73: if(ptr)
74: ptr->ref();
75: }
76: object_ptr(T *ptr, int) {
77: this->ptr=ptr;
78: }
79: object_ptr<T>& operator=(const object_ptr<T>& src) {
80: if(this!=&src)
81: if(ptr!=src.get()) {
82: if(ptr)
83: ptr->unref();
84: ptr=src.get();
85: if(ptr)
86: ptr->ref();
87: }
88: return *this;
89: }
90: ~object_ptr() {
91: if(ptr)
92: ptr->unref();
93: }
94: T& operator*() const {
95: return *get();
96: }
97: T *operator->() const {
98: return get();
99: }
100: T *get() const {
101: return ptr;
102: }
103: operator bool() const {
104: return get()!=0;
105: }
106: bool operator !() const {
107: return get()==0;
108: }
109: };
110:
111: #define DECLARE_OBJECT_PTR(name) \
112: typedef object_ptr<name> name##Ptr
113:
114: /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr & renamed field/params [not compiled on gcc]
115: template<class T>
116: class smart_ptr {
117: bool owns;
118: T *ptr;
119: public:
120: typedef T element_type;
121: explicit smart_ptr(T *aptr = 0)
122: : owns(aptr != 0), ptr(aptr) {}
123: smart_ptr(const smart_ptr<T>& src)
124: : owns(src.owns), ptr(src.release()) {}
125: smart_ptr<T>& operator=(const smart_ptr<T>& src)
126: {if (this != &src)
127: {if (ptr != src.get())
128: {if (owns)
1.1.2.5 paf 129: delete[] ptr;
1.1.2.1 paf 130: owns = src.owns; }
131: else if (src.owns)
132: owns = true;
133: ptr = src.release(); }
134: return (*this); }
135: ~smart_ptr()
136: {if (owns)
1.1.2.5 paf 137: delete[] ptr; }
1.1.2.1 paf 138: T& operator*() const
139: {return (*get()); }
140: T *get() const
141: {return ptr; }
142: T *release() const
143: {((smart_ptr<T> *)this)->owns = false;
144: return (ptr); }
145: operator bool() const {
146: return get()!=0;
1.1.2.4 paf 147: }
148: bool operator !() const {
149: return get()==0;
1.1.2.1 paf 150: }
151: operator T*() const {
152: return ptr;
153: }
154: };
1.1.2.6 paf 155:
156: #define DECLARE_SMART_PTR(name) \
157: typedef smart_ptr<name> name##Ptr
1.1.2.1 paf 158:
159: // defines
160:
161: #define override
162: #define rethrow throw
163:
164: // memory
165:
166: inline void *operator new[] (size_t size) {
167: return pa_malloc(size);
1.1.2.3 paf 168: }
169: inline void *operator new[] (size_t size, int /*zero, just flag to use calloc instead of malloc*/) {
170: return pa_calloc(size);
1.1.2.1 paf 171: }
172: inline void operator delete[] (void *ptr) {
173: pa_free(ptr);
174: }
175: inline void operator delete (void *ptr) {
176: pa_free(ptr);
177: }
178:
179: class PA_Allocated {
180: public:
181: /// the sole: instances allocated using our functions
182: static void *operator new(size_t size) {
183: return pa_malloc(size);
184: }
185: static void operator delete(void *ptr) {
186: pa_free(ptr);
187: }
188: static void *malloc(size_t size) {
189: return pa_malloc(size);
190: }
191: static void *calloc(size_t size) {
192: return pa_calloc(size);
193: }
194: static void free(void *ptr) {
195: pa_free(ptr);
196: }
197: static void *realloc(void *ptr, size_t size) {
198: return pa_realloc(ptr, size);
199: }
200:
201: };
202:
1.1.2.9 ! paf 203: #ifdef PA_DEBUG_REFERENCES
! 204: extern const void *refdbg_this;
! 205: void pa_stack_dump(const char *msg);
! 206: #endif
! 207:
1.1.2.1 paf 208: /**
209: Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
210: */
211: class PA_Object: public PA_Allocated {
212: mutable unsigned long freferences;
213: public:
214: PA_Object(): freferences(0) {}
215: virtual ~PA_Object() {}
216:
217: void ref() const {
1.1.2.9 ! paf 218: #ifdef PA_DEBUG_REFERENCES
! 219: if(this==refdbg_this) {
! 220: char buf[0x400];
! 221: _snprintf(buf, sizeof(buf), "[0x%p#%d++]\n", this, freferences);
! 222: pa_stack_dump(buf);
! 223: }
! 224: #endif
1.1.2.1 paf 225: freferences++;
226: }
227: void unref() const {
228: if(freferences) {
1.1.2.9 ! paf 229: #ifdef PA_DEBUG_REFERENCES
! 230: if(this==refdbg_this) {
! 231: char buf[0x400];
! 232: _snprintf(buf, sizeof(buf), "[0x%p#%d--]\n", this, freferences);
! 233: pa_stack_dump(buf);
! 234: }
! 235: #endif
1.1.2.1 paf 236: if(--freferences==0)
237: delete this;
238: }
239: }
1.1.2.7 paf 240: unsigned long references() { return freferences; }
1.1.2.1 paf 241: };
242: DECLARE_OBJECT_PTR(PA_Object);
243:
244: // convinient types
245:
246: typedef smart_ptr<char> CharPtr;
247:
248: #endif