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. */
54 ref_ptr ()
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. */
88 ~ref_ptr ()
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. */
108 ref_ptr &operator= (ref_ptr &&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 */
gdb::operator==
constexpr bool operator==(const function_view< Res(Args...)> &f, std::nullptr_t) noexcept
Definition: function-view.h:303
gdb::operator!=
constexpr bool operator!=(const function_view< Res(Args...)> &f, std::nullptr_t) noexcept
Definition: function-view.h:313
gdb::ref_ptr::reset
void reset(T *obj)
Definition: gdb_ref_ptr.h:121
gdb::ref_ptr::ref_ptr
ref_ptr()
Definition: gdb_ref_ptr.h:54
gdb::ref_ptr
Definition: gdb_ref_ptr.h:49
gdb::ref_ptr::ref_ptr
ref_ptr(T *obj)
Definition: gdb_ref_ptr.h:67
gdb::ref_ptr::operator->
T * operator->() const
Definition: gdb_ref_ptr.h:147
gdb::ref_ptr::~ref_ptr
~ref_ptr()
Definition: gdb_ref_ptr.h:88
gdb::ref_ptr::ref_ptr
ref_ptr(const std::nullptr_t)
Definition: gdb_ref_ptr.h:60
gdb
Definition: array-view.h:66
gdb::ref_ptr::m_obj
T * m_obj
Definition: gdb_ref_ptr.h:154
gdb::ref_ptr::operator=
ref_ptr & operator=(const ref_ptr &other)
Definition: gdb_ref_ptr.h:95
gdb::ref_ptr::release
T * release()
Definition: gdb_ref_ptr.h:138
gdb::ref_ptr::get
T * get() const
Definition: gdb_ref_ptr.h:130
gdb::ref_ptr::ref_ptr
ref_ptr(const ref_ptr &other)
Definition: gdb_ref_ptr.h:73
gdb::ref_ptr::ref_ptr
ref_ptr(ref_ptr &&other)
Definition: gdb_ref_ptr.h:81