xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/backward/auto_ptr.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // auto_ptr implementation -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file backward/auto_ptr.h
26*38fd1498Szrj  *  This is an internal header file, included by other library headers.
27*38fd1498Szrj  *  Do not attempt to use it directly. @headername{memory}
28*38fd1498Szrj  */
29*38fd1498Szrj 
30*38fd1498Szrj #ifndef _BACKWARD_AUTO_PTR_H
31*38fd1498Szrj #define _BACKWARD_AUTO_PTR_H 1
32*38fd1498Szrj 
33*38fd1498Szrj #include <bits/c++config.h>
34*38fd1498Szrj #include <debug/debug.h>
35*38fd1498Szrj 
_GLIBCXX_VISIBILITY(default)36*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
37*38fd1498Szrj {
38*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
39*38fd1498Szrj 
40*38fd1498Szrj   /**
41*38fd1498Szrj    *  A wrapper class to provide auto_ptr with reference semantics.
42*38fd1498Szrj    *  For example, an auto_ptr can be assigned (or constructed from)
43*38fd1498Szrj    *  the result of a function which returns an auto_ptr by value.
44*38fd1498Szrj    *
45*38fd1498Szrj    *  All the auto_ptr_ref stuff should happen behind the scenes.
46*38fd1498Szrj    */
47*38fd1498Szrj   template<typename _Tp1>
48*38fd1498Szrj     struct auto_ptr_ref
49*38fd1498Szrj     {
50*38fd1498Szrj       _Tp1* _M_ptr;
51*38fd1498Szrj 
52*38fd1498Szrj       explicit
53*38fd1498Szrj       auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }
54*38fd1498Szrj     } _GLIBCXX_DEPRECATED;
55*38fd1498Szrj 
56*38fd1498Szrj #pragma GCC diagnostic push
57*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58*38fd1498Szrj 
59*38fd1498Szrj   /**
60*38fd1498Szrj    *  @brief  A simple smart pointer providing strict ownership semantics.
61*38fd1498Szrj    *
62*38fd1498Szrj    *  The Standard says:
63*38fd1498Szrj    *  <pre>
64*38fd1498Szrj    *  An @c auto_ptr owns the object it holds a pointer to.  Copying
65*38fd1498Szrj    *  an @c auto_ptr copies the pointer and transfers ownership to the
66*38fd1498Szrj    *  destination.  If more than one @c auto_ptr owns the same object
67*38fd1498Szrj    *  at the same time the behavior of the program is undefined.
68*38fd1498Szrj    *
69*38fd1498Szrj    *  The uses of @c auto_ptr include providing temporary
70*38fd1498Szrj    *  exception-safety for dynamically allocated memory, passing
71*38fd1498Szrj    *  ownership of dynamically allocated memory to a function, and
72*38fd1498Szrj    *  returning dynamically allocated memory from a function.  @c
73*38fd1498Szrj    *  auto_ptr does not meet the CopyConstructible and Assignable
74*38fd1498Szrj    *  requirements for Standard Library <a
75*38fd1498Szrj    *  href="tables.html#65">container</a> elements and thus
76*38fd1498Szrj    *  instantiating a Standard Library container with an @c auto_ptr
77*38fd1498Szrj    *  results in undefined behavior.
78*38fd1498Szrj    *  </pre>
79*38fd1498Szrj    *  Quoted from [20.4.5]/3.
80*38fd1498Szrj    *
81*38fd1498Szrj    *  Good examples of what can and cannot be done with auto_ptr can
82*38fd1498Szrj    *  be found in the libstdc++ testsuite.
83*38fd1498Szrj    *
84*38fd1498Szrj    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
85*38fd1498Szrj    *  127.  auto_ptr<> conversion issues
86*38fd1498Szrj    *  These resolutions have all been incorporated.
87*38fd1498Szrj    */
88*38fd1498Szrj   template<typename _Tp>
89*38fd1498Szrj     class auto_ptr
90*38fd1498Szrj     {
91*38fd1498Szrj     private:
92*38fd1498Szrj       _Tp* _M_ptr;
93*38fd1498Szrj 
94*38fd1498Szrj     public:
95*38fd1498Szrj       /// The pointed-to type.
96*38fd1498Szrj       typedef _Tp element_type;
97*38fd1498Szrj 
98*38fd1498Szrj       /**
99*38fd1498Szrj        *  @brief  An %auto_ptr is usually constructed from a raw pointer.
100*38fd1498Szrj        *  @param  __p  A pointer (defaults to NULL).
101*38fd1498Szrj        *
102*38fd1498Szrj        *  This object now @e owns the object pointed to by @a __p.
103*38fd1498Szrj        */
104*38fd1498Szrj       explicit
105*38fd1498Szrj       auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
106*38fd1498Szrj 
107*38fd1498Szrj       /**
108*38fd1498Szrj        *  @brief  An %auto_ptr can be constructed from another %auto_ptr.
109*38fd1498Szrj        *  @param  __a  Another %auto_ptr of the same type.
110*38fd1498Szrj        *
111*38fd1498Szrj        *  This object now @e owns the object previously owned by @a __a,
112*38fd1498Szrj        *  which has given up ownership.
113*38fd1498Szrj        */
114*38fd1498Szrj       auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
115*38fd1498Szrj 
116*38fd1498Szrj       /**
117*38fd1498Szrj        *  @brief  An %auto_ptr can be constructed from another %auto_ptr.
118*38fd1498Szrj        *  @param  __a  Another %auto_ptr of a different but related type.
119*38fd1498Szrj        *
120*38fd1498Szrj        *  A pointer-to-Tp1 must be convertible to a
121*38fd1498Szrj        *  pointer-to-Tp/element_type.
122*38fd1498Szrj        *
123*38fd1498Szrj        *  This object now @e owns the object previously owned by @a __a,
124*38fd1498Szrj        *  which has given up ownership.
125*38fd1498Szrj        */
126*38fd1498Szrj       template<typename _Tp1>
127*38fd1498Szrj         auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
128*38fd1498Szrj 
129*38fd1498Szrj       /**
130*38fd1498Szrj        *  @brief  %auto_ptr assignment operator.
131*38fd1498Szrj        *  @param  __a  Another %auto_ptr of the same type.
132*38fd1498Szrj        *
133*38fd1498Szrj        *  This object now @e owns the object previously owned by @a __a,
134*38fd1498Szrj        *  which has given up ownership.  The object that this one @e
135*38fd1498Szrj        *  used to own and track has been deleted.
136*38fd1498Szrj        */
137*38fd1498Szrj       auto_ptr&
138*38fd1498Szrj       operator=(auto_ptr& __a) throw()
139*38fd1498Szrj       {
140*38fd1498Szrj 	reset(__a.release());
141*38fd1498Szrj 	return *this;
142*38fd1498Szrj       }
143*38fd1498Szrj 
144*38fd1498Szrj       /**
145*38fd1498Szrj        *  @brief  %auto_ptr assignment operator.
146*38fd1498Szrj        *  @param  __a  Another %auto_ptr of a different but related type.
147*38fd1498Szrj        *
148*38fd1498Szrj        *  A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type.
149*38fd1498Szrj        *
150*38fd1498Szrj        *  This object now @e owns the object previously owned by @a __a,
151*38fd1498Szrj        *  which has given up ownership.  The object that this one @e
152*38fd1498Szrj        *  used to own and track has been deleted.
153*38fd1498Szrj        */
154*38fd1498Szrj       template<typename _Tp1>
155*38fd1498Szrj         auto_ptr&
156*38fd1498Szrj         operator=(auto_ptr<_Tp1>& __a) throw()
157*38fd1498Szrj         {
158*38fd1498Szrj 	  reset(__a.release());
159*38fd1498Szrj 	  return *this;
160*38fd1498Szrj 	}
161*38fd1498Szrj 
162*38fd1498Szrj       /**
163*38fd1498Szrj        *  When the %auto_ptr goes out of scope, the object it owns is
164*38fd1498Szrj        *  deleted.  If it no longer owns anything (i.e., @c get() is
165*38fd1498Szrj        *  @c NULL), then this has no effect.
166*38fd1498Szrj        *
167*38fd1498Szrj        *  The C++ standard says there is supposed to be an empty throw
168*38fd1498Szrj        *  specification here, but omitting it is standard conforming.  Its
169*38fd1498Szrj        *  presence can be detected only if _Tp::~_Tp() throws, but this is
170*38fd1498Szrj        *  prohibited.  [17.4.3.6]/2
171*38fd1498Szrj        */
172*38fd1498Szrj       ~auto_ptr() { delete _M_ptr; }
173*38fd1498Szrj 
174*38fd1498Szrj       /**
175*38fd1498Szrj        *  @brief  Smart pointer dereferencing.
176*38fd1498Szrj        *
177*38fd1498Szrj        *  If this %auto_ptr no longer owns anything, then this
178*38fd1498Szrj        *  operation will crash.  (For a smart pointer, <em>no longer owns
179*38fd1498Szrj        *  anything</em> is the same as being a null pointer, and you know
180*38fd1498Szrj        *  what happens when you dereference one of those...)
181*38fd1498Szrj        */
182*38fd1498Szrj       element_type&
183*38fd1498Szrj       operator*() const throw()
184*38fd1498Szrj       {
185*38fd1498Szrj 	__glibcxx_assert(_M_ptr != 0);
186*38fd1498Szrj 	return *_M_ptr;
187*38fd1498Szrj       }
188*38fd1498Szrj 
189*38fd1498Szrj       /**
190*38fd1498Szrj        *  @brief  Smart pointer dereferencing.
191*38fd1498Szrj        *
192*38fd1498Szrj        *  This returns the pointer itself, which the language then will
193*38fd1498Szrj        *  automatically cause to be dereferenced.
194*38fd1498Szrj        */
195*38fd1498Szrj       element_type*
196*38fd1498Szrj       operator->() const throw()
197*38fd1498Szrj       {
198*38fd1498Szrj 	__glibcxx_assert(_M_ptr != 0);
199*38fd1498Szrj 	return _M_ptr;
200*38fd1498Szrj       }
201*38fd1498Szrj 
202*38fd1498Szrj       /**
203*38fd1498Szrj        *  @brief  Bypassing the smart pointer.
204*38fd1498Szrj        *  @return  The raw pointer being managed.
205*38fd1498Szrj        *
206*38fd1498Szrj        *  You can get a copy of the pointer that this object owns, for
207*38fd1498Szrj        *  situations such as passing to a function which only accepts
208*38fd1498Szrj        *  a raw pointer.
209*38fd1498Szrj        *
210*38fd1498Szrj        *  @note  This %auto_ptr still owns the memory.
211*38fd1498Szrj        */
212*38fd1498Szrj       element_type*
213*38fd1498Szrj       get() const throw() { return _M_ptr; }
214*38fd1498Szrj 
215*38fd1498Szrj       /**
216*38fd1498Szrj        *  @brief  Bypassing the smart pointer.
217*38fd1498Szrj        *  @return  The raw pointer being managed.
218*38fd1498Szrj        *
219*38fd1498Szrj        *  You can get a copy of the pointer that this object owns, for
220*38fd1498Szrj        *  situations such as passing to a function which only accepts
221*38fd1498Szrj        *  a raw pointer.
222*38fd1498Szrj        *
223*38fd1498Szrj        *  @note  This %auto_ptr no longer owns the memory.  When this object
224*38fd1498Szrj        *  goes out of scope, nothing will happen.
225*38fd1498Szrj        */
226*38fd1498Szrj       element_type*
227*38fd1498Szrj       release() throw()
228*38fd1498Szrj       {
229*38fd1498Szrj 	element_type* __tmp = _M_ptr;
230*38fd1498Szrj 	_M_ptr = 0;
231*38fd1498Szrj 	return __tmp;
232*38fd1498Szrj       }
233*38fd1498Szrj 
234*38fd1498Szrj       /**
235*38fd1498Szrj        *  @brief  Forcibly deletes the managed object.
236*38fd1498Szrj        *  @param  __p  A pointer (defaults to NULL).
237*38fd1498Szrj        *
238*38fd1498Szrj        *  This object now @e owns the object pointed to by @a __p.  The
239*38fd1498Szrj        *  previous object has been deleted.
240*38fd1498Szrj        */
241*38fd1498Szrj       void
242*38fd1498Szrj       reset(element_type* __p = 0) throw()
243*38fd1498Szrj       {
244*38fd1498Szrj 	if (__p != _M_ptr)
245*38fd1498Szrj 	  {
246*38fd1498Szrj 	    delete _M_ptr;
247*38fd1498Szrj 	    _M_ptr = __p;
248*38fd1498Szrj 	  }
249*38fd1498Szrj       }
250*38fd1498Szrj 
251*38fd1498Szrj       /**
252*38fd1498Szrj        *  @brief  Automatic conversions
253*38fd1498Szrj        *
254*38fd1498Szrj        *  These operations are supposed to convert an %auto_ptr into and from
255*38fd1498Szrj        *  an auto_ptr_ref automatically as needed.  This would allow
256*38fd1498Szrj        *  constructs such as
257*38fd1498Szrj        *  @code
258*38fd1498Szrj        *    auto_ptr<Derived>  func_returning_auto_ptr(.....);
259*38fd1498Szrj        *    ...
260*38fd1498Szrj        *    auto_ptr<Base> ptr = func_returning_auto_ptr(.....);
261*38fd1498Szrj        *  @endcode
262*38fd1498Szrj        *
263*38fd1498Szrj        *  But it doesn't work, and won't be fixed. For further details see
264*38fd1498Szrj        *  http://cplusplus.github.io/LWG/lwg-closed.html#463
265*38fd1498Szrj        */
266*38fd1498Szrj       auto_ptr(auto_ptr_ref<element_type> __ref) throw()
267*38fd1498Szrj       : _M_ptr(__ref._M_ptr) { }
268*38fd1498Szrj 
269*38fd1498Szrj       auto_ptr&
270*38fd1498Szrj       operator=(auto_ptr_ref<element_type> __ref) throw()
271*38fd1498Szrj       {
272*38fd1498Szrj 	if (__ref._M_ptr != this->get())
273*38fd1498Szrj 	  {
274*38fd1498Szrj 	    delete _M_ptr;
275*38fd1498Szrj 	    _M_ptr = __ref._M_ptr;
276*38fd1498Szrj 	  }
277*38fd1498Szrj 	return *this;
278*38fd1498Szrj       }
279*38fd1498Szrj 
280*38fd1498Szrj       template<typename _Tp1>
281*38fd1498Szrj         operator auto_ptr_ref<_Tp1>() throw()
282*38fd1498Szrj         { return auto_ptr_ref<_Tp1>(this->release()); }
283*38fd1498Szrj 
284*38fd1498Szrj       template<typename _Tp1>
285*38fd1498Szrj         operator auto_ptr<_Tp1>() throw()
286*38fd1498Szrj         { return auto_ptr<_Tp1>(this->release()); }
287*38fd1498Szrj     } _GLIBCXX_DEPRECATED;
288*38fd1498Szrj 
289*38fd1498Szrj   // _GLIBCXX_RESOLVE_LIB_DEFECTS
290*38fd1498Szrj   // 541. shared_ptr template assignment and void
291*38fd1498Szrj   template<>
292*38fd1498Szrj     class auto_ptr<void>
293*38fd1498Szrj     {
294*38fd1498Szrj     public:
295*38fd1498Szrj       typedef void element_type;
296*38fd1498Szrj     } _GLIBCXX_DEPRECATED;
297*38fd1498Szrj 
298*38fd1498Szrj #if __cplusplus >= 201103L
299*38fd1498Szrj   template<_Lock_policy _Lp>
300*38fd1498Szrj   template<typename _Tp>
301*38fd1498Szrj     inline
302*38fd1498Szrj     __shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r)
303*38fd1498Szrj     : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
304*38fd1498Szrj     { __r.release(); }
305*38fd1498Szrj 
306*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
307*38fd1498Szrj   template<typename _Tp1, typename>
308*38fd1498Szrj     inline
309*38fd1498Szrj     __shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r)
310*38fd1498Szrj     : _M_ptr(__r.get()), _M_refcount()
311*38fd1498Szrj     {
312*38fd1498Szrj       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
313*38fd1498Szrj       static_assert( sizeof(_Tp1) > 0, "incomplete type" );
314*38fd1498Szrj       _Tp1* __tmp = __r.get();
315*38fd1498Szrj       _M_refcount = __shared_count<_Lp>(std::move(__r));
316*38fd1498Szrj       _M_enable_shared_from_this_with(__tmp);
317*38fd1498Szrj     }
318*38fd1498Szrj 
319*38fd1498Szrj   template<typename _Tp>
320*38fd1498Szrj   template<typename _Tp1, typename>
321*38fd1498Szrj     inline
322*38fd1498Szrj     shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r)
323*38fd1498Szrj     : __shared_ptr<_Tp>(std::move(__r)) { }
324*38fd1498Szrj 
325*38fd1498Szrj   template<typename _Tp, typename _Dp>
326*38fd1498Szrj   template<typename _Up, typename>
327*38fd1498Szrj     inline
328*38fd1498Szrj     unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept
329*38fd1498Szrj     : _M_t(__u.release(), deleter_type()) { }
330*38fd1498Szrj #endif
331*38fd1498Szrj 
332*38fd1498Szrj #pragma GCC diagnostic pop
333*38fd1498Szrj 
334*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
335*38fd1498Szrj } // namespace
336*38fd1498Szrj 
337*38fd1498Szrj #endif /* _BACKWARD_AUTO_PTR_H */
338