LTP GCOV extension - code coverage report
Current view: | directory - usr/include/xapian - base.h
Test: | lcov.info
Date: | 2008-08-14 |  | Instrumented lines: | 11
Code covered: | 45.5 % |  | Executed lines: | 5

           1                 : /* base.h: Reference-counted pointers
           2                 :  *
           3                 :  * Copyright 1999,2000,2001 BrightStation PLC
           4                 :  * Copyright 2002 Ananova Ltd
           5                 :  * Copyright 2002,2003,2004,2007 Olly Betts
           6                 :  *
           7                 :  * This program is free software; you can redistribute it and/or
           8                 :  * modify it under the terms of the GNU General Public License as
           9                 :  * published by the Free Software Foundation; either version 2 of the
          10                 :  * License, or (at your option) any later version.
          11                 :  *
          12                 :  * This program is distributed in the hope that it will be useful,
          13                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
          14                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          15                 :  * GNU General Public License for more details.
          16                 :  *
          17                 :  * You should have received a copy of the GNU General Public License
          18                 :  * along with this program; if not, write to the Free Software
          19                 :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
          20                 :  * USA
          21                 :  */
          22                 :
          23                 : #ifndef XAPIAN_INCLUDED_BASE_H
          24                 : #define XAPIAN_INCLUDED_BASE_H
          25                 :
          26                 : #include <xapian/deprecated.h>
          27                 :
          28                 : namespace Xapian {
          29                 : namespace Internal {
          30                 :
          31                 : /** @internal Reference counted internal classes should inherit from RefCntBase.
          32                 :  *
          33                 :  * This gives the object a reference count used by RefCntPtr.
          34                 :  */
          35                 : class RefCntBase {
          36                 :     /* Note: We never delete a pointer to a subclass of RefCntBase using
          37                 :      * a RefCntBase *, so we don't need a virtual destructor here.
          38                 :      */
          39                 :     protected:
          40                 :         /** The copy constructor.
          41                 :          *
          42                 :          *  This is protected since it'll only be used by derived classes,
          43                 :          *  which should only rarely need copying (this is, after all, a
          44                 :          *  refcount implementation).  Sometimes it's needed, though,
          45                 :          *  since we need to zero ref_count in the copy.
          46                 :          */
          47                 :         RefCntBase(const RefCntBase &) : ref_count(0) { }
          48                 :
          49                 :     public:
          50                 :         /// The constructor, which initialises the ref_count to 0.
          51                 :         RefCntBase() : ref_count(0) { }
          52                 :
          53                 :         typedef unsigned int ref_count_t;
          54                 :
          55                 :         /** The actual reference count.  It's mutable so we can have reference
          56                 :          *  counting work with const pointers.
          57                 :          */
          58                 :         mutable ref_count_t ref_count;
          59                 : };
          60                 :
          61                 : /** @internal A reference-counted pointer.  Can be used with any
          62                 :  *  class derived from RefCntBase, as long as it is allocated
          63                 :  *  on the heap by new (not new[]!).
          64                 :  */
          65                 : template <class T>
          66                 : class RefCntPtr {
          67                 :     private:
          68                 :         T *dest;
          69                 :
          70                 :     public:
          71                 :         T *operator->() const;
          72                 :         T &operator*() const;
          73                 :         T *get() const;
          74                 :         /** Make a RefCntPtr for an object which may already
          75                 :          *  have reference counted pointers.
          76                 :          *
          77                 :          *  You usually pass in a newly created object, or an object may pass
          78                 :          *  in "this" to get a RefCntPtr to itself to pass to other classes.
          79                 :          *  (e.g. a database might pass a newly created postlist a reference
          80                 :          *  counted pointer to itself.)
          81                 :          */
          82                 :         RefCntPtr(T *dest_);
          83                 :         RefCntPtr();
          84                 :         RefCntPtr(const RefCntPtr &other);
          85                 :         void operator=(const RefCntPtr &other);
          86                 :         void operator=(T *dest_);
          87                 :         ~RefCntPtr();
          88                 :
          89                 :         template <class U>
          90                 :         RefCntPtr(const RefCntPtr<U> &other);
          91                 : };
          92                 :
          93                 : template <class T>
          94              19 : inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_)
          95                 : {
          96              19 :     if (dest) ++dest->ref_count;
          97              19 : }
          98                 :
          99                 : template <class T>
         100                 : inline RefCntPtr<T>::RefCntPtr() : dest(0)
         101                 : {
         102                 : }
         103                 :
         104                 : template <class T>
         105                 : inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest)
         106                 : {
         107                 :     if (dest) ++dest->ref_count;
         108                 : }
         109                 :
         110                 : template <class T>
         111                 : inline void RefCntPtr<T>::operator=(const RefCntPtr &other) {
         112                 :     operator=(other.dest);
         113                 : }
         114                 :
         115                 : template <class T>
         116                 : inline void RefCntPtr<T>::operator=(T *dest_) {
         117                 :     // check if we're assigning a pointer to itself
         118                 :     if (dest == dest_) return;
         119                 :
         120                 :     // copy the new dest in before we delete the old to avoid a small
         121                 :     // window in which dest points to a deleted object
         122                 :     // FIXME: if pointer assignment isn't atomic, we ought to use locking...
         123                 :     T *old_dest = dest;
         124                 :     dest = dest_;
         125                 :     if (dest) ++dest->ref_count;
         126                 :     if (old_dest && --old_dest->ref_count == 0) delete old_dest;
         127                 : }
         128                 :
         129                 : template <class T>
         130               0 : inline RefCntPtr<T>::~RefCntPtr()
         131                 : {
         132               0 :     if (dest && --dest->ref_count == 0) {
         133                 :         // zero before we delete to avoid a small window in which dest points
         134                 :         // to a deleted object
         135                 :         // FIXME: if pointer assignment isn't atomic, we ought to use locking...
         136               0 :         T * condemned = dest;
         137               0 :         dest = 0;
         138               0 :         delete condemned;
         139                 :     }
         140               0 : }
         141                 :
         142                 : template <class T>
         143                 : template <class U>
         144                 : inline
         145                 : RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other)
         146                 :         : dest(other.get())
         147                 : {
         148                 :     if (dest) ++dest->ref_count;
         149                 : }
         150                 :
         151                 : template <class T>
         152                 : inline T *RefCntPtr<T>::operator->() const
         153                 : {
         154                 :     return dest;
         155                 : }
         156                 :
         157                 : template <class T>
         158                 : inline T &RefCntPtr<T>::operator*() const
         159                 : {
         160                 :     return *dest;
         161                 : }
         162                 :
         163                 : template <class T>
         164              30 : inline T *RefCntPtr<T>::get() const
         165                 : {
         166              30 :     return dest;
         167                 : }
         168                 :
         169                 : }
         170                 : }
         171                 :
         172                 : #endif /* XAPIAN_INCLUDED_BASE_H */

Generated by: LTP GCOV extension version 1.6