MySQL++  3.2.5
refcounted.h
Go to the documentation of this file.
1 
4 /***********************************************************************
5  Copyright © 2007-2011, 2018 by Educational Technology Resources, Inc.
6  and © 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 "common.h"
32 
33 #include <memory>
34 
35 #include <stddef.h>
36 
37 namespace mysqlpp {
38 
46 template <class T>
47 struct RefCountedPointerDestroyer
48 {
50  void operator()(T* doomed) const { delete doomed; }
51 };
52 
53 
80 
81 template <class T, class Destroyer = RefCountedPointerDestroyer<T> >
82 class RefCountedPointer
83 {
84 public:
85  typedef RefCountedPointer<T> ThisType;
86 
92  counted_(0),
93  refs_(0)
94  {
95  }
96 
102  explicit RefCountedPointer(T* c) :
103  counted_(c),
104  refs_(0)
105  {
106  UNIQUE_PTR(T) exception_guard(counted_);
107  if (counted_) {
108  refs_ = new size_t(1);
109  }
110  exception_guard.release(); // previous new didn't throw
111  }
112 
114  RefCountedPointer(const ThisType& other) :
115  counted_(other.counted_),
116  refs_(other.counted_ ? other.refs_ : 0)
117  {
118  if (counted_) {
119  ++(*refs_);
120  }
121  }
122 
128  {
129  if (refs_ && (--(*refs_) == 0)) {
130  Destroyer()(counted_);
131  delete refs_;
132  }
133  }
134 
142  ThisType& assign(T* c)
143  {
144  // The create-temporary-and-swap idiom lets us keep memory
145  // allocation in the ctor and deallocation in the dtor so
146  // we don't leak in the face of an exception.
147  ThisType(c).swap(*this);
148  return *this;
149  }
150 
159  ThisType& assign(const ThisType& other)
160  {
161  // The create-temporary-and-swap idiom lets us keep memory
162  // allocation in the ctor and deallocation in the dtor so
163  // we don't leak in the face of an exception.
164  ThisType(other).swap(*this);
165  return *this;
166  }
167 
172  ThisType& operator =(T* c)
173  {
174  return assign(c);
175  }
176 
182  ThisType& operator =(const ThisType& rhs)
183  {
184  return assign(rhs);
185  }
186 
188  T* operator ->() const
189  {
190  return counted_;
191  }
192 
194  T& operator *() const
195  {
196  return *counted_;
197  }
198 
218  operator void*()
219  {
220  return counted_;
221  }
222 
226  operator const void*() const
227  {
228  return counted_;
229  }
230 
232  T* raw()
233  {
234  return counted_;
235  }
236 
238  const T* raw() const
239  {
240  return counted_;
241  }
242 
247  void swap(ThisType& other)
248  {
249  std::swap(counted_, other.counted_);
250  std::swap(refs_, other.refs_);
251  }
252 
253 private:
255  T* counted_;
256 
262  size_t* refs_;
263 };
264 
265 
266 } // end namespace mysqlpp
267 
268 #endif // !defined(MYSQLPP_REFCOUNTED_H)
269 
mysqlpp::RefCountedPointer::operator->
T * operator->() const
Access the object through the smart pointer.
Definition: refcounted.h:210
mysqlpp::RefCountedPointer::ThisType
RefCountedPointer< T > ThisType
alias for this object's type
Definition: refcounted.h:107
mysqlpp::RefCountedPointer::operator=
ThisType & operator=(T *c)
Set (or reset) the pointer to the counted object.
Definition: refcounted.h:194
mysqlpp::RefCountedPointer::RefCountedPointer
RefCountedPointer()
Default constructor.
Definition: refcounted.h:113
mysqlpp::RefCountedPointer::assign
ThisType & assign(T *c)
Sets (or resets) the pointer to the counted object.
Definition: refcounted.h:164
mysqlpp::RefCountedPointer::raw
T * raw()
Return the raw pointer in T* context.
Definition: refcounted.h:254
mysqlpp::RefCountedPointer::~RefCountedPointer
~RefCountedPointer()
Destructor.
Definition: refcounted.h:149
mysqlpp::RefCountedPointer::swap
void swap(ThisType &other)
Exchange our managed memory with another pointer.
Definition: refcounted.h:269
mysqlpp::RefCountedPointer::operator*
T & operator*() const
Dereference the smart pointer.
Definition: refcounted.h:216
common.h
This file includes top-level definitions for use both internal to the library, and outside it....
mysqlpp::RefCountedPointerDestroyer::operator()
void operator()(T *doomed) const
Functor implementation.
Definition: refcounted.h:94