7e441ab2976ab67e48e67b89064a72c22fe9ec7f
[enigma2.git] / lib / base / smartptr.h
1 #ifndef __smartptr_h
2 #define __smartptr_h
3
4 #include "object.h"
5 #include <stdio.h>
6
7 #ifdef SWIG
8 #define TEMPLATE_TYPEDEF(x, y) \
9 %template(y) x; \
10 typedef x y
11 #else
12 #define TEMPLATE_TYPEDEF(x, y) typedef x y
13 #endif
14
15 template<class T>
16 class ePtr
17 {
18 protected:
19         T *ptr;
20 public:
21         T &operator*() { return *ptr; }
22         ePtr(): ptr(0)
23         {
24         }
25         ePtr(T *c): ptr(c)
26         {
27                 if (c)
28                         c->AddRef();
29         }
30         ePtr(const ePtr &c)
31         {
32                 ptr=c.ptr;
33                 if (ptr)
34                         ptr->AddRef();
35         }
36         ePtr &operator=(T *c)
37         {
38                 if (c)
39                         c->AddRef();
40                 if (ptr)
41                         ptr->Release();
42                 ptr=c;
43                 return *this;
44         }
45         
46         ePtr &operator=(ePtr<T> &c)
47         {
48                 if (c.ptr)
49                         c.ptr->AddRef();
50                 if (ptr)
51                         ptr->Release();
52                 ptr=c.ptr;
53                 return *this;
54         }
55         
56         ~ePtr()
57         {
58                 if (ptr)
59                         ptr->Release();
60         }
61         
62         T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; }
63         T* &ptrref() { assert(!ptr); return ptr; }
64         T* operator->() const { assert(ptr); return ptr; }
65         operator T*() const { return this->ptr; }
66 };
67
68
69 template<class T>
70 class eUsePtr
71 {
72 protected:
73         T *ptr;
74 public:
75         T &operator*() { return *ptr; }
76         eUsePtr(): ptr(0)
77         {
78         }
79         eUsePtr(T *c): ptr(c)
80         {
81                 if (c)
82                 {
83                         c->AddRef();
84                         c->AddUse();
85                 }
86         }
87         eUsePtr(const eUsePtr &c)
88         {
89                 ptr=c.ptr;
90                 if (ptr)
91                 {
92                         ptr->AddRef();
93                         ptr->AddUse();
94                 }
95         }
96         eUsePtr &operator=(T *c)
97         {
98                 if (c)
99                 {
100                         c->AddRef();
101                         c->AddUse();
102                 }
103                 if (ptr)
104                 {
105                         ptr->ReleaseUse();
106                         ptr->Release();
107                 }
108                 ptr=c;
109                 return *this;
110         }
111         
112         eUsePtr &operator=(eUsePtr<T> &c)
113         {
114                 if (c.ptr)
115                 {
116                         c.ptr->AddRef();
117                         c.ptr->AddUse();
118                 }
119                 if (ptr)
120                 {
121                         ptr->ReleaseUse();
122                         ptr->Release();
123                 }
124                 ptr=c.ptr;
125                 return *this;
126         }
127         
128         ~eUsePtr()
129         {
130                 if (ptr)
131                 {
132                         ptr->ReleaseUse();
133                         ptr->Release();
134                 }
135         }
136         
137         T* grabRef() { if (!ptr) return 0; ptr->AddRef(); ptr->AddUse(); return ptr; }
138         T* &ptrref() { assert(!ptr); return ptr; }
139         T* operator->() const { assert(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->() { assert(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 { assert(ptr); return ptr; }
194 };
195 #endif
196
197 #endif