Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

/include/xapian/base.h

00001 /* base.h: Reference-counted pointers
00002  *
00003  * ----START-LICENCE----
00004  * Copyright 1999,2000,2001 BrightStation PLC
00005  * Copyright 2002 Ananova Ltd
00006  * Copyright 2002,2003,2004 Olly Betts
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA
00022  * -----END-LICENCE-----
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     // check if we're assigning a pointer to itself
00115     if (dest == dest_) return;
00116 
00117     // copy the new dest in before we delete the old to avoid a small
00118     // window in which dest points to a deleted object
00119     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
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         // zero before we delete to avoid a small window in which dest points
00131         // to a deleted object
00132         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
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 /* XAPIAN_INCLUDED_BASE_H */

Documentation for Xapian (version 0.8.1).
Generated on 30 Jun 2004 by Doxygen 1.2.15.