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 
00032 namespace Xapian {
00033 namespace Internal {
00034 class RefCntBase {
00035     protected:
00043         RefCntBase(const RefCntBase &) : ref_count(0) { }
00044 
00045     public:
00047         RefCntBase() : ref_count(0) { }
00048 
00049         typedef unsigned int ref_count_t;
00050 
00052         mutable ref_count_t ref_count;
00053 };
00054 
00059 template <class T>
00060 class RefCntPtr {
00061     private:
00062         T *dest;
00063 
00064     public:
00065         T *operator->() const;
00066         T &operator*() const;
00067         T *get() const;
00076         RefCntPtr(T *dest_);
00077         RefCntPtr();
00078         RefCntPtr(const RefCntPtr &other);
00079         void operator=(const RefCntPtr &other);
00080         ~RefCntPtr();
00081 
00082         template <class U>
00083         RefCntPtr(const RefCntPtr<U> &other);
00084 };
00085 
00086 template <class T>
00087 inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
00088 {
00089     if (dest) ++dest->ref_count;
00090 }
00091 
00092 template <class T>
00093 inline RefCntPtr<T>::RefCntPtr() : dest(0)
00094 {
00095 }
00096 
00097 template <class T>
00098 inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
00099 {
00100     if (dest) ++dest->ref_count;
00101 }
00102 
00103 template <class T>
00104 inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
00105     // check if we're assigning a pointer to itself
00106     if (dest == other.dest) return;
00107     
00108     // copy the new dest in before we delete the old to avoid a small
00109     // window in which dest points to a deleted object
00110     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00111     T *old_dest = dest;
00112     dest = other.dest;
00113     if (dest) ++dest->ref_count;
00114     if (old_dest && --old_dest->ref_count == 0) delete old_dest;
00115 }
00116 
00117 template <class T>
00118 inline RefCntPtr<T>::~RefCntPtr()
00119 {
00120     if (dest && --dest->ref_count == 0) {
00121         // zero before we delete to avoid a small window in which dest points
00122         // to a deleted object
00123         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00124         T * condemned = dest;
00125         dest = 0;
00126         delete condemned;
00127     }
00128 }
00129 
00130 template <class T>
00131 template <class U>
00132 inline
00133 RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
00134         : dest(other.get())
00135 {
00136     if (dest) ++dest->ref_count;
00137 }
00138 
00139 template <class T>
00140 inline T *RefCntPtr<T>::operator->() const
00141 {
00142     return dest;
00143 }
00144 
00145 template <class T>
00146 inline T &RefCntPtr<T>::operator*() const
00147 {
00148     return *dest;
00149 }
00150 
00151 template <class T>
00152 inline T *RefCntPtr<T>::get() const
00153 {
00154     return dest;
00155 }
00156 
00157 }
00158 }
00159 
00160 #endif /* XAPIAN_INCLUDED_BASE_H */

Documentation for Xapian (version 0.6.5).
Generated on 4 Jul 2003 by Doxygen 1.2.15.