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