00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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();
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
00143
00144
00145 ThisType(c).swap(*this);
00146 return *this;
00147 }
00148
00157 ThisType& assign(const ThisType& other)
00158 {
00159
00160
00161
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 }
00265
00266 #endif // !defined(MYSQLPP_REFCOUNTED_H)
00267