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