gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
refcnt.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2018 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2002-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Nathan Binkert
41  */
42 
43 #ifndef __BASE_REFCNT_HH__
44 #define __BASE_REFCNT_HH__
45 
46 #include <type_traits>
47 
60 {
61  private:
62  // The reference count is mutable because one may want to
63  // reference count a const pointer. This really is OK because
64  // const is about logical constness of the object not really about
65  // strictly disallowing an object to change.
66  mutable int count;
67 
68  private:
69  // Don't allow a default copy constructor or copy operator on
70  // these objects because the default operation will copy the
71  // reference count as well and we certainly don't want that.
72  RefCounted(const RefCounted &);
74 
75  public:
83  RefCounted() : count(0) {}
84 
94  virtual ~RefCounted() {}
95 
97  void incref() const { ++count; }
98 
101  void decref() const { if (--count <= 0) delete this; }
102 };
103 
119 template <class T>
121 {
122  public:
123  using PtrType = T*;
124 
125  protected:
128  static constexpr auto TisConst = std::is_const<T>::value;
129  using ConstT = typename std::conditional<TisConst,
132  friend ConstT;
133  using NonConstT = typename std::conditional<TisConst,
135  RefCountingPtr<T>>::type;
136  friend NonConstT;
138  T *data;
141 
148  void
149  copy(T *d)
150  {
151  data = d;
152  if (data)
153  data->incref();
154  }
155 
161  void
162  del()
163  {
164  if (data)
165  data->decref();
166  }
167 
171  void
172  set(T *d)
173  {
174  // Need to check if we're actually changing because otherwise
175  // we could delete the last reference before adding the new
176  // reference.
177  if (data != d) {
178  del();
179  copy(d);
180  }
181  }
182 
183  public:
185  RefCountingPtr() : data(0) {}
186 
189  RefCountingPtr(T *data) { copy(data); }
190 
193  RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
194 
199  {
200  data = r.data;
201  r.data = nullptr;
202  }
203 
204  template <bool B = TisConst>
205  RefCountingPtr(const NonConstT &r) { copy(r.data); }
206 
208  ~RefCountingPtr() { del(); }
209 
210  // The following pointer access functions are const because they
211  // don't actually change the pointer, though the user could change
212  // what is pointed to. This is analagous to a "Foo * const".
213 
215  T *operator->() const { return data; }
216 
218  T &operator*() const { return *data; }
219 
221  T *get() const { return data; }
222 
223  template <bool B = TisConst>
225  {
226  return RefCountingPtr<const T>(*this);
227  }
228 
230  const RefCountingPtr &operator=(T *p) { set(p); return *this; }
231 
234  { return operator=(r.data); }
235 
238  {
239  /* This happens regardless of whether the pointer is the same or not,
240  * because of the move semantics, the rvalue needs to be 'destroyed'.
241  */
242  del();
243  data = r.data;
244  r.data = nullptr;
245  return *this;
246  }
247 
249  bool operator!() const { return data == 0; }
250 
252  operator bool() const { return data != 0; }
253 };
254 
256 template<class T>
257 inline bool operator==(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
258 { return l.get() == r.get(); }
259 
262 template<class T>
263 inline bool operator==(const RefCountingPtr<T> &l, const T *r)
264 { return l.get() == r; }
265 
268 template<class T>
269 inline bool operator==(const T *l, const RefCountingPtr<T> &r)
270 { return l == r.get(); }
271 
273 template<class T>
274 inline bool operator!=(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
275 { return l.get() != r.get(); }
276 
279 template<class T>
280 inline bool operator!=(const RefCountingPtr<T> &l, const T *r)
281 { return l.get() != r; }
282 
285 template<class T>
286 inline bool operator!=(const T *l, const RefCountingPtr<T> &r)
287 { return l != r.get(); }
288 
289 #endif // __BASE_REFCNT_HH__
friend ConstT
Definition: refcnt.hh:132
typename std::conditional< TisConst, RefCountingPtr< MinorDynInst >, RefCountingPtr< typename std::add_const< MinorDynInst >::type > >::type ConstT
Definition: refcnt.hh:131
virtual ~RefCounted()
We make the destructor virtual because we&#39;re likely to have virtual functions on reference counted ob...
Definition: refcnt.hh:94
const RefCountingPtr & operator=(RefCountingPtr &&r)
Move-assign the pointer from another RefCountingPtr.
Definition: refcnt.hh:237
friend NonConstT
Definition: refcnt.hh:136
If you want a reference counting pointer to a mutable object, create it like this: ...
Definition: refcnt.hh:120
RefCountingPtr()
Create an empty reference counting pointer.
Definition: refcnt.hh:185
const RefCountingPtr & operator=(T *p)
Assign a new value to the pointer.
Definition: refcnt.hh:230
RefCountingPtr(RefCountingPtr &&r)
Move-constructor.
Definition: refcnt.hh:198
uint8_t type
Definition: inet.hh:333
~RefCountingPtr()
Destroy the pointer and any reference it may hold.
Definition: refcnt.hh:208
RefCounted()
We initialize the reference count to zero and the first object to take ownership of it must increment...
Definition: refcnt.hh:83
Bitfield< 9 > d
void del()
Delete the reference to any existing object if it is non NULL.
Definition: refcnt.hh:162
Derive from RefCounted if you want to enable reference counting of this class.
Definition: refcnt.hh:59
typename std::conditional< TisConst, RefCountingPtr< typename std::remove_const< MinorDynInst >::type >, RefCountingPtr< MinorDynInst > >::type NonConstT
Definition: refcnt.hh:135
RefCountingPtr(T *data)
Create a new reference counting pointer to some object (probably something newly created).
Definition: refcnt.hh:189
RefCountingPtr(const RefCountingPtr &r)
Create a new reference counting pointer by copying another one.
Definition: refcnt.hh:193
T * operator->() const
Access a member variable.
Definition: refcnt.hh:215
T & operator*() const
Dereference the pointer.
Definition: refcnt.hh:218
bool operator==(const RefCountingPtr< T > &l, const RefCountingPtr< T > &r)
Check for equality of two reference counting pointers.
Definition: refcnt.hh:257
RefCountingPtr(const NonConstT &r)
Definition: refcnt.hh:205
RefCounted & operator=(const RefCounted &)
void copy(T *d)
Copy a new pointer value and increment the reference count if it is a valid pointer.
Definition: refcnt.hh:149
bool operator!=(const RefCountingPtr< T > &l, const RefCountingPtr< T > &r)
Check for inequality of two reference counting pointers.
Definition: refcnt.hh:274
const RefCountingPtr & operator=(const RefCountingPtr &r)
Copy the pointer from another RefCountingPtr.
Definition: refcnt.hh:233
bool operator!() const
Check if the pointer is empty.
Definition: refcnt.hh:249
T * data
The stored pointer.
Definition: refcnt.hh:140
Bitfield< 0 > p
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:221
const char data[]
int count
Definition: refcnt.hh:66
Bitfield< 5 > l
void incref() const
Increment the reference count.
Definition: refcnt.hh:97
void decref() const
Decrement the reference count and destroy the object if all references are gone.
Definition: refcnt.hh:101

Generated on Fri Feb 28 2020 16:26:58 for gem5 by doxygen 1.8.13