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
00053 mutable ref_count_t ref_count;
00054 };
00055
00060 template <class T>
00061 class RefCntPtr {
00062 private:
00063 T *dest;
00064
00065 public:
00066 T *operator->() const;
00067 T &operator*() const;
00068 T *get() const;
00077 RefCntPtr(T *dest_);
00078 RefCntPtr();
00079 RefCntPtr(const RefCntPtr &other);
00080 void operator=(const RefCntPtr &other);
00081 ~RefCntPtr();
00082
00083 template <class U>
00084 RefCntPtr(const RefCntPtr<U> &other);
00085 };
00086
00087 template <class T>
00088 inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
00089 {
00090 if (dest) ++dest->ref_count;
00091 }
00092
00093 template <class T>
00094 inline RefCntPtr<T>::RefCntPtr() : dest(0)
00095 {
00096 }
00097
00098 template <class T>
00099 inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
00100 {
00101 if (dest) ++dest->ref_count;
00102 }
00103
00104 template <class T>
00105 inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
00106
00107 if (dest == other.dest) return;
00108
00109
00110
00111
00112 T *old_dest = dest;
00113 dest = other.dest;
00114 if (dest) ++dest->ref_count;
00115 if (old_dest && --old_dest->ref_count == 0) delete old_dest;
00116 }
00117
00118 template <class T>
00119 inline RefCntPtr<T>::~RefCntPtr()
00120 {
00121 if (dest && --dest->ref_count == 0) {
00122
00123
00124
00125 T * condemned = dest;
00126 dest = 0;
00127 delete condemned;
00128 }
00129 }
00130
00131 template <class T>
00132 template <class U>
00133 inline
00134 RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
00135 : dest(other.get())
00136 {
00137 if (dest) ++dest->ref_count;
00138 }
00139
00140 template <class T>
00141 inline T *RefCntPtr<T>::operator->() const
00142 {
00143 return dest;
00144 }
00145
00146 template <class T>
00147 inline T &RefCntPtr<T>::operator*() const
00148 {
00149 return *dest;
00150 }
00151
00152 template <class T>
00153 inline T *RefCntPtr<T>::get() const
00154 {
00155 return dest;
00156 }
00157
00158 }
00159 }
00160
00161 #endif