add helper object for eSmartPtr, resolving a race condition.
[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 template<class T>
8 class ePtr
9 {
10                 /* read doc/iObject about the ePtrHelper */
11         template<class T1>
12         class ePtrHelper
13         {
14                 T1 *m_obj;
15         public:
16                 inline ePtrHelper(T1 *obj): m_obj(obj)
17                 {
18                         m_obj->AddRef();
19                 }
20                 inline ~ePtrHelper()
21                 {
22                         m_obj->Release();
23                 }
24                 inline T1* operator->() { return m_obj; }
25         };
26 protected:
27         T *ptr;
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         }
38         ePtr(const ePtr &c)
39         {
40                 ptr=c.ptr;
41                 if (ptr)
42                         ptr->AddRef();
43         }
44         ePtr &operator=(T *c)
45         {
46                 if (ptr)
47                         ptr->Release();
48                 ptr=c;
49                 if (ptr)
50                         ptr->AddRef();
51                 return *this;
52         }
53         
54         ePtr &operator=(ePtr<T> &c)
55         {
56                 if (ptr)
57                         ptr->Release();
58                 ptr=c.ptr;
59                 if (ptr)
60                         ptr->AddRef();
61                 return *this;
62         }
63         
64         ~ePtr()
65         {
66                 if (ptr)
67                         ptr->Release();
68         }
69         T* &ptrref() { assert(!ptr); return ptr; }
70         ePtrHelper<T> operator->() { assert(ptr); return ePtrHelper<T>(ptr); }
71
72                         /* for const objects, we don't need the helper, as they can't */
73                         /* be changed outside the program flow. at least this is */
74                         /* what the compiler assumes, so in case you're using const */
75                         /* ePtrs note that they have to be const. */
76         const T* operator->() const { assert(ptr); return ptr; }
77         operator T*() const { return this->ptr; }
78 };
79
80
81 #endif