bakery
2.6
Main Page
Namespaces
Classes
Files
File List
File Members
bakery
Utilities
sharedptr.h
Go to the documentation of this file.
1
/*
2
* Copyright 2004 Murray Cumming
3
*
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
8
*
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
13
*
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the Free
16
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
*/
18
19
#ifndef BAKERY_UTILITIES_SHAREDPTR_H
20
#define BAKERY_UTILITIES_SHAREDPTR_H
21
22
#include <iostream>
//Just for debugging.
23
24
namespace
Bakery
25
{
26
30
template
<
typename
T_obj >
31
class
sharedptr
32
{
33
public
:
34
typedef
size_t
size_type
;
35
37
sharedptr
();
38
40
explicit
sharedptr
(T_obj* pobj);
41
43
sharedptr
(
const
sharedptr
& src);
44
46
sharedptr
&
operator=
(
const
sharedptr
& src);
47
48
virtual
~sharedptr
();
49
52
inline
T_obj&
operator*
();
53
56
inline
const
T_obj&
operator*
()
const
;
57
65
inline
T_obj*
operator->
()
const
;
66
75
inline
operator
bool()
const
;
76
78
inline
T_obj*
obj
();
79
81
inline
const
T_obj*
obj
()
const
;
82
83
84
protected
:
85
inline
void
ref
();
86
inline
void
unref
();
87
88
size_type
*
m_pRefCount
;
//Shared between instances, by copying.
89
T_obj*
m_pobj
;
//The underlying instance.
90
};
91
92
template
<
typename
T_obj>
93
sharedptr<T_obj>::sharedptr
()
94
: m_pRefCount(0), m_pobj(0)
95
{
96
97
}
98
99
template
<
typename
T_obj>
100
sharedptr<T_obj>::sharedptr
(T_obj* pobj)
101
: m_pRefCount(0), m_pobj(pobj)
102
{
103
//Start refcounting:
104
ref
();
105
}
106
107
template
<
typename
T_obj>
108
sharedptr<T_obj>::sharedptr
(
const
sharedptr<T_obj>
& src)
109
: m_pRefCount(src.m_pRefCount), m_pobj(src.m_pobj)
110
{
111
ref
();
112
}
113
114
template
<
typename
T_obj>
115
sharedptr<T_obj>
&
sharedptr<T_obj>::operator=
(
const
sharedptr<T_obj>
& src)
116
{
117
//std::cout << "sharedptr& operator=(const sharedptr& src)" << std::endl;
118
if
(&src !=
this
)
119
{
120
//Unref any existing stuff.
121
//operator= can never run before a constructor, so these values will be initialized already.
122
if
(m_pobj)
//The if() might not be required.
123
{
124
unref();
//Could cause a deallocation.
125
}
126
127
//Copy:
128
m_pobj = src.
m_pobj
;
129
130
m_pRefCount = src.
m_pRefCount
;
131
ref();
132
}
133
134
return
*
this
;
135
}
136
137
template
<
typename
T_obj>
138
sharedptr<T_obj>::~sharedptr
()
139
{
140
unref();
141
}
142
143
/*
144
template< typename T_obj>
145
void sharedptr<T_obj>::clear_without_deallocating()
146
{
147
m_pobj = 0;
148
}
149
*/
150
151
template
<
typename
T_obj>
152
inline
153
T_obj*
sharedptr<T_obj>::obj
()
154
{
155
return
m_pobj;
156
}
157
158
template
<
typename
T_obj>
159
inline
160
const
T_obj*
sharedptr<T_obj>::obj
()
const
161
{
162
return
m_pobj;
163
}
164
165
template
<
typename
T_obj>
166
inline
167
T_obj&
sharedptr<T_obj>::operator*
()
168
{
169
return
*m_pobj;
170
}
171
172
template
<
typename
T_obj>
173
inline
174
const
T_obj&
sharedptr<T_obj>::operator*
()
const
175
{
176
return
*m_pobj;
177
}
178
179
template
<
typename
T_obj>
180
inline
181
T_obj*
sharedptr<T_obj>::operator->
()
const
182
{
183
return
m_pobj;
184
}
185
186
template
<
class
T_obj>
187
inline
188
sharedptr<T_obj>::operator
bool()
const
189
{
190
return
(m_pobj != 0);
191
}
192
193
194
template
<
class
T_obj>
195
inline
196
void
sharedptr<T_obj>::ref
()
197
{
198
if
(m_pobj)
//Don't waste time on invalid instances. These would be very rare anyway, and intentionally created with (0,0) construction.
199
{
200
if
(m_pRefCount == 0)
201
{
202
//std::cout << "sharedptr::ref(): first ref" << std::endl;
203
//First ref, so allocate the shared count:
204
m_pRefCount =
new
size_type
();
205
*m_pRefCount = 1;
206
}
207
else
208
{
209
//std::cout << "sharedptr::ref(): starting at" << *m_pRefCount << std::endl;
210
(*m_pRefCount)++;
211
}
212
}
213
}
214
215
template
<
class
T_obj>
216
inline
217
void
sharedptr<T_obj>::unref
()
218
{
219
if
(m_pRefCount)
220
{
221
//std::cout << "sharedptr::unref(): starting at " << *m_pRefCount << std::endl;
222
223
if
( (*m_pRefCount) > 0 )
224
(*m_pRefCount)--;
225
226
//Unalloc if this is the last user of the obj:
227
if
(*m_pRefCount == 0)
228
{
229
if
(m_pobj)
230
{
231
//try
232
//{
233
//std::cout << "sharedptr::unref(): deallocating " << *m_pRefCount << std::endl;
234
delete
m_pobj;
235
m_pobj = 0;
236
//}
237
/*
238
catch(ex_base&)
239
{
240
//std::cout << "sharedptr::unref(): exception thrown during deallocation." << std::endl;
241
//Ignore it. Can't throw an expection up to the destructor.
242
}
243
*/
244
245
m_pobj = 0;
246
}
247
248
//Clear ref count:
249
delete
m_pRefCount;
250
m_pRefCount = 0;
251
}
252
}
253
else
254
{
255
//std::cout << "sharedptr::unref(): ref not setup." << std::endl;
256
}
257
258
}
259
260
261
}
//namespace
262
263
#endif //BAKERY_UTILITIES_SHAREDPTR_H
264
Generated by
1.8.4