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