|
|
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.5 ! paf 12: static const char* IDENT_MEMORY_H="$Date: 2003/02/26 11:29:58 $";
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: };
160:
161: // defines
162:
163: #define override
164: #define rethrow throw
165:
166: // memory
167:
168: inline void *operator new[] (size_t size) {
169: return pa_malloc(size);
1.1.2.3 paf 170: }
171: inline void *operator new[] (size_t size, int /*zero, just flag to use calloc instead of malloc*/) {
172: return pa_calloc(size);
1.1.2.1 paf 173: }
174: inline void operator delete[] (void *ptr) {
175: pa_free(ptr);
176: }
177: inline void operator delete (void *ptr) {
178: pa_free(ptr);
179: }
180:
181: class PA_Allocated {
182: public:
183: /// the sole: instances allocated using our functions
184: static void *operator new(size_t size) {
185: return pa_malloc(size);
186: }
187: static void operator delete(void *ptr) {
188: pa_free(ptr);
189: }
190: static void *malloc(size_t size) {
191: return pa_malloc(size);
192: }
193: static void *calloc(size_t size) {
194: return pa_calloc(size);
195: }
196: static void free(void *ptr) {
197: pa_free(ptr);
198: }
199: static void *realloc(void *ptr, size_t size) {
200: return pa_realloc(ptr, size);
201: }
202:
203: };
204:
205: /**
206: Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
207: */
208: class PA_Object: public PA_Allocated {
209: mutable unsigned long freferences;
210: public:
211: PA_Object(): freferences(0) {}
212: virtual ~PA_Object() {}
213:
214: void ref() const {
215: freferences++;
216: }
217: void unref() const {
218: if(freferences) {
219: if(--freferences==0)
220: delete this;
221: }
222: }
223: };
224: DECLARE_OBJECT_PTR(PA_Object);
225:
226: // convinient types
227:
228: typedef smart_ptr<char> CharPtr;
229:
230: #endif