1 /*****************************************************************************/
2 /* Software Testing Automation Framework (STAF) */
3 /* (C) Copyright IBM Corp. 2001 */
4 /* */
5 /* This software is licensed under the Eclipse Public License (EPL) V1.0. */
6 /*****************************************************************************/
7
8 #ifndef STAF_RefPtr
9 #define STAF_RefPtr
10
11 #include "STAFThread.h"
12
13 #ifdef __cplusplus
14
15 // STAFBuffer<T> - This class provides a simple delete wrapper
16
17 template <class TheType>
18 class STAFBuffer
19 {
20 public:
21
22 enum Init { INIT = 0 };
23 enum Type { SCALAR = 0, ARRAY = 1 };
24
25 STAFBuffer(TheType *, Init init, Type type = ARRAY);
26
27 TheType *operator->() const { return fPtr; }
28 TheType &operator*() const { return *fPtr; }
29 operator TheType *() const { return fPtr; }
30
31 ~STAFBuffer();
32
33 private:
34
35 // Don't allow assignment or copy construction
36 STAFBuffer(const STAFBuffer &);
37 STAFBuffer &operator=(const STAFBuffer &from);
38 STAFBuffer &operator=(const TheType *);
39
40 TheType *fPtr;
41 Type fType;
42 };
43
44 template <class TheType>
STAFBuffer(TheType * ptr,Init init,Type type)45 inline STAFBuffer<TheType>::STAFBuffer(TheType *ptr, Init init, Type type)
46 : fPtr(ptr), fType(type)
47 {
48 /* Do Nothing */
49 }
50
51 template <class TheType>
~STAFBuffer()52 inline STAFBuffer<TheType>::~STAFBuffer()
53 {
54 if (fType == SCALAR) delete fPtr;
55 else delete [] fPtr;
56 }
57
58
59 // STAFRefPtr<T> - This class provides thread safe reference counted pointers
60
61 template <class TheType>
62 class STAFRefPtr
63 {
64 public:
65
66 enum Init { INIT = 0 };
67 enum Type { SCALAR = 0, ARRAY = 1, CUSTOM = 2, CUSTOMARRAY = 3 };
68 typedef void(*TypeFreeFunction)(TheType *);
69 typedef void(*TypeArrayFreeFunction)(TheType *, unsigned int);
70
71 STAFRefPtr();
72 STAFRefPtr(TheType *, Init init, Type type = SCALAR, TypeFreeFunction = 0);
73 STAFRefPtr(TheType *, Init init, unsigned int size,
74 TypeArrayFreeFunction arrayFreeFunc);
75 STAFRefPtr(const STAFRefPtr &from);
76
77 STAFRefPtr &operator=(const STAFRefPtr &from);
78 bool operator==(const STAFRefPtr &rhs);
79 TheType *operator->() const { return fPtr; }
80 TheType &operator*() const { return *fPtr; }
81 operator TheType *() const { return fPtr; }
82
count()83 STAFThreadSafeScalar_t count() { return fCount ? *fCount : -1; }
84
85 ~STAFRefPtr();
86
87 private:
88
89 // Don't allow assignment from raw pointer type.
90 STAFRefPtr &operator=(const TheType *);
91
92 TheType *fPtr;
93 Type fType;
94 union
95 {
96 TypeFreeFunction fFreeFunc;
97 TypeArrayFreeFunction fArrayFreeFunc;
98 };
99 unsigned int fSize;
100 STAFThreadSafeScalar_t *fCount;
101 };
102
103 template <class TheType>
STAFRefPtr()104 inline STAFRefPtr<TheType>::STAFRefPtr() : fPtr(0), fType(SCALAR), fFreeFunc(0),
105 fCount(0), fSize(0)
106 { /* Do Nothing */ }
107
108 template <class TheType>
STAFRefPtr(TheType * ptr,Init init,Type type,TypeFreeFunction freeFunc)109 inline STAFRefPtr<TheType>::STAFRefPtr(TheType *ptr, Init init, Type type,
110 TypeFreeFunction freeFunc)
111 : fPtr(ptr), fType(type), fFreeFunc(freeFunc), fCount(0), fSize(0)
112 {
113 fCount = new STAFThreadSafeScalar_t(1);
114 }
115
116 template <class TheType>
STAFRefPtr(TheType * ptr,Init init,unsigned int size,TypeArrayFreeFunction freeFunc)117 inline STAFRefPtr<TheType>::STAFRefPtr(TheType *ptr, Init init,
118 unsigned int size,
119 TypeArrayFreeFunction freeFunc)
120 : fPtr(ptr), fType(CUSTOMARRAY), fArrayFreeFunc(freeFunc), fCount(0),
121 fSize(size)
122 {
123 fCount = new STAFThreadSafeScalar_t(1);
124 }
125
126 template <class TheType>
STAFRefPtr(const STAFRefPtr & from)127 inline STAFRefPtr<TheType>::STAFRefPtr(const STAFRefPtr &from)
128 : fPtr(from.fPtr), fType(from.fType), fSize(from.fSize), fCount(from.fCount)
129 {
130 if (fType == CUSTOMARRAY)
131 fArrayFreeFunc = from.fArrayFreeFunc;
132 else
133 fFreeFunc = from.fFreeFunc;
134
135 if (fCount != 0)
136 STAFThreadSafeIncrement(fCount);
137 }
138
139 template <class TheType>
140 inline STAFRefPtr<TheType> &STAFRefPtr<TheType>::operator=(const STAFRefPtr &from)
141 {
142 if (fPtr == from.fPtr) return *this;
143
144 if (fCount != 0)
145 {
146 if (STAFThreadSafeDecrement(fCount) == 0)
147 {
148 if (fType == SCALAR) delete fPtr;
149 else if (fType == ARRAY) delete [] fPtr;
150 else if (fType == CUSTOM) fFreeFunc(fPtr);
151 else fArrayFreeFunc(fPtr, fSize);
152
153 delete fCount;
154 }
155 }
156
157 fPtr = from.fPtr;
158 fType = from.fType;
159 fFreeFunc = from.fFreeFunc;
160 fSize = from.fSize;
161 fCount = from.fCount;
162
163 if (fCount != 0)
164 STAFThreadSafeIncrement(fCount);
165
166 return *this;
167 }
168
169 template <class TheType>
170 inline bool STAFRefPtr<TheType>::operator==(const STAFRefPtr &rhs)
171 {
172 return (fPtr == rhs.fPtr);
173 }
174
175 template <class TheType>
~STAFRefPtr()176 inline STAFRefPtr<TheType>::~STAFRefPtr()
177 {
178 if (fCount != 0)
179 {
180 if (STAFThreadSafeDecrement(fCount) == 0)
181 {
182 if (fType == SCALAR) delete fPtr;
183 else if (fType == ARRAY) delete [] fPtr;
184 else if (fType == CUSTOM) fFreeFunc(fPtr);
185 else fArrayFreeFunc(fPtr, fSize);
186
187 delete fCount;
188 }
189 }
190 }
191
192 // End #ifdef __cplusplus
193
194 #endif
195
196 #endif
197