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 #include <xapian/deprecated.h>
00029 
00030 namespace Xapian {
00031 namespace Internal {
00032 
00037 class RefCntBase {
00038     protected:
00046         RefCntBase(const RefCntBase &) : ref_count(0) { }
00047 
00048     public:
00050         RefCntBase() : ref_count(0) { }
00051 
00052         typedef unsigned int ref_count_t;
00053 
00057         mutable ref_count_t ref_count;
00058 };
00059 
00064 template <class T>
00065 class RefCntPtr {
00066     private:
00067         T *dest;
00068 
00069     public:
00070         T *operator->() const;
00071         T &operator*() const;
00072         T *get() const;
00081         RefCntPtr(T *dest_);
00082         RefCntPtr();
00083         RefCntPtr(const RefCntPtr &other);
00084         void operator=(const RefCntPtr &other);
00085         void operator=(T *dest_);
00086         ~RefCntPtr();
00087 
00088         template <class U>
00089         RefCntPtr(const RefCntPtr<U> &other);
00090 };
00091 
00092 template <class T>
00093 inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
00094 {
00095     if (dest) ++dest->ref_count;
00096 }
00097 
00098 template <class T>
00099 inline RefCntPtr<T>::RefCntPtr() : dest(0)
00100 {
00101 }
00102 
00103 template <class T>
00104 inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
00105 {
00106     if (dest) ++dest->ref_count;
00107 }
00108 
00109 template <class T>
00110 inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
00111     operator=(other.dest);
00112 }
00113 
00114 template <class T>
00115 inline void RefCntPtr<T>::operator=(T *dest_) {
00116     // check if we're assigning a pointer to itself
00117     if (dest == dest_) return;
00118 
00119     // copy the new dest in before we delete the old to avoid a small
00120     // window in which dest points to a deleted object
00121     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00122     T *old_dest = dest;
00123     dest = dest_;
00124     if (dest) ++dest->ref_count;
00125     if (old_dest && --old_dest->ref_count == 0) delete old_dest;
00126 }
00127 
00128 template <class T>
00129 inline RefCntPtr<T>::~RefCntPtr()
00130 {
00131     if (dest && --dest->ref_count == 0) {
00132         // zero before we delete to avoid a small window in which dest points
00133         // to a deleted object
00134         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00135         T * condemned = dest;
00136         dest = 0;
00137         delete condemned;
00138     }
00139 }
00140 
00141 template <class T>
00142 template <class U>
00143 inline
00144 RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
00145         : dest(other.get())
00146 {
00147     if (dest) ++dest->ref_count;
00148 }
00149 
00150 template <class T>
00151 inline T *RefCntPtr<T>::operator->() const
00152 {
00153     return dest;
00154 }
00155 
00156 template <class T>
00157 inline T &RefCntPtr<T>::operator*() const
00158 {
00159     return *dest;
00160 }
00161 
00162 template <class T>
00163 inline T *RefCntPtr<T>::get() const
00164 {
00165     return dest;
00166 }
00167 
00168 }
00169 }
00170 
00171 #endif /* XAPIAN_INCLUDED_BASE_H */

Documentation for Xapian (version 0.9.6).
Generated on 15 May 2006 by Doxygen 1.4.6.