refcounted.h
Go to the documentation of this file.
1 
4 /***********************************************************************
5  Copyright (c) 2007-2011 by Educational Technology Resources, Inc. and
6  (c) 2007 by Jonathan Wakely. Others may also hold copyrights on
7  code in this file. See the CREDITS.txt file in the top directory
8  of the distribution for details.
9 
10  This file is part of MySQL++.
11 
12  MySQL++ is free software; you can redistribute it and/or modify it
13  under the terms of the GNU Lesser General Public License as published
14  by the Free Software Foundation; either version 2.1 of the License, or
15  (at your option) any later version.
16 
17  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
18  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20  License for more details.
21 
22  You should have received a copy of the GNU Lesser General Public
23  License along with MySQL++; if not, write to the Free Software
24  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
25  USA
26 ***********************************************************************/
27 
28 #if !defined(MYSQLPP_REFCOUNTED_H)
29 #define MYSQLPP_REFCOUNTED_H
30 
31 #include <memory>
32 
33 #include <stddef.h>
34 
35 namespace mysqlpp {
36 
44 template <class T>
46 {
48  void operator()(T* doomed) const { delete doomed; }
49 };
50 
51 
78 
79 template <class T, class Destroyer = RefCountedPointerDestroyer<T> >
81 {
82 public:
84 
90  counted_(0),
91  refs_(0)
92  {
93  }
94 
100  explicit RefCountedPointer(T* c) :
101  counted_(c),
102  refs_(0)
103  {
104  std::auto_ptr<T> exception_guard(counted_);
105  if (counted_) {
106  refs_ = new size_t(1);
107  }
108  exception_guard.release(); // previous new didn't throw
109  }
110 
112  RefCountedPointer(const ThisType& other) :
113  counted_(other.counted_),
114  refs_(other.counted_ ? other.refs_ : 0)
115  {
116  if (counted_) {
117  ++(*refs_);
118  }
119  }
120 
126  {
127  if (refs_ && (--(*refs_) == 0)) {
128  Destroyer()(counted_);
129  delete refs_;
130  }
131  }
132 
141  {
142  // The create-temporary-and-swap idiom lets us keep memory
143  // allocation in the ctor and deallocation in the dtor so
144  // we don't leak in the face of an exception.
145  ThisType(c).swap(*this);
146  return *this;
147  }
148 
157  ThisType& assign(const ThisType& other)
158  {
159  // The create-temporary-and-swap idiom lets us keep memory
160  // allocation in the ctor and deallocation in the dtor so
161  // we don't leak in the face of an exception.
162  ThisType(other).swap(*this);
163  return *this;
164  }
165 
171  {
172  return assign(c);
173  }
174 
181  {
182  return assign(rhs);
183  }
184 
186  T* operator ->() const
187  {
188  return counted_;
189  }
190 
192  T& operator *() const
193  {
194  return *counted_;
195  }
196 
216  operator void*()
217  {
218  return counted_;
219  }
220 
224  operator const void*() const
225  {
226  return counted_;
227  }
228 
230  T* raw()
231  {
232  return counted_;
233  }
234 
236  const T* raw() const
237  {
238  return counted_;
239  }
240 
245  void swap(ThisType& other)
246  {
247  std::swap(counted_, other.counted_);
248  std::swap(refs_, other.refs_);
249  }
250 
251 private:
253  T* counted_;
254 
260  size_t* refs_;
261 };
262 
263 
264 } // end namespace mysqlpp
265 
266 #endif // !defined(MYSQLPP_REFCOUNTED_H)
267 
T * raw()
Return the raw pointer in T* context.
Definition: refcounted.h:230
~RefCountedPointer()
Destructor.
Definition: refcounted.h:125
RefCountedPointer(const ThisType &other)
Copy constructor.
Definition: refcounted.h:112
void swap(ThisType &other)
Exchange our managed memory with another pointer.
Definition: refcounted.h:245
Functor to call delete on the pointer you pass to it.
Definition: refcounted.h:45
RefCountedPointer(T *c)
Standard constructor.
Definition: refcounted.h:100
void operator()(T *doomed) const
Functor implementation.
Definition: refcounted.h:48
const T * raw() const
Return the raw pointer when used in const T* context.
Definition: refcounted.h:236
ThisType & assign(const ThisType &other)
Copy an existing refcounted pointer.
Definition: refcounted.h:157
RefCountedPointer< T > ThisType
alias for this object&#39;s type
Definition: refcounted.h:83
T & operator*() const
Dereference the smart pointer.
Definition: refcounted.h:192
Creates an object that acts as a reference-counted pointer to another object.
Definition: refcounted.h:80
ThisType & assign(T *c)
Sets (or resets) the pointer to the counted object.
Definition: refcounted.h:140
T * operator->() const
Access the object through the smart pointer.
Definition: refcounted.h:186
RefCountedPointer()
Default constructor.
Definition: refcounted.h:89
ThisType & operator=(T *c)
Set (or reset) the pointer to the counted object.
Definition: refcounted.h:170