1 /* gnu::unique_ptr, a simple std::unique_ptr replacement for C++03.
2 
3    Copyright (C) 2007-2018 Free Software Foundation, Inc.
4 
5    This file is part of GCC.
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 /* gnu::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, gnu::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 gnu::unique_ptr partial
34    specialization that uses a custom (stateless) deleter:
35    gnu::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 gnu::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, gnu::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 GNU_UNIQUE_PTR_H
75 #define GNU_UNIQUE_PTR_H 1
76 
77 #if __cplusplus >= 201103
78 # include <memory>
79 #endif
80 
81 namespace gnu
82 {
83 
84 #if __cplusplus >= 201103
85 
86 /* In C++11 mode, all we need is import the standard
87    std::unique_ptr.  */
88 template<typename T> using unique_ptr = std::unique_ptr<T>;
89 
90 /* Pull in move as well.  */
91 using std::move;
92 
93 #else /* C++11 */
94 
95 /* Default destruction policy used by gnu::unique_ptr when no deleter
96    is specified.  Uses delete.  */
97 
98 template<typename T>
99 struct default_delete
100 {
101   void operator () (T *ptr) const { delete ptr; }
102 };
103 
104 /* Specialization for arrays.  Uses delete[].  */
105 
106 template<typename T>
107 struct default_delete<T[]>
108 {
109   void operator () (T *ptr) const { delete [] ptr; }
110 };
111 
112 namespace detail
113 {
114 /* Type used to support implicit construction from NULL:
115 
116      gnu::unique_ptr<foo> func (....)
117      {
118      return NULL;
119      }
120 
121    and assignment from NULL:
122 
123      gnu::unique_ptr<foo> ptr (....);
124      ...
125      ptr = NULL;
126 
127   It is intentionally not defined anywhere.  */
128 struct nullptr_t;
129 
130 /* Base class of our unique_ptr emulation.  Contains code common to
131    both unique_ptr<T, D> and unique_ptr<T[], D>.  */
132 
133 template<typename T, typename D>
134 class unique_ptr_base
135 {
136 public:
137   typedef T *pointer;
138   typedef T element_type;
139   typedef D deleter_type;
140 
141   /* Takes ownership of a pointer.  P is a pointer to an object of
142      element_type type.  Defaults to NULL.  */
143   explicit unique_ptr_base (element_type *p = NULL) throw () : m_ptr (p) {}
144 
145   /* The "move" constructor.  Really a copy constructor that actually
146      moves.  Even though std::unique_ptr is not copyable, our little
147      simpler emulation allows it, because:
148 
149        - There are no rvalue references in C++03.  Our move emulation
150        instead relies on copy/assignment moving, like std::auto_ptr.
151        - RVO/NRVO requires an accessible copy constructor
152   */
153   unique_ptr_base (const unique_ptr_base &other) throw ()
154     : m_ptr (const_cast<unique_ptr_base &> (other).release ()) {}
155 
156   /* Converting "move" constructor.  Really an lvalue ref converting
157      constructor that actually moves.  This allows constructs such as:
158 
159       unique_ptr<Derived> func_returning_unique_ptr (.....);
160       ...
161       unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
162   */
163   template<typename T1, typename D1>
164   unique_ptr_base (const unique_ptr_base<T1, D1> &other) throw ()
165     : m_ptr (const_cast<unique_ptr_base<T1, D1> &> (other).release ()) {}
166 
167   /* The "move" assignment operator.  Really an lvalue ref copy
168      assignment operator that actually moves.  See comments above.  */
169   unique_ptr_base &operator= (const unique_ptr_base &other) throw ()
170   {
171     reset (const_cast<unique_ptr_base &> (other).release ());
172     return *this;
173   }
174 
175   /* Converting "move" assignment.  Really an lvalue ref converting
176      copy assignment operator that moves.  See comments above.  */
177   template<typename T1, typename D1>
178   unique_ptr_base &operator= (const unique_ptr_base<T1, D1> &other) throw ()
179   {
180     reset (const_cast<unique_ptr_base<T1, D1> &> (other).release ());
181     return *this;
182   }
183 
184   /* std::unique_ptr does not allow assignment, except from nullptr.
185      nullptr doesn't exist in C++03, so we allow assignment from NULL
186      instead [ptr = NULL;].
187   */
188   unique_ptr_base &operator= (detail::nullptr_t *) throw ()
189   {
190     reset ();
191     return *this;
192   }
193 
194   ~unique_ptr_base () { call_deleter (); }
195 
196   /* "explicit operator bool ()" emulation using the safe bool
197      idiom.  */
198 private:
199   typedef void (unique_ptr_base::*explicit_operator_bool) () const;
200   void this_type_does_not_support_comparisons () const {}
201 
202 public:
203   operator explicit_operator_bool () const
204   {
205     return (m_ptr != NULL
206 	    ? &unique_ptr_base::this_type_does_not_support_comparisons
207 	    : 0);
208   }
209 
210   element_type *get () const throw () { return m_ptr; }
211 
212   element_type *release () throw ()
213   {
214     pointer tmp = m_ptr;
215     m_ptr = NULL;
216     return tmp;
217   }
218 
219   void reset (element_type *p = NULL) throw ()
220   {
221     if (p != m_ptr)
222       {
223 	call_deleter ();
224 	m_ptr = p;
225       }
226   }
227 
228 private:
229 
230   /* Call the deleter.  Note we assume the deleter is "stateless".  */
231   void call_deleter ()
232   {
233     D d;
234 
235     d (m_ptr);
236   }
237 
238   element_type *m_ptr;
239 };
240 
241 } /* namespace detail */
242 
243 /* Macro used to create a unique_ptr_base "partial specialization" --
244    a subclass that uses a specific deleter.  Basically this re-defines
245    the necessary constructors.  This is necessary because C++03
246    doesn't support inheriting constructors with "using".  While at it,
247    we inherit the assignment operator.  TYPE is the name of the type
248    being defined.  Assumes that 'base_type' is a typedef of the
249    baseclass TYPE is inheriting from.  */
250 #define DEFINE_GNU_UNIQUE_PTR(TYPE)						\
251 public:									\
252   explicit TYPE (T *p = NULL) throw ()					\
253     : base_type (p) {}							\
254 									\
255   TYPE (const TYPE &other) throw () : base_type (other) {}		\
256 									\
257   TYPE (detail::nullptr_t *) throw () : base_type (NULL) {}		\
258 									\
259   template<typename T1, typename D1>					\
260   TYPE (const detail::unique_ptr_base<T1, D1> &other) throw ()		\
261     : base_type (other) {}						\
262 									\
263   using base_type::operator=;
264 
265 /* Define single-object gnu::unique_ptr.  */
266 
267 template <typename T, typename D = default_delete<T> >
268 class unique_ptr : public detail::unique_ptr_base<T, D>
269 {
270   typedef detail::unique_ptr_base<T, D> base_type;
271 
272   DEFINE_GNU_UNIQUE_PTR (unique_ptr)
273 
274 public:
275   /* Dereferencing.  */
276   T &operator* () const throw () { return *this->get (); }
277   T *operator-> () const throw () { return this->get (); }
278 };
279 
280 /* Define gnu::unique_ptr specialization for T[].  */
281 
282 template <typename T, typename D>
283 class unique_ptr<T[], D> : public detail::unique_ptr_base<T, D>
284 {
285   typedef detail::unique_ptr_base<T, D> base_type;
286 
287   DEFINE_GNU_UNIQUE_PTR (unique_ptr)
288 
289 public:
290   /* Indexing operator.  */
291   T &operator[] (size_t i) const { return this->get ()[i]; }
292 };
293 
294 /* Comparison operators.  */
295 
296 template <typename T, typename D,
297 	  typename U, typename E>
298 inline bool
299 operator== (const detail::unique_ptr_base<T, D> &x,
300 	    const detail::unique_ptr_base<U, E> &y)
301 { return x.get() == y.get(); }
302 
303 template <typename T, typename D,
304 	  typename U, typename E>
305 inline bool
306 operator!= (const detail::unique_ptr_base<T, D> &x,
307 	    const detail::unique_ptr_base<U, E> &y)
308 { return x.get() != y.get(); }
309 
310 template<typename T, typename D,
311 	 typename U, typename E>
312 inline bool
313 operator< (const detail::unique_ptr_base<T, D> &x,
314 	   const detail::unique_ptr_base<U, E> &y)
315 { return x.get() < y.get (); }
316 
317 template<typename T, typename D,
318 	 typename U, typename E>
319 inline bool
320 operator<= (const detail::unique_ptr_base<T, D> &x,
321 	    const detail::unique_ptr_base<U, E> &y)
322 { return !(y < x); }
323 
324 template<typename T, typename D,
325 	 typename U, typename E>
326 inline bool
327 operator> (const detail::unique_ptr_base<T, D> &x,
328 	   const detail::unique_ptr_base<U, E> &y)
329 { return y < x; }
330 
331 template<typename T, typename D,
332 	 typename U, typename E>
333 inline bool
334 operator>= (const detail::unique_ptr_base<T, D> &x,
335 	    const detail::unique_ptr_base<U, E> &y)
336 { return !(x < y); }
337 
338 /* std::move "emulation".  This is as simple as it can be -- no
339    attempt is made to emulate rvalue references.  Instead relies on
340    the fact that gnu::unique_ptr has move semantics like
341    std::auto_ptr.  I.e., copy/assignment actually moves.  */
342 
343 template<typename T, typename D>
344 unique_ptr<T, D>
345 move (unique_ptr<T, D> v)
346 {
347   return v;
348 }
349 
350 #endif /* C++11 */
351 
352 /* Define gnu::unique_xmalloc_ptr, a gnu::unique_ptr that manages
353    xmalloc'ed memory.  */
354 
355 /* The deleter for gnu::unique_xmalloc_ptr.  Uses free.  */
356 template <typename T>
357 struct xmalloc_deleter
358 {
359   void operator() (T *ptr) const { free (ptr); }
360 };
361 
362 /* Same, for arrays.  */
363 template <typename T>
364 struct xmalloc_deleter<T[]>
365 {
366   void operator() (T *ptr) const { free (ptr); }
367 };
368 
369 #if __cplusplus >= 201103
370 
371 /* In C++11, we just import the standard unique_ptr to our namespace
372    with a custom deleter.  */
373 
374 template<typename T> using unique_xmalloc_ptr
375   = std::unique_ptr<T, xmalloc_deleter<T>>;
376 
377 #else /* C++11 */
378 
379 /* In C++03, we don't have template aliases, so we need to define a
380    subclass instead, and re-define the constructors, because C++03
381    doesn't support inheriting constructors either.  */
382 
383 template <typename T>
384 class unique_xmalloc_ptr : public unique_ptr<T, xmalloc_deleter<T> >
385 {
386   typedef unique_ptr<T, xmalloc_deleter<T> > base_type;
387 
388   DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
389 };
390 
391 /* Define gnu::unique_xmalloc_ptr specialization for T[].  */
392 
393 template <typename T>
394 class unique_xmalloc_ptr<T[]> : public unique_ptr<T[], xmalloc_deleter<T[]> >
395 {
396   typedef unique_ptr<T[], xmalloc_deleter<T[]> > base_type;
397 
398   DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
399 };
400 
401 #endif /* C++11 */
402 
403 } /* namespace gnu */
404 
405 #endif /* GNU_UNIQUE_PTR_H */
406