refcounted.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 /***********************************************************************
00005  Copyright (c) 2007-2011 by Educational Technology Resources, Inc. and
00006  (c) 2007 by Jonathan Wakely.  Others may also hold copyrights on
00007  code in this file.  See the CREDITS.txt file in the top directory
00008  of the distribution for details.
00009 
00010  This file is part of MySQL++.
00011 
00012  MySQL++ is free software; you can redistribute it and/or modify it
00013  under the terms of the GNU Lesser General Public License as published
00014  by the Free Software Foundation; either version 2.1 of the License, or
00015  (at your option) any later version.
00016 
00017  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
00018  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00019  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00020  License for more details.
00021 
00022  You should have received a copy of the GNU Lesser General Public
00023  License along with MySQL++; if not, write to the Free Software
00024  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00025  USA
00026 ***********************************************************************/
00027 
00028 #if !defined(MYSQLPP_REFCOUNTED_H)
00029 #define MYSQLPP_REFCOUNTED_H
00030 
00031 #include <memory>
00032 
00033 #include <stddef.h>
00034 
00035 namespace mysqlpp {
00036 
00044 template <class T>
00045 struct RefCountedPointerDestroyer
00046 {
00048         void operator()(T* doomed) const { delete doomed; }
00049 };
00050 
00051 
00078 
00079 template <class T, class Destroyer = RefCountedPointerDestroyer<T> >
00080 class RefCountedPointer
00081 {
00082 public:
00083         typedef RefCountedPointer<T> ThisType;  
00084 
00089         RefCountedPointer() :
00090         counted_(0),
00091         refs_(0)
00092         {
00093         }
00094         
00100         explicit RefCountedPointer(T* c) :
00101         counted_(c),
00102         refs_(0)
00103         {
00104                 std::auto_ptr<T> exception_guard(counted_);
00105                 if (counted_) {
00106                         refs_ = new size_t(1);
00107                 }
00108                 exception_guard.release();      // previous new didn't throw
00109         }
00110 
00112         RefCountedPointer(const ThisType& other) :
00113         counted_(other.counted_),
00114         refs_(other.counted_ ? other.refs_ : 0)
00115         {
00116                 if (counted_) {
00117                         ++(*refs_);
00118                 }
00119         }
00120 
00125         ~RefCountedPointer()
00126         {
00127                 if (refs_ && (--(*refs_) == 0)) {
00128                         Destroyer()(counted_);
00129                         delete refs_;
00130                 }
00131         }
00132 
00140         ThisType& assign(T* c)
00141         {
00142                 // The create-temporary-and-swap idiom lets us keep memory
00143                 // allocation in the ctor and deallocation in the dtor so
00144                 // we don't leak in the face of an exception.
00145                 ThisType(c).swap(*this);
00146                 return *this;
00147         }
00148 
00157         ThisType& assign(const ThisType& other)
00158         {
00159                 // The create-temporary-and-swap idiom lets us keep memory
00160                 // allocation in the ctor and deallocation in the dtor so
00161                 // we don't leak in the face of an exception.
00162                 ThisType(other).swap(*this);
00163                 return *this;
00164         }
00165 
00170         ThisType& operator =(T* c)
00171         {
00172                 return assign(c);
00173         }
00174 
00180         ThisType& operator =(const ThisType& rhs)
00181         {
00182                 return assign(rhs);
00183         }
00184 
00186         T* operator ->() const
00187         {
00188                 return counted_;
00189         }       
00190 
00192         T& operator *() const
00193         {
00194                 return *counted_;
00195         }       
00196 
00216         operator void*()
00217         {
00218                 return counted_;
00219         }
00220 
00224         operator const void*() const
00225         {
00226                 return counted_;
00227         }
00228 
00230         T* raw()
00231         {
00232                 return counted_;
00233         }
00234 
00236         const T* raw() const
00237         {
00238                 return counted_;
00239         }
00240 
00245         void swap(ThisType& other)
00246         {
00247                 std::swap(counted_, other.counted_);
00248                 std::swap(refs_, other.refs_);
00249         }       
00250 
00251 private:
00253         T* counted_;
00254 
00260         size_t* refs_;
00261 };
00262 
00263 
00264 } // end namespace mysqlpp
00265 
00266 #endif // !defined(MYSQLPP_REFCOUNTED_H)
00267 

Generated on 10 Dec 2013 for MySQL++ by  doxygen 1.4.7