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