ac6b9eb0767fe8d8854e43043c63bc67e4c368f9
[enigma2.git] / lib / base / smartptr.h
1 #ifndef __smartptr_h
2 #define __smartptr_h
3
4 #include "object.h"
5 #include <stdio.h>
6 #include <lib/python/swig.h>
7
8 inline void ptrAssert(void *p) { if (!p) *(unsigned long*)0=0; }
9
10 template<class T>
11 class ePtr
12 {
13 protected:
14         T *ptr;
15 public:
16         T &operator*() { return *ptr; }
17         ePtr(): ptr(0)
18         {
19         }
20         ePtr(T *c): ptr(c)
21         {
22                 if (c)
23                         c->AddRef();
24         }
25         ePtr(const ePtr &c)
26         {
27                 ptr=c.ptr;
28                 if (ptr)
29                         ptr->AddRef();
30         }
31         ePtr &operator=(T *c)
32         {
33                 if (c)
34                         c->AddRef();
35                 if (ptr)
36                         ptr->Release();
37                 ptr=c;
38                 return *this;
39         }
40         
41         ePtr &operator=(ePtr<T> &c)
42         {
43                 if (c.ptr)
44                         c.ptr->AddRef();
45                 if (ptr)
46                         ptr->Release();
47                 ptr=c.ptr;
48                 return *this;
49         }
50         
51         ~ePtr()
52         {
53                 if (ptr)
54                         ptr->Release();
55         }
56         
57 #ifndef SWIG
58         T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; }
59         T* &ptrref() { ASSERT(!ptr); return ptr; }
60 #endif
61         T* operator->() const { ptrAssert(ptr); return ptr; }
62         operator T*() const { return this->ptr; }
63         
64         operator bool() const { return !!this->ptr; }
65 };
66
67
68 template<class T>
69 class eUsePtr
70 {
71 protected:
72         T *ptr;
73 public:
74         T &operator*() { return *ptr; }
75         eUsePtr(): ptr(0)
76         {
77         }
78         eUsePtr(T *c): ptr(c)
79         {
80                 if (c)
81                 {
82                         c->AddRef();
83                         c->AddUse();
84                 }
85         }
86         eUsePtr(const eUsePtr &c)
87         {
88                 ptr=c.ptr;
89                 if (ptr)
90                 {
91                         ptr->AddRef();
92                         ptr->AddUse();
93                 }
94         }
95         eUsePtr &operator=(T *c)
96         {
97                 if (c)
98                 {
99                         c->AddRef();
100                         c->AddUse();
101                 }
102                 if (ptr)
103                 {
104                         ptr->ReleaseUse();
105                         ptr->Release();
106                 }
107                 ptr=c;
108                 return *this;
109         }
110         
111         eUsePtr &operator=(eUsePtr<T> &c)
112         {
113                 if (c.ptr)
114                 {
115                         c.ptr->AddRef();
116                         c.ptr->AddUse();
117                 }
118                 if (ptr)
119                 {
120                         ptr->ReleaseUse();
121                         ptr->Release();
122                 }
123                 ptr=c.ptr;
124                 return *this;
125         }
126         
127         ~eUsePtr()
128         {
129                 if (ptr)
130                 {
131                         ptr->ReleaseUse();
132                         ptr->Release();
133                 }
134         }
135         
136 #ifndef SWIG
137         T* grabRef() { if (!ptr) return 0; ptr->AddRef(); ptr->AddUse(); return ptr; }
138         T* &ptrref() { ASSERT(!ptr); return ptr; }
139 #endif
140         T* operator->() const { ptrAssert(ptr); return ptr; }
141         operator T*() const { return this->ptr; }
142 };
143
144
145
146 #ifndef SWIG
147 template<class T>
148 class eMutablePtr: public ePtr<T>
149 {
150                 /* read doc/iObject about the ePtrHelper */
151         template<class T1>
152         class ePtrHelper
153         {
154                 T1 *m_obj;
155         public:
156                 inline ePtrHelper(T1 *obj): m_obj(obj)
157                 {
158                         m_obj->AddRef();
159                 }
160                 inline ~ePtrHelper()
161                 {
162                         m_obj->Release();
163                 }
164                 inline T1* operator->() { return m_obj; }
165         };
166 protected:
167         T *ptr;
168 public:
169         eMutablePtr(): ePtr<T>(0)
170         {
171         }
172         
173         eMutablePtr(T *c): ePtr<T>(c)
174         {
175         }
176
177         eMutablePtr(const eMutablePtr &c): ePtr<T>(c)
178         {
179         }
180         
181         eMutablePtr &operator=(T *c)
182         {
183                 ePtr<T>::operator=(c);
184                 return *this;
185         }
186         
187         
188         ePtrHelper<T> operator->() { ptrAssert(ptr); return ePtrHelper<T>(ptr); }
189
190                         /* for const objects, we don't need the helper, as they can't */
191                         /* be changed outside the program flow. at least this is */
192                         /* what the compiler assumes, so in case you're using const */
193                         /* eMutablePtrs note that they have to be const. */
194         const T* operator->() const { ptrAssert(ptr); return ptr; }
195 };
196 #endif
197
198 #endif