|
|
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.8 ! paf 12: static const char* IDENT_MEMORY_H="$Date: 2003/03/06 12:58:32 $";
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: }
1.1.2.1 paf 53:
54: template<typename T> class object_ptr {
55: T *ptr;
56: public:
57: typedef T element_type;
58:
59: explicit object_ptr(T *ptr = 0) {
60: this->ptr=ptr;
61: if(ptr)
62: ptr->ref();
63: }
64: template<class B> object_ptr(const object_ptr<B>& src) {
65: this->ptr=src.get();
66: if(ptr)
67: ptr->ref();
68: }
69: object_ptr(const object_ptr<T>& src) {
70: ptr=src.get();
71: if(ptr)
72: ptr->ref();
73: }
74: object_ptr(T *ptr, int) {
75: this->ptr=ptr;
76: }
77: object_ptr<T>& operator=(const object_ptr<T>& src) {
78: if(this!=&src)
79: if(ptr!=src.get()) {
80: if(ptr)
81: ptr->unref();
82: ptr=src.get();
83: if(ptr)
84: ptr->ref();
85: }
86: return *this;
87: }
88: ~object_ptr() {
89: if(ptr)
90: ptr->unref();
91: }
92: T& operator*() const {
93: return *get();
94: }
95: T *operator->() const {
96: return get();
97: }
98: T *get() const {
99: return ptr;
100: }
101: operator bool() const {
102: return get()!=0;
103: }
104: bool operator !() const {
105: return get()==0;
106: }
107: };
108:
109: #define DECLARE_OBJECT_PTR(name) \
110: typedef object_ptr<name> name##Ptr
111:
112: /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr & renamed field/params [not compiled on gcc]
113: template<class T>
114: class smart_ptr {
115: bool owns;
116: T *ptr;
117: public:
118: typedef T element_type;
119: explicit smart_ptr(T *aptr = 0)
120: : owns(aptr != 0), ptr(aptr) {}
121: smart_ptr(const smart_ptr<T>& src)
122: : owns(src.owns), ptr(src.release()) {}
123: smart_ptr<T>& operator=(const smart_ptr<T>& src)
124: {if (this != &src)
125: {if (ptr != src.get())
126: {if (owns)
1.1.2.5 paf 127: delete[] ptr;
1.1.2.1 paf 128: owns = src.owns; }
129: else if (src.owns)
130: owns = true;
131: ptr = src.release(); }
132: return (*this); }
133: ~smart_ptr()
134: {if (owns)
1.1.2.5 paf 135: delete[] ptr; }
1.1.2.1 paf 136: T& operator*() const
137: {return (*get()); }
138: T *get() const
139: {return ptr; }
140: T *release() const
141: {((smart_ptr<T> *)this)->owns = false;
142: return (ptr); }
143: operator bool() const {
144: return get()!=0;
1.1.2.4 paf 145: }
146: bool operator !() const {
147: return get()==0;
1.1.2.1 paf 148: }
149: operator T*() const {
150: return ptr;
151: }
152: };
1.1.2.6 paf 153:
154: #define DECLARE_SMART_PTR(name) \
155: typedef smart_ptr<name> name##Ptr
1.1.2.1 paf 156:
157: // defines
158:
159: #define override
160: #define rethrow throw
161:
162: // memory
163:
164: inline void *operator new[] (size_t size) {
165: return pa_malloc(size);
1.1.2.3 paf 166: }
167: inline void *operator new[] (size_t size, int /*zero, just flag to use calloc instead of malloc*/) {
168: return pa_calloc(size);
1.1.2.1 paf 169: }
170: inline void operator delete[] (void *ptr) {
171: pa_free(ptr);
172: }
173: inline void operator delete (void *ptr) {
174: pa_free(ptr);
175: }
176:
177: class PA_Allocated {
178: public:
179: /// the sole: instances allocated using our functions
180: static void *operator new(size_t size) {
181: return pa_malloc(size);
182: }
183: static void operator delete(void *ptr) {
184: pa_free(ptr);
185: }
186: static void *malloc(size_t size) {
187: return pa_malloc(size);
188: }
189: static void *calloc(size_t size) {
190: return pa_calloc(size);
191: }
192: static void free(void *ptr) {
193: pa_free(ptr);
194: }
195: static void *realloc(void *ptr, size_t size) {
196: return pa_realloc(ptr, size);
197: }
198:
199: };
200:
201: /**
202: Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
203: */
204: class PA_Object: public PA_Allocated {
205: mutable unsigned long freferences;
206: public:
207: PA_Object(): freferences(0) {}
208: virtual ~PA_Object() {}
209:
210: void ref() const {
211: freferences++;
212: }
213: void unref() const {
214: if(freferences) {
215: if(--freferences==0)
216: delete this;
217: }
218: }
1.1.2.7 paf 219: unsigned long references() { return freferences; }
1.1.2.1 paf 220: };
221: DECLARE_OBJECT_PTR(PA_Object);
222:
223: // convinient types
224:
225: typedef smart_ptr<char> CharPtr;
226:
227: #endif