Merge branch 'master' of /home/tmbinc/enigma2-git
[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         operator bool() const { return !!this->ptr; }
61 #endif
62         T* operator->() const { ptrAssert(ptr); return ptr; }
63         operator T*() const { return this->ptr; }
64 };
65
66
67 template<class T>
68 class eUsePtr
69 {
70 protected:
71         T *ptr;
72 public:
73         T &operator*() { return *ptr; }
74         eUsePtr(): ptr(0)
75         {
76         }
77         eUsePtr(T *c): ptr(c)
78         {
79                 if (c)
80                 {
81                         c->AddRef();
82                         c->AddUse();
83                 }
84         }
85         eUsePtr(const eUsePtr &c)
86         {
87                 ptr=c.ptr;
88                 if (ptr)
89                 {
90                         ptr->AddRef();
91                         ptr->AddUse();
92                 }
93         }
94         eUsePtr &operator=(T *c)
95         {
96                 if (c)
97                 {
98                         c->AddRef();
99                         c->AddUse();
100                 }
101                 if (ptr)
102                 {
103                         ptr->ReleaseUse();
104                         ptr->Release();
105                 }
106                 ptr=c;
107                 return *this;
108         }
109         
110         eUsePtr &operator=(eUsePtr<T> &c)
111         {
112                 if (c.ptr)
113                 {
114                         c.ptr->AddRef();
115                         c.ptr->AddUse();
116                 }
117                 if (ptr)
118                 {
119                         ptr->ReleaseUse();
120                         ptr->Release();
121                 }
122                 ptr=c.ptr;
123                 return *this;
124         }
125         
126         ~eUsePtr()
127         {
128                 if (ptr)
129                 {
130                         ptr->ReleaseUse();
131                         ptr->Release();
132                 }
133         }
134         
135 #ifndef SWIG
136         T* grabRef() { if (!ptr) return 0; ptr->AddRef(); ptr->AddUse(); return ptr; }
137         T* &ptrref() { ASSERT(!ptr); return ptr; }
138 #endif
139         T* operator->() const { ptrAssert(ptr); return ptr; }
140         operator T*() const { return this->ptr; }
141 };
142
143
144
145 #ifndef SWIG
146 template<class T>
147 class eMutablePtr: public ePtr<T>
148 {
149                 /* read doc/iObject about the ePtrHelper */
150         template<class T1>
151         class ePtrHelper
152         {
153                 T1 *m_obj;
154         public:
155                 inline ePtrHelper(T1 *obj): m_obj(obj)
156                 {
157                         m_obj->AddRef();
158                 }
159                 inline ~ePtrHelper()
160                 {
161                         m_obj->Release();
162                 }
163                 inline T1* operator->() { return m_obj; }
164         };
165 protected:
166         T *ptr;
167 public:
168         eMutablePtr(): ePtr<T>(0)
169         {
170         }
171         
172         eMutablePtr(T *c): ePtr<T>(c)
173         {
174         }
175
176         eMutablePtr(const eMutablePtr &c): ePtr<T>(c)
177         {
178         }
179         
180         eMutablePtr &operator=(T *c)
181         {
182                 ePtr<T>::operator=(c);
183                 return *this;
184         }
185         
186         
187         ePtrHelper<T> operator->() { ptrAssert(ptr); return ePtrHelper<T>(ptr); }
188
189                         /* for const objects, we don't need the helper, as they can't */
190                         /* be changed outside the program flow. at least this is */
191                         /* what the compiler assumes, so in case you're using const */
192                         /* eMutablePtrs note that they have to be const. */
193         const T* operator->() const { ptrAssert(ptr); return ptr; }
194 };
195 #endif
196
197 #endif