aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
refPtr_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4
* info_at_agrum_dot_org
5
*
6
* This library is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
*
19
*/
20
21
22
/**
23
* @file
24
* @brief Implementation of aGrUM's "smart" pointers.
25
*
26
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
#
include
<
agrum
/
tools
/
core
/
refPtr
.
h
>
29
30
namespace
gum
{
31
32
// default constructor
33
34
template
<
typename
Val >
35
INLINE RefPtr<
Val
>::
RefPtr
(
Val
*
v
) :
36
val__
(
v
),
refcount__
(
v
?
new
unsigned
int
(1U) : 0) {
37
// for debugging purposes
38
GUM_CONSTRUCTOR
(
RefPtr
);
39
}
40
41
// copy constructor
42
43
template
<
typename
Val
>
44
INLINE
RefPtr
<
Val
>::
RefPtr
(
const
RefPtr
<
Val
>&
from
) :
45
val__
(
from
.
val__
),
refcount__
(
from
.
refcount__
) {
46
// for debugging purposes
47
GUM_CONS_CPY
(
RefPtr
);
48
49
if
(
refcount__
) ++*
refcount__
;
50
}
51
52
// copy constructor for castable pointers
53
54
template
<
typename
Val
>
55
template
<
typename
DownVal
>
56
INLINE
RefPtr
<
Val
>::
RefPtr
(
const
RefPtr
<
DownVal
>&
from
) :
57
val__
(
from
.
val__
),
refcount__
(
from
.
refcount__
) {
58
// for debugging purposes
59
GUM_CONS_CPY
(
RefPtr
);
60
61
if
(
refcount__
) ++*
refcount__
;
62
}
63
64
// removes the current content of the smart pointer
65
66
template
<
typename
Val
>
67
INLINE
void
RefPtr
<
Val
>::
destroy__
(
unsigned
int
*
count
,
Val
*
v
) {
68
if
(
count
) {
69
if
(*
count
== 1U) {
70
// do not change the order of the deletes (this prevents memory leaks
71
// when
72
// the delete of v fails (note that this should probably never happen))
73
delete
count
;
74
delete
v
;
75
}
else
76
--*
count
;
77
}
78
}
79
80
// copy operator
81
82
template
<
typename
Val
>
83
INLINE
RefPtr
<
Val
>&
RefPtr
<
Val
>::
operator
=(
const
RefPtr
<
Val
>&
from
) {
84
// avoid self assignment
85
if
(
val__
!=
from
.
val__
) {
86
// for debugging purposes
87
GUM_OP_CPY
(
RefPtr
);
88
89
// keep track of the current refcount and dumb pointer
90
unsigned
int
*
old_refcount
=
refcount__
;
91
Val
*
old_val
=
val__
;
92
93
// perform the copy
94
refcount__
=
from
.
refcount__
;
95
val__
=
from
.
val__
;
96
97
if
(
refcount__
) ++*
refcount__
;
98
99
// now try to dereference the old dumb pointer
100
destroy__
(
old_refcount
,
old_val
);
101
}
102
103
return
*
this
;
104
}
105
106
// copy operator
107
108
template
<
typename
Val
>
109
INLINE
RefPtr
<
Val
>&
RefPtr
<
Val
>::
operator
=(
Val
*
from
) {
110
// avoid self assignment
111
if
(
val__
!=
from
) {
112
// for debugging purposes
113
GUM_OP_CPY
(
RefPtr
);
114
115
// keep track of the current refcount and dumb pointer
116
unsigned
int
*
old_refcount
=
refcount__
;
117
Val
*
old_val
=
val__
;
118
119
// perform the copy
120
try
{
121
if
(
from
)
122
refcount__
=
new
unsigned
int
(1U);
123
else
124
refcount__
= 0;
125
126
val__
=
from
;
127
}
catch
(
std
::
bad_alloc
&) {
128
if
(*
old_refcount
== 1) {
129
val__
=
from
;
130
delete
old_val
;
131
return
*
this
;
132
}
133
134
refcount__
= 0;
135
val__
= 0;
136
throw
;
137
}
138
139
// now try to dereference the old dumb pointer
140
destroy__
(
old_refcount
,
old_val
);
141
}
142
143
return
*
this
;
144
}
145
146
// copy operator for downcastable pointers
147
148
template
<
typename
Val
>
149
template
<
typename
DownVal
>
150
INLINE
RefPtr
<
Val
>&
RefPtr
<
Val
>::
operator
=(
const
RefPtr
<
DownVal
>&
from
) {
151
// for debugging purposes
152
GUM_OP_CPY
(
RefPtr
);
153
// keep track of the current refcount and dumb pointer
154
unsigned
int
*
old_refcount
=
refcount__
;
155
Val
*
old_val
=
val__
;
156
157
// perform the copy
158
refcount__
=
from
.
refcount__
;
159
val__
=
from
.
val__
;
160
161
if
(
refcount__
) ++*
refcount__
;
162
163
// now try to dereference the old dumb pointer
164
destroy__
(
old_refcount
,
old_val
);
165
166
return
*
this
;
167
}
168
169
// destructor: it decrements the Val's reference count
170
171
template
<
typename
Val
>
172
INLINE
RefPtr
<
Val
>::~
RefPtr
() {
173
// for debugging purposes
174
GUM_DESTRUCTOR
(
RefPtr
);
175
destroy__
(
refcount__
,
val__
);
176
}
177
178
// checks whether two RefPtr<Val> are smart pointers for the same element
179
180
template
<
typename
Val
>
181
INLINE
bool
RefPtr
<
Val
>::
operator
==(
const
RefPtr
<
Val
>&
from
)
const
{
182
return
from
.
refcount__
==
refcount__
;
183
}
184
185
// checks whether two RefPtr<Val> are smart pointers for differen elements
186
187
template
<
typename
Val
>
188
INLINE
bool
RefPtr
<
Val
>::
operator
!=(
const
RefPtr
<
Val
>&
from
)
const
{
189
return
from
.
refcount__
!=
refcount__
;
190
}
191
192
// dereferencing operator
193
194
template
<
typename
Val
>
195
INLINE
Val
&
RefPtr
<
Val
>::
operator
*() {
196
if
(!
val__
) {
GUM_ERROR
(
NullElement
,
"dereferencing a nullptr pointer"
); }
197
198
return
*
val__
;
199
}
200
201
// dereferencing operator
202
203
template
<
typename
Val
>
204
INLINE
const
Val
&
RefPtr
<
Val
>::
operator
*()
const
{
205
if
(!
val__
) {
GUM_ERROR
(
NullElement
,
"dereferencing a nullptr pointer"
); }
206
207
return
*
val__
;
208
}
209
210
// dereferencing operator
211
212
template
<
typename
Val
>
213
INLINE
Val
*
RefPtr
<
Val
>::
operator
->()
const
{
214
if
(!
val__
) {
GUM_ERROR
(
NullElement
,
"dereferencing a nullptr pointer"
); }
215
216
return
val__
;
217
}
218
219
// checks whether a RefPtr points toward something
220
221
template
<
typename
Val
>
222
INLINE
RefPtr
<
Val
>::
operator
bool
()
const
{
223
return
(
val__
!= 0);
224
}
225
226
// dereference what was referenced by the smart pointer
227
228
template
<
typename
Val
>
229
INLINE
void
RefPtr
<
Val
>::
clear
() {
230
// keep track of the old pointer and reference count
231
unsigned
int
*
old_refcount
=
refcount__
;
232
Val
*
old_val
=
val__
;
233
// set properly the dumb pointer and its refcount
234
val__
= 0;
235
refcount__
= 0;
236
// now try to dereference the old dumb pointer
237
destroy__
(
old_refcount
,
old_val
);
238
}
239
240
// returns the number of references on the contained pointer
241
242
template
<
typename
Val
>
243
INLINE
unsigned
int
RefPtr
<
Val
>::
refCount
()
const
{
244
if
(
refcount__
== 0)
return
0;
245
246
return
*
refcount__
;
247
}
248
249
// returns the refcount pointer
250
251
template
<
typename
Val
>
252
INLINE
unsigned
int
*
RefPtr
<
Val
>::
refCountPtr__
()
const
{
253
return
refcount__
;
254
}
255
256
// replace the contents of two RefPtr
257
258
template
<
typename
Val
>
259
void
swap
(
RefPtr
<
Val
>&
ptr1
,
RefPtr
<
Val
>&
ptr2
) {
260
// save from's content
261
Val
*
tmp_val
=
ptr2
.
val__
;
262
unsigned
int
*
tmp_refcount
=
ptr2
.
refcount__
;
263
// modify from's content
264
ptr2
.
refcount__
=
ptr1
.
refcount__
;
265
ptr2
.
val__
=
ptr1
.
val__
;
266
// modify this's content
267
ptr1
.
val__
=
tmp_val
;
268
ptr1
.
refcount__
=
tmp_refcount
;
269
}
270
271
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669