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 #ifndef XAPIAN_INCLUDED_BASE_H
00026 #define XAPIAN_INCLUDED_BASE_H
00027
00028 namespace Xapian {
00029 namespace Internal {
00030
00035 class RefCntBase {
00036 protected:
00044 RefCntBase(const RefCntBase &) : ref_count(0) { }
00045
00046 public:
00048 RefCntBase() : ref_count(0) { }
00049
00050 typedef unsigned int ref_count_t;
00051
00055 mutable ref_count_t ref_count;
00056 };
00057
00062 template <class T>
00063 class RefCntPtr {
00064 private:
00065 T *dest;
00066
00067 public:
00068 T *operator->() const;
00069 T &operator*() const;
00070 T *get() const;
00079 RefCntPtr(T *dest_);
00080 RefCntPtr();
00081 RefCntPtr(const RefCntPtr &other);
00082 void operator=(const RefCntPtr &other);
00083 void operator=(T *dest_);
00084 ~RefCntPtr();
00085
00086 template <class U>
00087 RefCntPtr(const RefCntPtr<U> &other);
00088 };
00089
00090 template <class T>
00091 inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
00092 {
00093 if (dest) ++dest->ref_count;
00094 }
00095
00096 template <class T>
00097 inline RefCntPtr<T>::RefCntPtr() : dest(0)
00098 {
00099 }
00100
00101 template <class T>
00102 inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
00103 {
00104 if (dest) ++dest->ref_count;
00105 }
00106
00107 template <class T>
00108 inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
00109 operator=(other.dest);
00110 }
00111
00112 template <class T>
00113 inline void RefCntPtr<T>::operator=(T *dest_) {
00114
00115 if (dest == dest_) return;
00116
00117
00118
00119
00120 T *old_dest = dest;
00121 dest = dest_;
00122 if (dest) ++dest->ref_count;
00123 if (old_dest && --old_dest->ref_count == 0) delete old_dest;
00124 }
00125
00126 template <class T>
00127 inline RefCntPtr<T>::~RefCntPtr()
00128 {
00129 if (dest && --dest->ref_count == 0) {
00130
00131
00132
00133 T * condemned = dest;
00134 dest = 0;
00135 delete condemned;
00136 }
00137 }
00138
00139 template <class T>
00140 template <class U>
00141 inline
00142 RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
00143 : dest(other.get())
00144 {
00145 if (dest) ++dest->ref_count;
00146 }
00147
00148 template <class T>
00149 inline T *RefCntPtr<T>::operator->() const
00150 {
00151 return dest;
00152 }
00153
00154 template <class T>
00155 inline T &RefCntPtr<T>::operator*() const
00156 {
00157 return *dest;
00158 }
00159
00160 template <class T>
00161 inline T *RefCntPtr<T>::get() const
00162 {
00163 return dest;
00164 }
00165
00166 }
00167 }
00168
00169 #endif