GDB (xrefs)
gdb_ref_ptr.h
Go to the documentation of this file.
1 /* Reference-counted smart pointer class
2 
3  Copyright (C) 2016-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (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, see <http://www.gnu.org/licenses/>. */
19 
20 #ifndef GDB_REF_PTR_H
21 #define GDB_REF_PTR_H
22 
23 #include <cstddef>
24 
25 namespace gdb
26 {
27 
28 /* An instance of this class either holds a reference to a
29  reference-counted object or is "NULL". Reference counting is
30  handled externally by a policy class. If the object holds a
31  reference, then when the object is destroyed, the reference is
32  decref'd.
33 
34  Normally an instance is constructed using a pointer. This sort of
35  initialization lets this class manage the lifetime of that
36  reference.
37 
38  Assignment and copy construction will make a new reference as
39  appropriate. Assignment from a plain pointer is disallowed to
40  avoid confusion about whether this acquires a new reference;
41  instead use the "reset" method -- which, like the pointer
42  constructor, transfers ownership.
43 
44  The policy class must provide two static methods:
45  void incref (T *);
46  void decref (T *);
47 */
48 template<typename T, typename Policy>
49 class ref_ptr
50 {
51  public:
52 
53  /* Create a new NULL instance. */
55  : m_obj (NULL)
56  {
57  }
58 
59  /* Create a new NULL instance. Note that this is not explicit. */
60  ref_ptr (const std::nullptr_t)
61  : m_obj (NULL)
62  {
63  }
64 
65  /* Create a new instance. OBJ is a reference, management of which
66  is now transferred to this class. */
67  explicit ref_ptr (T *obj)
68  : m_obj (obj)
69  {
70  }
71 
72  /* Copy another instance. */
73  ref_ptr (const ref_ptr &other)
74  : m_obj (other.m_obj)
75  {
76  if (m_obj != NULL)
77  Policy::incref (m_obj);
78  }
79 
80  /* Transfer ownership from OTHER. */
81  ref_ptr (ref_ptr &&other)
82  : m_obj (other.m_obj)
83  {
84  other.m_obj = NULL;
85  }
86 
87  /* Destroy this instance. */
89  {
90  if (m_obj != NULL)
91  Policy::decref (m_obj);
92  }
93 
94  /* Copy another instance. */
95  ref_ptr &operator= (const ref_ptr &other)
96  {
97  /* Do nothing on self-assignment. */
98  if (this != &other)
99  {
100  reset (other.m_obj);
101  if (m_obj != NULL)
102  Policy::incref (m_obj);
103  }
104  return *this;
105  }
106 
107  /* Transfer ownership from OTHER. */
109  {
110  /* Do nothing on self-assignment. */
111  if (this != &other)
112  {
113  reset (other.m_obj);
114  other.m_obj = NULL;
115  }
116  return *this;
117  }
118 
119  /* Change this instance's referent. OBJ is a reference, management
120  of which is now transferred to this class. */
121  void reset (T *obj)
122  {
123  if (m_obj != NULL)
124  Policy::decref (m_obj);
125  m_obj = obj;
126  }
127 
128  /* Return this instance's referent without changing the state of
129  this class. */
130  T *get () const
131  {
132  return m_obj;
133  }
134 
135  /* Return this instance's referent, and stop managing this
136  reference. The caller is now responsible for the ownership of
137  the reference. */
138  T *release ()
139  {
140  T *result = m_obj;
141 
142  m_obj = NULL;
143  return result;
144  }
145 
146  /* Let users refer to members of the underlying pointer. */
147  T *operator-> () const
148  {
149  return m_obj;
150  }
151 
152  private:
153 
154  T *m_obj;
155 };
156 
157 template<typename T, typename Policy>
158 inline bool operator== (const ref_ptr<T, Policy> &lhs,
159  const ref_ptr<T, Policy> &rhs)
160 {
161  return lhs.get () == rhs.get ();
162 }
163 
164 template<typename T, typename Policy>
165 inline bool operator== (const ref_ptr<T, Policy> &lhs, const T *rhs)
166 {
167  return lhs.get () == rhs;
168 }
169 
170 template<typename T, typename Policy>
171 inline bool operator== (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
172 {
173  return lhs.get () == nullptr;
174 }
175 
176 template<typename T, typename Policy>
177 inline bool operator== (const T *lhs, const ref_ptr<T, Policy> &rhs)
178 {
179  return lhs == rhs.get ();
180 }
181 
182 template<typename T, typename Policy>
183 inline bool operator== (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
184 {
185  return nullptr == rhs.get ();
186 }
187 
188 template<typename T, typename Policy>
189 inline bool operator!= (const ref_ptr<T, Policy> &lhs,
190  const ref_ptr<T, Policy> &rhs)
191 {
192  return lhs.get () != rhs.get ();
193 }
194 
195 template<typename T, typename Policy>
196 inline bool operator!= (const ref_ptr<T, Policy> &lhs, const T *rhs)
197 {
198  return lhs.get () != rhs;
199 }
200 
201 template<typename T, typename Policy>
202 inline bool operator!= (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
203 {
204  return lhs.get () != nullptr;
205 }
206 
207 template<typename T, typename Policy>
208 inline bool operator!= (const T *lhs, const ref_ptr<T, Policy> &rhs)
209 {
210  return lhs != rhs.get ();
211 }
212 
213 template<typename T, typename Policy>
214 inline bool operator!= (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
215 {
216  return nullptr != rhs.get ();
217 }
218 
219 }
220 
221 #endif /* GDB_REF_PTR_H */
constexpr bool operator==(const function_view< Res(Args...)> &f, std::nullptr_t) noexcept
constexpr bool operator!=(const function_view< Res(Args...)> &f, std::nullptr_t) noexcept
void reset(T *obj)
Definition: gdb_ref_ptr.h:121
ref_ptr(T *obj)
Definition: gdb_ref_ptr.h:67
T * operator->() const
Definition: gdb_ref_ptr.h:147
ref_ptr(const std::nullptr_t)
Definition: gdb_ref_ptr.h:60
Definition: array-view.h:66
ref_ptr & operator=(const ref_ptr &other)
Definition: gdb_ref_ptr.h:95
T * get() const
Definition: gdb_ref_ptr.h:130
ref_ptr(const ref_ptr &other)
Definition: gdb_ref_ptr.h:73
ref_ptr(ref_ptr &&other)
Definition: gdb_ref_ptr.h:81