- skins are now loaded first and applied later
[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
70 #ifndef SWIG
71 template<class T>
72 class eMutablePtr: public ePtr<T>
73 {
74                 /* read doc/iObject about the ePtrHelper */
75         template<class T1>
76         class ePtrHelper
77         {
78                 T1 *m_obj;
79         public:
80                 inline ePtrHelper(T1 *obj): m_obj(obj)
81                 {
82                         m_obj->AddRef();
83                 }
84                 inline ~ePtrHelper()
85                 {
86                         m_obj->Release();
87                 }
88                 inline T1* operator->() { return m_obj; }
89         };
90 protected:
91         T *ptr;
92 public:
93         eMutablePtr(): ePtr<T>(0)
94         {
95         }
96         
97         eMutablePtr(T *c): ePtr<T>(c)
98         {
99         }
100
101         eMutablePtr(const eMutablePtr &c): ePtr<T>(c)
102         {
103         }
104         
105         eMutablePtr &operator=(T *c)
106         {
107                 ePtr<T>::operator=(c);
108                 return *this;
109         }
110         
111         
112         ePtrHelper<T> operator->() { assert(ptr); return ePtrHelper<T>(ptr); }
113
114                         /* for const objects, we don't need the helper, as they can't */
115                         /* be changed outside the program flow. at least this is */
116                         /* what the compiler assumes, so in case you're using const */
117                         /* eMutablePtrs note that they have to be const. */
118         const T* operator->() const { assert(ptr); return ptr; }
119 };
120 #endif
121
122 #endif