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 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 
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     // check if we're assigning a pointer to itself
00107     if (dest == other.dest) return;
00108     
00109     // copy the new dest in before we delete the old to avoid a small
00110     // window in which dest points to a deleted object
00111     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
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         // zero before we delete to avoid a small window in which dest points
00123         // to a deleted object
00124         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
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 /* XAPIAN_INCLUDED_BASE_H */

Documentation for Xapian (version 0.7.1).
Generated on 11 Jul 2003 by Doxygen 1.2.15.