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 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();
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
00141
00142
00143 ThisType(c).swap(*this);
00144 return *this;
00145 }
00146
00155 ThisType& assign(const ThisType& other)
00156 {
00157
00158
00159
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 }
00263
00264 #endif // !defined(MYSQLPP_REFCOUNTED_H)
00265