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