include/xapian/base.h

Go to the documentation of this file.
00001 
00004 /* Copyright 1999,2000,2001 BrightStation PLC
00005  * Copyright 2002 Ananova Ltd
00006  * Copyright 2002,2003,2004,2007 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
00021  * USA
00022  */
00023 
00024 #ifndef XAPIAN_INCLUDED_BASE_H
00025 #define XAPIAN_INCLUDED_BASE_H
00026 
00027 #include <xapian/deprecated.h>
00028 
00029 namespace Xapian {
00030 namespace Internal {
00031 
00036 class RefCntBase {
00037     /* Note: We never delete a pointer to a subclass of RefCntBase using
00038      * a RefCntBase *, so we don't need a virtual destructor here.
00039      */
00040     protected:
00048         RefCntBase(const RefCntBase &) : ref_count(0) { }
00049 
00050     public:
00052         RefCntBase() : ref_count(0) { }
00053 
00054         typedef unsigned int ref_count_t;
00055 
00059         mutable ref_count_t ref_count;
00060 };
00061 
00066 template <class T>
00067 class RefCntPtr {
00068     private:
00069         T *dest;
00070 
00071     public:
00072         T *operator->() const;
00073         T &operator*() const;
00074         T *get() const;
00083         RefCntPtr(T *dest_);
00084         RefCntPtr();
00085         RefCntPtr(const RefCntPtr &other);
00086         void operator=(const RefCntPtr &other);
00087         void operator=(T *dest_);
00088         ~RefCntPtr();
00089 
00090         template <class U>
00091         RefCntPtr(const RefCntPtr<U> &other);
00092 };
00093 
00094 template <class T>
00095 inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
00096 {
00097     if (dest) ++dest->ref_count;
00098 }
00099 
00100 template <class T>
00101 inline RefCntPtr<T>::RefCntPtr() : dest(0)
00102 {
00103 }
00104 
00105 template <class T>
00106 inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
00107 {
00108     if (dest) ++dest->ref_count;
00109 }
00110 
00111 template <class T>
00112 inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
00113     operator=(other.dest);
00114 }
00115 
00116 template <class T>
00117 inline void RefCntPtr<T>::operator=(T *dest_) {
00118     // check if we're assigning a pointer to itself
00119     if (dest == dest_) return;
00120 
00121     // copy the new dest in before we delete the old to avoid a small
00122     // window in which dest points to a deleted object
00123     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00124     T *old_dest = dest;
00125     dest = dest_;
00126     if (dest) ++dest->ref_count;
00127     if (old_dest && --old_dest->ref_count == 0) delete old_dest;
00128 }
00129 
00130 template <class T>
00131 inline RefCntPtr<T>::~RefCntPtr()
00132 {
00133     if (dest && --dest->ref_count == 0) {
00134         // zero before we delete to avoid a small window in which dest points
00135         // to a deleted object
00136         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
00137         T * condemned = dest;
00138         dest = 0;
00139         delete condemned;
00140     }
00141 }
00142 
00143 template <class T>
00144 template <class U>
00145 inline
00146 RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
00147         : dest(other.get())
00148 {
00149     if (dest) ++dest->ref_count;
00150 }
00151 
00152 template <class T>
00153 inline T *RefCntPtr<T>::operator->() const
00154 {
00155     return dest;
00156 }
00157 
00158 template <class T>
00159 inline T &RefCntPtr<T>::operator*() const
00160 {
00161     return *dest;
00162 }
00163 
00164 template <class T>
00165 inline T *RefCntPtr<T>::get() const
00166 {
00167     return dest;
00168 }
00169 
00170 }
00171 }
00172 
00173 #endif /* XAPIAN_INCLUDED_BASE_H */

Documentation for Xapian (version 1.0.20).
Generated on 28 Apr 2010 by Doxygen 1.5.2.