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