Use ui_file_as_string in gdbarch.sh/gdbarch.c
[deliverable/binutils-gdb.git] / gdb / common / gdb_unique_ptr.h
CommitLineData
da804164
PA
1/* gdb::unique_ptr, a simple std::unique_ptr replacement for C++03.
2
3 Copyright (C) 2007-2016 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/* gdb::unique_ptr defines a C++ owning smart pointer that exposes a
21 subset of the std::unique_ptr API.
22
23 In fact, when compiled with a C++11 compiler, gdb::unique_ptr
24 actually _is_ std::unique_ptr. When compiled with a C++03 compiler
25 OTOH, it's an hand coded std::unique_ptr emulation that assumes
26 code is correct and doesn't try to be too smart.
27
28 This supports custom deleters, but not _stateful_ deleters, so you
29 can't use those in C++11 mode either. Only the managed pointer is
30 stored in the smart pointer. That could be changed; it simply
31 wasn't found necessary.
32
33 At the end of the file you'll find a gdb::unique_ptr partial
34 specialization that uses a custom (stateless) deleter:
35 gdb::unique_xmalloc_ptr. That is used to manage pointers to
36 objects allocated with xmalloc.
37
38 The C++03 version was originally based on GCC 7.0's std::auto_ptr
39 and then heavily customized to behave more like C++11's
40 std::unique_ptr, but at this point, it no longer shares much at all
41 with the original file. But, that's the history and the reason for
42 the copyright's starting year.
43
44 The C++03 version lets you shoot yourself in the foot, since
45 similarly to std::auto_ptr, the copy constructor and assignment
46 operators actually move. Also, in the name of simplicity, no
47 effort is spent on using SFINAE to prevent invalid conversions,
48 etc. This is not really a problem, because the goal here is to
49 allow code that would be correct using std::unique_ptr to be
50 equally correct in C++03 mode, and, just as efficient. If client
51 code compiles correctly with a C++11 (or newer) compiler, we know
52 we're not doing anything invalid by mistake.
53
54 Usage notes:
55
56 - Putting gdb::unique_ptr in standard containers is not supported,
57 since C++03 containers are not move-aware (and our emulation
58 relies on copy actually moving).
59
60 - Since there's no nullptr in C++03, gdb::unique_ptr allows
61 implicit initialization and assignment from NULL instead.
62
63 - To check whether there's an associated managed object, all these
64 work as expected:
65
66 if (ptr)
67 if (!ptr)
68 if (ptr != NULL)
69 if (ptr == NULL)
70 if (NULL != ptr)
71 if (NULL == ptr)
72*/
73
74#ifndef GDB_UNIQUE_PTR_H
75#define GDB_UNIQUE_PTR_H 1
76
77#include <memory>
78
79namespace gdb
80{
81
82#if __cplusplus >= 201103
83
84/* In C++11 mode, all we need is import the standard
85 std::unique_ptr. */
86template<typename T> using unique_ptr = std::unique_ptr<T>;
87
88/* Pull in move as well. */
89using std::move;
90
91#else /* C++11 */
92
93/* Default destruction policy used by gdb::unique_ptr when no deleter
94 is specified. Uses delete. */
95
96template<typename T>
97struct default_delete
98{
99 void operator () (T *ptr) const { delete ptr; }
100};
101
102/* Specialization for arrays. Uses delete[]. */
103
104template<typename T>
105struct default_delete<T[]>
106{
107 void operator () (T *ptr) const { delete [] ptr; }
108};
109
110namespace detail
111{
112/* Type used to support implicit construction from NULL:
113
114 gdb::unique_ptr<foo> func (....)
115 {
116 return NULL;
117 }
118
119 and assignment from NULL:
120
121 gdb::unique_ptr<foo> ptr (....);
122 ...
123 ptr = NULL;
124
125 It is intentionally not defined anywhere. */
126struct nullptr_t;
127
128/* Base class of our unique_ptr emulation. Contains code common to
129 both unique_ptr<T, D> and unique_ptr<T[], D>. */
130
131template<typename T, typename D>
132class unique_ptr_base
133{
134public:
135 typedef T *pointer;
136 typedef T element_type;
137 typedef D deleter_type;
138
139 /* Takes ownership of a pointer. P is a pointer to an object of
140 element_type type. Defaults to NULL. */
141 explicit unique_ptr_base (element_type *p = NULL) throw () : m_ptr (p) {}
142
143 /* The "move" constructor. Really a copy constructor that actually
144 moves. Even though std::unique_ptr is not copyable, our little
145 simpler emulation allows it, because:
146
147 - There are no rvalue references in C++03. Our move emulation
148 instead relies on copy/assignment moving, like std::auto_ptr.
149 - RVO/NRVO requires an accessible copy constructor
150 */
151 unique_ptr_base (const unique_ptr_base &other) throw ()
152 : m_ptr (const_cast<unique_ptr_base &> (other).release ()) {}
153
154 /* Converting "move" constructor. Really an lvalue ref converting
155 constructor that actually moves. This allows constructs such as:
156
157 unique_ptr<Derived> func_returning_unique_ptr (.....);
158 ...
159 unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
160 */
161 template<typename T1, typename D1>
162 unique_ptr_base (const unique_ptr_base<T1, D1> &other) throw ()
163 : m_ptr (const_cast<unique_ptr_base<T1, D1> &> (other).release ()) {}
164
165 /* The "move" assignment operator. Really an lvalue ref copy
166 assignment operator that actually moves. See comments above. */
167 unique_ptr_base &operator= (const unique_ptr_base &other) throw ()
168 {
169 reset (const_cast<unique_ptr_base &> (other).release ());
170 return *this;
171 }
172
173 /* Converting "move" assignment. Really an lvalue ref converting
174 copy assignment operator that moves. See comments above. */
175 template<typename T1, typename D1>
176 unique_ptr_base &operator= (const unique_ptr_base<T1, D1> &other) throw ()
177 {
178 reset (const_cast<unique_ptr_base<T1, D1> &> (other).release ());
179 return *this;
180 }
181
182 /* std::unique_ptr does not allow assignment, except from nullptr.
183 nullptr doesn't exist in C++03, so we allow assignment from NULL
184 instead [ptr = NULL;].
185 */
186 unique_ptr_base &operator= (detail::nullptr_t *) throw ()
187 {
188 reset ();
189 return *this;
190 }
191
192 ~unique_ptr_base () { call_deleter (); }
193
194 /* "explicit operator bool ()" emulation using the safe bool
195 idiom. */
196private:
197 typedef void (unique_ptr_base::*explicit_operator_bool) () const;
198 void this_type_does_not_support_comparisons () const {}
199
200public:
201 operator explicit_operator_bool () const
202 {
203 return (m_ptr != NULL
204 ? &unique_ptr_base::this_type_does_not_support_comparisons
205 : 0);
206 }
207
208 element_type *get () const throw () { return m_ptr; }
209
210 element_type *release () throw ()
211 {
212 pointer tmp = m_ptr;
213 m_ptr = NULL;
214 return tmp;
215 }
216
217 void reset (element_type *p = NULL) throw ()
218 {
219 if (p != m_ptr)
220 {
221 call_deleter ();
222 m_ptr = p;
223 }
224 }
225
226private:
227
228 /* Call the deleter. Note we assume the deleter is "stateless". */
229 void call_deleter ()
230 {
231 D d;
232
233 d (m_ptr);
234 }
235
236 element_type *m_ptr;
237};
238
239} /* namespace detail */
240
241/* Macro used to create a unique_ptr_base "partial specialization" --
242 a subclass that uses a specific deleter. Basically this re-defines
243 the necessary constructors. This is necessary because C++03
244 doesn't support inheriting constructors with "using". While at it,
245 we inherit the assignment operator. TYPE is the name of the type
246 being defined. Assumes that 'base_type' is a typedef of the
247 baseclass TYPE is inheriting from. */
248#define DEFINE_GDB_UNIQUE_PTR(TYPE) \
249public: \
250 explicit TYPE (T *p = NULL) throw () \
251 : base_type (p) {} \
252 \
253 TYPE (const TYPE &other) throw () : base_type (other) {} \
254 \
255 TYPE (detail::nullptr_t *) throw () : base_type (NULL) {} \
256 \
257 template<typename T1, typename D1> \
258 TYPE (const detail::unique_ptr_base<T1, D1> &other) throw () \
259 : base_type (other) {} \
260 \
261 using base_type::operator=;
262
263/* Define single-object gdb::unique_ptr. */
264
265template <typename T, typename D = default_delete<T> >
266class unique_ptr : public detail::unique_ptr_base<T, D>
267{
268 typedef detail::unique_ptr_base<T, D> base_type;
269
270 DEFINE_GDB_UNIQUE_PTR (unique_ptr)
271
272public:
273 /* Dereferencing. */
274 T &operator* () const throw () { return *this->get (); }
275 T *operator-> () const throw () { return this->get (); }
276};
277
278/* Define gdb::unique_ptr specialization for T[]. */
279
280template <typename T, typename D>
281class unique_ptr<T[], D> : public detail::unique_ptr_base<T, D>
282{
283 typedef detail::unique_ptr_base<T, D> base_type;
284
285 DEFINE_GDB_UNIQUE_PTR (unique_ptr)
286
287public:
288 /* Indexing operator. */
289 T &operator[] (size_t i) const { return this->get ()[i]; }
290};
291
292/* Comparison operators. */
293
294template <typename T, typename D,
295 typename U, typename E>
296inline bool
297operator== (const detail::unique_ptr_base<T, D> &x,
298 const detail::unique_ptr_base<U, E> &y)
299{ return x.get() == y.get(); }
300
301template <typename T, typename D,
302 typename U, typename E>
303inline bool
304operator!= (const detail::unique_ptr_base<T, D> &x,
305 const detail::unique_ptr_base<U, E> &y)
306{ return x.get() != y.get(); }
307
308template<typename T, typename D,
309 typename U, typename E>
310inline bool
311operator< (const detail::unique_ptr_base<T, D> &x,
312 const detail::unique_ptr_base<U, E> &y)
313{ return x.get() < y.get (); }
314
315template<typename T, typename D,
316 typename U, typename E>
317inline bool
318operator<= (const detail::unique_ptr_base<T, D> &x,
319 const detail::unique_ptr_base<U, E> &y)
320{ return !(y < x); }
321
322template<typename T, typename D,
323 typename U, typename E>
324inline bool
325operator> (const detail::unique_ptr_base<T, D> &x,
326 const detail::unique_ptr_base<U, E> &y)
327{ return y < x; }
328
329template<typename T, typename D,
330 typename U, typename E>
331inline bool
332operator>= (const detail::unique_ptr_base<T, D> &x,
333 const detail::unique_ptr_base<U, E> &y)
334{ return !(x < y); }
335
336/* std::move "emulation". This is as simple as it can be -- no
337 attempt is made to emulate rvalue references. Instead relies on
338 the fact that gdb::unique_ptr has move semantics like
339 std::auto_ptr. I.e., copy/assignment actually moves. */
340
341template<typename T, typename D>
342unique_ptr<T, D>
343move (unique_ptr<T, D> v)
344{
345 return v;
346}
347
348#endif /* C++11 */
349
350/* Define gdb::unique_xmalloc_ptr, a gdb::unique_ptr that manages
351 xmalloc'ed memory. */
352
353/* The deleter for gdb::unique_xmalloc_ptr. Uses xfree. */
354template <typename T>
355struct xfree_deleter
356{
357 void operator() (T *ptr) const { xfree (ptr); }
358};
359
360#if __cplusplus >= 201103
361
362/* In C++11, we just import the standard unique_ptr to our namespace
363 with a custom deleter. */
364
365template<typename T> using unique_xmalloc_ptr
366 = std::unique_ptr<T, xfree_deleter<T>>;
367
368#else /* C++11 */
369
370/* In C++03, we don't have template aliases, so we need to define a
371 subclass instead, and re-define the constructors, because C++03
372 doesn't support inheriting constructors either. */
373
374template <typename T>
375class unique_xmalloc_ptr : public unique_ptr<T, xfree_deleter<T> >
376{
377 typedef unique_ptr<T, xfree_deleter<T> > base_type;
378
379 DEFINE_GDB_UNIQUE_PTR (unique_xmalloc_ptr)
380};
381
382#endif /* C++11 */
383
384} /* namespace gdb */
385
386#endif /* GDB_UNIQUE_PTR_H */
This page took 0.040788 seconds and 4 git commands to generate.