gem5  v20.1.0.0
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 
41 #ifndef __BASE_REFCNT_HH__
42 #define __BASE_REFCNT_HH__
43 
44 #include <type_traits>
45 
58 {
59  private:
60  // The reference count is mutable because one may want to
61  // reference count a const pointer. This really is OK because
62  // const is about logical constness of the object not really about
63  // strictly disallowing an object to change.
64  mutable int count;
65 
66  private:
67  // Don't allow a default copy constructor or copy operator on
68  // these objects because the default operation will copy the
69  // reference count as well and we certainly don't want that.
70  RefCounted(const RefCounted &);
72 
73  public:
81  RefCounted() : count(0) {}
82 
92  virtual ~RefCounted() {}
93 
95  void incref() const { ++count; }
96 
99  void decref() const { if (--count <= 0) delete this; }
100 };
101 
117 template <class T>
119 {
120  public:
121  using PtrType = T*;
122 
123  protected:
126  static constexpr auto TisConst = std::is_const<T>::value;
127  using ConstT = typename std::conditional<TisConst,
130  friend ConstT;
131  using NonConstT = typename std::conditional<TisConst,
134  friend NonConstT;
136  T *data;
139 
146  void
147  copy(T *d)
148  {
149  data = d;
150  if (data)
151  data->incref();
152  }
153 
159  void
160  del()
161  {
162  if (data)
163  data->decref();
164  }
165 
169  void
170  set(T *d)
171  {
172  // Need to check if we're actually changing because otherwise
173  // we could delete the last reference before adding the new
174  // reference.
175  if (data != d) {
176  del();
177  copy(d);
178  }
179  }
180 
181  public:
184 
188 
191  RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
192 
197  {
198  data = r.data;
199  r.data = nullptr;
200  }
201 
202  template <bool B = TisConst>
203  RefCountingPtr(const NonConstT &r) { copy(r.data); }
204 
207 
208  // The following pointer access functions are const because they
209  // don't actually change the pointer, though the user could change
210  // what is pointed to. This is analagous to a "Foo * const".
211 
213  T *operator->() const { return data; }
214 
216  T &operator*() const { return *data; }
217 
219  T *get() const { return data; }
220 
221  template <bool B = TisConst>
223  {
224  return RefCountingPtr<const T>(*this);
225  }
226 
228  const RefCountingPtr &operator=(T *p) { set(p); return *this; }
229 
232  { return operator=(r.data); }
233 
236  {
237  /* This happens regardless of whether the pointer is the same or not,
238  * because of the move semantics, the rvalue needs to be 'destroyed'.
239  */
240  del();
241  data = r.data;
242  r.data = nullptr;
243  return *this;
244  }
245 
247  bool operator!() const { return data == 0; }
248 
250  operator bool() const { return data != 0; }
251 };
252 
254 template<class T>
255 inline bool operator==(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
256 { return l.get() == r.get(); }
257 
260 template<class T>
261 inline bool operator==(const RefCountingPtr<T> &l, const T *r)
262 { return l.get() == r; }
263 
266 template<class T>
267 inline bool operator==(const T *l, const RefCountingPtr<T> &r)
268 { return l == r.get(); }
269 
271 template<class T>
272 inline bool operator!=(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
273 { return l.get() != r.get(); }
274 
277 template<class T>
278 inline bool operator!=(const RefCountingPtr<T> &l, const T *r)
279 { return l.get() != r; }
280 
283 template<class T>
284 inline bool operator!=(const T *l, const RefCountingPtr<T> &r)
285 { return l != r.get(); }
286 
287 #endif // __BASE_REFCNT_HH__
RefCounted::RefCounted
RefCounted()
We initialize the reference count to zero and the first object to take ownership of it must increment...
Definition: refcnt.hh:81
RefCountingPtr::NonConstT
friend NonConstT
Definition: refcnt.hh:134
RefCountingPtr::RefCountingPtr
RefCountingPtr()
Create an empty reference counting pointer.
Definition: refcnt.hh:183
RefCountingPtr::operator=
const RefCountingPtr & operator=(RefCountingPtr &&r)
Move-assign the pointer from another RefCountingPtr.
Definition: refcnt.hh:235
RefCountingPtr::ConstT
friend ConstT
Definition: refcnt.hh:130
type
uint8_t type
Definition: inet.hh:421
RefCounted::count
int count
Definition: refcnt.hh:64
RefCountingPtr< MinorDynInst >::ConstT
typename std::conditional< TisConst, RefCountingPtr< MinorDynInst >, RefCountingPtr< typename std::add_const< MinorDynInst >::type > >::type ConstT
Definition: refcnt.hh:129
RefCountingPtr::operator=
const RefCountingPtr & operator=(T *p)
Assign a new value to the pointer.
Definition: refcnt.hh:228
RefCountingPtr::RefCountingPtr
RefCountingPtr(T *data)
Create a new reference counting pointer to some object (probably something newly created).
Definition: refcnt.hh:187
RefCounted::operator=
RefCounted & operator=(const RefCounted &)
RefCountingPtr::set
void set(T *d)
Drop the old reference and change it to something new.
Definition: refcnt.hh:170
RefCountingPtr::RefCountingPtr
RefCountingPtr(const NonConstT &r)
Definition: refcnt.hh:203
RefCountingPtr< MinorDynInst >::PtrType
MinorDynInst * PtrType
Definition: refcnt.hh:121
RefCountingPtr::~RefCountingPtr
~RefCountingPtr()
Destroy the pointer and any reference it may hold.
Definition: refcnt.hh:206
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
MipsISA::r
r
Definition: pra_constants.hh:95
RefCounted::incref
void incref() const
Increment the reference count.
Definition: refcnt.hh:95
RefCounted::~RefCounted
virtual ~RefCounted()
We make the destructor virtual because we're likely to have virtual functions on reference counted ob...
Definition: refcnt.hh:92
RefCountingPtr::RefCountingPtr
RefCountingPtr(RefCountingPtr &&r)
Move-constructor.
Definition: refcnt.hh:196
RefCountingPtr::operator*
T & operator*() const
Dereference the pointer.
Definition: refcnt.hh:216
RefCountingPtr::operator=
const RefCountingPtr & operator=(const RefCountingPtr &r)
Copy the pointer from another RefCountingPtr.
Definition: refcnt.hh:231
RefCountingPtr::del
void del()
Delete the reference to any existing object if it is non NULL.
Definition: refcnt.hh:160
RefCounted::decref
void decref() const
Decrement the reference count and destroy the object if all references are gone.
Definition: refcnt.hh:99
RefCountingPtr::RefCountingPtr
RefCountingPtr(const RefCountingPtr &r)
Create a new reference counting pointer by copying another one.
Definition: refcnt.hh:191
RefCountingPtr< MinorDynInst >::NonConstT
typename std::conditional< TisConst, RefCountingPtr< typename std::remove_const< MinorDynInst >::type >, RefCountingPtr< MinorDynInst > >::type NonConstT
Definition: refcnt.hh:133
RefCountingPtr::operator->
T * operator->() const
Access a member variable.
Definition: refcnt.hh:213
RefCounted
Derive from RefCounted if you want to enable reference counting of this class.
Definition: refcnt.hh:57
RefCountingPtr::operator!
bool operator!() const
Check if the pointer is empty.
Definition: refcnt.hh:247
RefCountingPtr::copy
void copy(T *d)
Copy a new pointer value and increment the reference count if it is a valid pointer.
Definition: refcnt.hh:147
operator!=
bool operator!=(const RefCountingPtr< T > &l, const RefCountingPtr< T > &r)
Check for inequality of two reference counting pointers.
Definition: refcnt.hh:272
operator==
bool operator==(const RefCountingPtr< T > &l, const RefCountingPtr< T > &r)
Check for equality of two reference counting pointers.
Definition: refcnt.hh:255
RefCountingPtr::TisConst
static constexpr auto TisConst
Convenience aliases for const/non-const versions of T w/ friendship.
Definition: refcnt.hh:126
RefCountingPtr
If you want a reference counting pointer to a mutable object, create it like this:
Definition: refcnt.hh:118
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:320
RefCountingPtr::data
T * data
The stored pointer.
Definition: refcnt.hh:138
RefCountingPtr::get
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:219

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17