refcounted.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 /***********************************************************************
00005  Copyright (c) 2007 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 namespace mysqlpp {
00034 
00042 template <class T>
00043 struct RefCountedPointerDestroyer
00044 {
00046         void operator()(T* doomed) const { delete doomed; }
00047 };
00048 
00049 
00076 
00077 template <class T, class Destroyer = RefCountedPointerDestroyer<T> >
00078 class RefCountedPointer
00079 {
00080 public:
00081         typedef RefCountedPointer<T> ThisType;  
00082 
00087         RefCountedPointer() :
00088         counted_(0),
00089         refs_(0)
00090         {
00091         }
00092         
00098         explicit RefCountedPointer(T* c) :
00099         counted_(c),
00100         refs_(0)
00101         {
00102                 std::auto_ptr<T> exception_guard(counted_);
00103                 if (counted_) {
00104                         refs_ = new size_t(1);
00105                 }
00106                 exception_guard.release();      // previous new didn't throw
00107         }
00108 
00110         RefCountedPointer(const ThisType& other) :
00111         counted_(other.counted_),
00112         refs_(other.counted_ ? other.refs_ : 0)
00113         {
00114                 if (counted_) {
00115                         ++(*refs_);
00116                 }
00117         }
00118 
00123         ~RefCountedPointer()
00124         {
00125                 if (refs_ && (--(*refs_) == 0)) {
00126                         Destroyer()(counted_);
00127                         delete refs_;
00128                 }
00129         }
00130 
00138         ThisType& assign(T* c)
00139         {
00140                 // The create-temporary-and-swap idiom lets us keep memory
00141                 // allocation in the ctor and deallocation in the dtor so
00142                 // we don't leak in the face of an exception.
00143                 ThisType(c).swap(*this);
00144                 return *this;
00145         }
00146 
00155         ThisType& assign(const ThisType& other)
00156         {
00157                 // The create-temporary-and-swap idiom lets us keep memory
00158                 // allocation in the ctor and deallocation in the dtor so
00159                 // we don't leak in the face of an exception.
00160                 ThisType(other).swap(*this);
00161                 return *this;
00162         }
00163 
00168         ThisType& operator =(T* c)
00169         {
00170                 return assign(c);
00171         }
00172 
00178         ThisType& operator =(const ThisType& rhs)
00179         {
00180                 return assign(rhs);
00181         }
00182 
00184         T* operator ->() const
00185         {
00186                 return counted_;
00187         }       
00188 
00190         T& operator *() const
00191         {
00192                 return *counted_;
00193         }       
00194 
00214         operator void*()
00215         {
00216                 return counted_;
00217         }
00218 
00222         operator const void*() const
00223         {
00224                 return counted_;
00225         }
00226 
00228         T* raw()
00229         {
00230                 return counted_;
00231         }
00232 
00234         const T* raw() const
00235         {
00236                 return counted_;
00237         }
00238 
00243         void swap(ThisType& other)
00244         {
00245                 std::swap(counted_, other.counted_);
00246                 std::swap(refs_, other.refs_);
00247         }       
00248 
00249 private:
00251         T* counted_;
00252 
00258         size_t* refs_;
00259 };
00260 
00261 
00262 } // end namespace mysqlpp
00263 
00264 #endif // !defined(MYSQLPP_REFCOUNTED_H)
00265 

Generated on Thu Jun 3 11:59:12 2010 for MySQL++ by  doxygen 1.4.7