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