This file is indexed.

/usr/include/simgear/structure/SGWeakReferenced.hxx is in libsimgear-dev 1:2018.1.1+dfsg-1.

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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright (C) 2004-2009  Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#ifndef SGWeakReferenced_HXX
#define SGWeakReferenced_HXX

#include "SGReferenced.hxx"
#include "SGSharedPtr.hxx"

#include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp>

#ifdef _MSC_VER
# pragma warning(push)
  // C4355: 'this' : used in base member initializer list
  // Tell MSVC we know what we do and really want to do it this way.
# pragma warning(disable: 4355)
#endif

template<typename T>
class SGWeakPtr;
class SGVirtualWeakReferenced;

/**
 * Base class for all reference counted SimGear objects supporting weak
 * references, not incrementing the reference count.
 *
 * Classes derived from this one are meant to be managed with the SGSharedPtr
 * and SGWeakPtr classes.
 *
 * If the class hierarchy contains virtual base classes use
 * SGVirtualWeakReferenced instead.
 */
class SGWeakReferenced {
public:
  /// The object backref and the reference count for this object need to be
  /// there in any case. Also these are per object and shall not be copied nor
  /// assigned.
  /// The reference count for this object is stored in a secondary object that
  /// is shared with all weak pointers to this current object. This way we
  /// have an atomic decision using the reference count of this current object
  /// if the backref is still valid. At the time where the atomic count is
  /// equal to zero the object is considered dead.
  SGWeakReferenced(void) :
    mWeakData(new WeakData(this))
  {}
  SGWeakReferenced(const SGWeakReferenced& weakReferenced) :
    mWeakData(new WeakData(this))
  {}
  ~SGWeakReferenced(void)
  { mWeakData->mWeakReferenced = 0; }

  /// Do not copy the weak backward references ...
  SGWeakReferenced& operator=(const SGWeakReferenced&)
  { return *this; }

  /// The usual operations on weak pointers.
  /// The interface should stay the same then what we have in Referenced.
  static unsigned get(const SGWeakReferenced* ref)
  { if (ref) return ++(ref->mWeakData->mRefcount); else return 0; }
  static unsigned put(const SGWeakReferenced* ref)
  { if (ref) return --(ref->mWeakData->mRefcount); else return 0; }
  static unsigned count(const SGWeakReferenced* ref)
  { if (ref) return ref->mWeakData->mRefcount; else return 0; }

private:
  /// Support for weak references, not increasing the reference count
  /// that is done through that small helper class which holds an uncounted
  /// reference which is zeroed out on destruction of the current object
  class WeakData : public SGReferenced {
  public:
    WeakData(SGWeakReferenced* weakReferenced) :
      mRefcount(0u),
      mWeakReferenced(weakReferenced)
    { }

    template<typename T>
    T* getPointer()
    {
      // Try to increment the reference count if the count is greater
      // then zero. Since it should only be incremented iff it is nonzero, we
      // need to check that value and try to do an atomic test and set. If this
      // fails, try again. The usual lockless algorithm ...
      unsigned count;
      do {
        count = mRefcount;
        if (count == 0)
          return 0;
      } while (!mRefcount.compareAndExchange(count, count + 1));
      // We know that as long as the refcount is not zero, the pointer still
      // points to valid data. So it is safe to work on it.
      return up_cast<T>(mWeakReferenced);
    }

    SGAtomic mRefcount;
    SGWeakReferenced* mWeakReferenced;

  private:
    WeakData(void);
    WeakData(const WeakData&);
    WeakData& operator=(const WeakData&);

    /// Upcast in a class hierarchy with a virtual base class
    template<class T>
    static
    typename boost::enable_if<
      boost::is_base_of<SGVirtualWeakReferenced, T>,
      T*
    >::type
    up_cast(SGWeakReferenced* ptr);

    /// Upcast in a non-virtual class hierarchy
    template<class T>
    static
    typename boost::disable_if<
      boost::is_base_of<SGVirtualWeakReferenced, T>,
      T*
    >::type
    up_cast(SGWeakReferenced* ptr)
    {
      return static_cast<T*>(ptr);
    }
  };

  SGSharedPtr<WeakData> mWeakData;

  template<typename T>
  friend class SGWeakPtr;
};

/**
 * Base class for all reference counted SimGear objects with virtual base
 * classes, supporting weak references.
 *
 * Classes derived from this one are meant to be managed with the SGSharedPtr
 * and SGWeakPtr classes.
 *
 * @code{cpp}
 *
 * class Base1:
 *   public virtual SGVirtualWeakReferenced
 * {};
 *
 * class Base2:
 *   public virtual SGVirtualWeakReferenced
 * {};
 *
 * class Derived:
 *   public Base1,
 *   public Base2
 * {};
 *
 * SGSharedPtr<Derived> ptr( new Derived() );
 * SGWeakPtr<Derived> weak_ptr( ptr );
 * SGSharedPtr<Base1> ptr1( weak_ptr.lock() );
 * SGSharedPtr<Base2> ptr2( weak_ptr.lock() );
 *
 * @endcode
 */
class SGVirtualWeakReferenced:
  public SGWeakReferenced
{
  public:
    virtual ~SGVirtualWeakReferenced() {}
};

/// Upcast in a class hierarchy with a virtual base class
// We (clang) need the definition of SGVirtualWeakReferenced for the static_cast
template<class T>
typename boost::enable_if<
  boost::is_base_of<SGVirtualWeakReferenced, T>,
  T*
>::type
SGWeakReferenced::WeakData::up_cast(SGWeakReferenced* ptr)
{
  // First get the virtual base class, which then can be used to further
  // upcast.
  return dynamic_cast<T*>(static_cast<SGVirtualWeakReferenced*>(ptr));
}

#ifdef _MSC_VER
# pragma warning(pop)
#endif

#endif