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