]> Git Repo - binutils.git/blob - gdbsupport/gdb_ref_ptr.h
Automatic date update in version.in
[binutils.git] / gdbsupport / gdb_ref_ptr.h
1 /* Reference-counted smart pointer class
2
3    Copyright (C) 2016-2022 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 COMMON_GDB_REF_PTR_H
21 #define COMMON_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) noexcept
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   ATTRIBUTE_UNUSED_RESULT 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   /* Acquire a new reference and return a ref_ptr that owns it.  */
153   static ref_ptr<T, Policy> new_reference (T *obj)
154   {
155     Policy::incref (obj);
156     return ref_ptr<T, Policy> (obj);
157   }
158
159  private:
160
161   T *m_obj;
162 };
163
164 template<typename T, typename Policy>
165 inline bool operator== (const ref_ptr<T, Policy> &lhs,
166                         const ref_ptr<T, Policy> &rhs)
167 {
168   return lhs.get () == rhs.get ();
169 }
170
171 template<typename T, typename Policy>
172 inline bool operator== (const ref_ptr<T, Policy> &lhs, const T *rhs)
173 {
174   return lhs.get () == rhs;
175 }
176
177 template<typename T, typename Policy>
178 inline bool operator== (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
179 {
180   return lhs.get () == nullptr;
181 }
182
183 template<typename T, typename Policy>
184 inline bool operator== (const T *lhs, const ref_ptr<T, Policy> &rhs)
185 {
186   return lhs == rhs.get ();
187 }
188
189 template<typename T, typename Policy>
190 inline bool operator== (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
191 {
192   return nullptr == rhs.get ();
193 }
194
195 template<typename T, typename Policy>
196 inline bool operator!= (const ref_ptr<T, Policy> &lhs,
197                         const ref_ptr<T, Policy> &rhs)
198 {
199   return lhs.get () != rhs.get ();
200 }
201
202 template<typename T, typename Policy>
203 inline bool operator!= (const ref_ptr<T, Policy> &lhs, const T *rhs)
204 {
205   return lhs.get () != rhs;
206 }
207
208 template<typename T, typename Policy>
209 inline bool operator!= (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
210 {
211   return lhs.get () != nullptr;
212 }
213
214 template<typename T, typename Policy>
215 inline bool operator!= (const T *lhs, const ref_ptr<T, Policy> &rhs)
216 {
217   return lhs != rhs.get ();
218 }
219
220 template<typename T, typename Policy>
221 inline bool operator!= (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
222 {
223   return nullptr != rhs.get ();
224 }
225
226 }
227
228 #endif /* COMMON_GDB_REF_PTR_H */
This page took 0.035747 seconds and 4 git commands to generate.