100db7afdSDavid E. O'Brien // <memory> -*- C++ -*-
200db7afdSDavid E. O'Brien 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
400db7afdSDavid E. O'Brien //
500db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
600db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
700db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
800db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
900db7afdSDavid E. O'Brien // any later version.
1000db7afdSDavid E. O'Brien 
1100db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1200db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1300db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1400db7afdSDavid E. O'Brien // GNU General Public License for more details.
1500db7afdSDavid E. O'Brien 
1600db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1700db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1900db7afdSDavid E. O'Brien // USA.
2000db7afdSDavid E. O'Brien 
2100db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2200db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2300db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2400db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2500db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2600db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2700db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2800db7afdSDavid E. O'Brien // the GNU General Public License.
2900db7afdSDavid E. O'Brien 
3000db7afdSDavid E. O'Brien /*
3100db7afdSDavid E. O'Brien  * Copyright (c) 1997-1999
3200db7afdSDavid E. O'Brien  * Silicon Graphics Computer Systems, Inc.
3300db7afdSDavid E. O'Brien  *
3400db7afdSDavid E. O'Brien  * Permission to use, copy, modify, distribute and sell this software
3500db7afdSDavid E. O'Brien  * and its documentation for any purpose is hereby granted without fee,
3600db7afdSDavid E. O'Brien  * provided that the above copyright notice appear in all copies and
3700db7afdSDavid E. O'Brien  * that both that copyright notice and this permission notice appear
3800db7afdSDavid E. O'Brien  * in supporting documentation.  Silicon Graphics makes no
3900db7afdSDavid E. O'Brien  * representations about the suitability of this software for any
4000db7afdSDavid E. O'Brien  * purpose.  It is provided "as is" without express or implied warranty.
4100db7afdSDavid E. O'Brien  *
4200db7afdSDavid E. O'Brien  */
4300db7afdSDavid E. O'Brien 
44*f8a1b7d9SAlexander Kabaev /** @file include/memory
45*f8a1b7d9SAlexander Kabaev  *  This is a Standard C++ Library header.
4600db7afdSDavid E. O'Brien  */
4700db7afdSDavid E. O'Brien 
48ffeaf689SAlexander Kabaev #ifndef _GLIBCXX_MEMORY
49ffeaf689SAlexander Kabaev #define _GLIBCXX_MEMORY 1
5000db7afdSDavid E. O'Brien 
5100db7afdSDavid E. O'Brien #pragma GCC system_header
5200db7afdSDavid E. O'Brien 
5300db7afdSDavid E. O'Brien #include <bits/stl_algobase.h>
54ffeaf689SAlexander Kabaev #include <bits/allocator.h>
5500db7afdSDavid E. O'Brien #include <bits/stl_construct.h>
5600db7afdSDavid E. O'Brien #include <bits/stl_iterator_base_types.h> //for iterator_traits
5700db7afdSDavid E. O'Brien #include <bits/stl_uninitialized.h>
5800db7afdSDavid E. O'Brien #include <bits/stl_raw_storage_iter.h>
59ffeaf689SAlexander Kabaev #include <debug/debug.h>
60f260e61bSAlexander Kabaev #include <limits>
6100db7afdSDavid E. O'Brien 
_GLIBCXX_BEGIN_NAMESPACE(std)62*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
63*f8a1b7d9SAlexander Kabaev 
6400db7afdSDavid E. O'Brien   /**
6500db7afdSDavid E. O'Brien    *  @if maint
6600db7afdSDavid E. O'Brien    *  This is a helper function.  The unused second parameter exists to
6700db7afdSDavid E. O'Brien    *  permit the real get_temporary_buffer to use template parameter deduction.
68ca6500fcSAlexander Kabaev    *
69ca6500fcSAlexander Kabaev    *  XXX This should perhaps use the pool.
7000db7afdSDavid E. O'Brien    *  @endif
7100db7afdSDavid E. O'Brien    */
72ca6500fcSAlexander Kabaev   template<typename _Tp>
7300db7afdSDavid E. O'Brien     pair<_Tp*, ptrdiff_t>
7400db7afdSDavid E. O'Brien     __get_temporary_buffer(ptrdiff_t __len, _Tp*)
7500db7afdSDavid E. O'Brien     {
76f260e61bSAlexander Kabaev       const ptrdiff_t __max = numeric_limits<ptrdiff_t>::max() / sizeof(_Tp);
77f260e61bSAlexander Kabaev       if (__len > __max)
78f260e61bSAlexander Kabaev 	__len = __max;
7900db7afdSDavid E. O'Brien 
801b86b14eSAlexander Kabaev       while (__len > 0)
811b86b14eSAlexander Kabaev 	{
82ffeaf689SAlexander Kabaev 	  _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
83ffeaf689SAlexander Kabaev 							nothrow));
8400db7afdSDavid E. O'Brien 	  if (__tmp != 0)
8500db7afdSDavid E. O'Brien 	    return pair<_Tp*, ptrdiff_t>(__tmp, __len);
8600db7afdSDavid E. O'Brien 	  __len /= 2;
8700db7afdSDavid E. O'Brien 	}
88ffeaf689SAlexander Kabaev       return pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
8900db7afdSDavid E. O'Brien     }
9000db7afdSDavid E. O'Brien 
9100db7afdSDavid E. O'Brien   /**
92ffeaf689SAlexander Kabaev    *  @brief Allocates a temporary buffer.
9300db7afdSDavid E. O'Brien    *  @param  len  The number of objects of type Tp.
9400db7afdSDavid E. O'Brien    *  @return See full description.
9500db7afdSDavid E. O'Brien    *
9600db7afdSDavid E. O'Brien    *  Reinventing the wheel, but this time with prettier spokes!
9700db7afdSDavid E. O'Brien    *
98ffeaf689SAlexander Kabaev    *  This function tries to obtain storage for @c len adjacent Tp
99ffeaf689SAlexander Kabaev    *  objects.  The objects themselves are not constructed, of course.
100ffeaf689SAlexander Kabaev    *  A pair<> is returned containing "the buffer s address and
101ffeaf689SAlexander Kabaev    *  capacity (in the units of sizeof(Tp)), or a pair of 0 values if
102ffeaf689SAlexander Kabaev    *  no storage can be obtained."  Note that the capacity obtained
103ffeaf689SAlexander Kabaev    *  may be less than that requested if the memory is unavailable;
104ffeaf689SAlexander Kabaev    *  you should compare len with the .second return value.
105ffeaf689SAlexander Kabaev    *
106ffeaf689SAlexander Kabaev    * Provides the nothrow exception guarantee.
10700db7afdSDavid E. O'Brien    */
108ca6500fcSAlexander Kabaev   template<typename _Tp>
109ca6500fcSAlexander Kabaev     inline pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __len)110ca6500fcSAlexander Kabaev     get_temporary_buffer(ptrdiff_t __len)
111ffeaf689SAlexander Kabaev     { return std::__get_temporary_buffer(__len, static_cast<_Tp*>(0)); }
11200db7afdSDavid E. O'Brien 
11300db7afdSDavid E. O'Brien   /**
11400db7afdSDavid E. O'Brien    *  @brief The companion to get_temporary_buffer().
11500db7afdSDavid E. O'Brien    *  @param  p  A buffer previously allocated by get_temporary_buffer.
11600db7afdSDavid E. O'Brien    *  @return   None.
11700db7afdSDavid E. O'Brien    *
11800db7afdSDavid E. O'Brien    *  Frees the memory pointed to by p.
11900db7afdSDavid E. O'Brien    */
120ca6500fcSAlexander Kabaev   template<typename _Tp>
121ca6500fcSAlexander Kabaev     void
return_temporary_buffer(_Tp * __p)122ca6500fcSAlexander Kabaev     return_temporary_buffer(_Tp* __p)
123ffeaf689SAlexander Kabaev     { ::operator delete(__p, nothrow); }
12400db7afdSDavid E. O'Brien 
125ca6500fcSAlexander Kabaev   /**
126ffeaf689SAlexander Kabaev    *  A wrapper class to provide auto_ptr with reference semantics.
127ffeaf689SAlexander Kabaev    *  For example, an auto_ptr can be assigned (or constructed from)
128ffeaf689SAlexander Kabaev    *  the result of a function which returns an auto_ptr by value.
129ca6500fcSAlexander Kabaev    *
130ca6500fcSAlexander Kabaev    *  All the auto_ptr_ref stuff should happen behind the scenes.
131ca6500fcSAlexander Kabaev    */
132ca6500fcSAlexander Kabaev   template<typename _Tp1>
13300db7afdSDavid E. O'Brien     struct auto_ptr_ref
13400db7afdSDavid E. O'Brien     {
13500db7afdSDavid E. O'Brien       _Tp1* _M_ptr;
136ca6500fcSAlexander Kabaev 
137ca6500fcSAlexander Kabaev       explicit
auto_ptr_refauto_ptr_ref1381b86b14eSAlexander Kabaev       auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }
13900db7afdSDavid E. O'Brien     };
14000db7afdSDavid E. O'Brien 
141ca6500fcSAlexander Kabaev 
14200db7afdSDavid E. O'Brien   /**
143ca6500fcSAlexander Kabaev    *  @brief  A simple smart pointer providing strict ownership semantics.
144ca6500fcSAlexander Kabaev    *
145ca6500fcSAlexander Kabaev    *  The Standard says:
146ca6500fcSAlexander Kabaev    *  <pre>
147ffeaf689SAlexander Kabaev    *  An @c auto_ptr owns the object it holds a pointer to.  Copying
148ffeaf689SAlexander Kabaev    *  an @c auto_ptr copies the pointer and transfers ownership to the
149ffeaf689SAlexander Kabaev    *  destination.  If more than one @c auto_ptr owns the same object
150ffeaf689SAlexander Kabaev    *  at the same time the behavior of the program is undefined.
151ca6500fcSAlexander Kabaev    *
152ffeaf689SAlexander Kabaev    *  The uses of @c auto_ptr include providing temporary
153ffeaf689SAlexander Kabaev    *  exception-safety for dynamically allocated memory, passing
154ffeaf689SAlexander Kabaev    *  ownership of dynamically allocated memory to a function, and
155ffeaf689SAlexander Kabaev    *  returning dynamically allocated memory from a function.  @c
156ffeaf689SAlexander Kabaev    *  auto_ptr does not meet the CopyConstructible and Assignable
157ffeaf689SAlexander Kabaev    *  requirements for Standard Library <a
158ffeaf689SAlexander Kabaev    *  href="tables.html#65">container</a> elements and thus
159ffeaf689SAlexander Kabaev    *  instantiating a Standard Library container with an @c auto_ptr
160ffeaf689SAlexander Kabaev    *  results in undefined behavior.
161ca6500fcSAlexander Kabaev    *  </pre>
162ca6500fcSAlexander Kabaev    *  Quoted from [20.4.5]/3.
163ca6500fcSAlexander Kabaev    *
164ffeaf689SAlexander Kabaev    *  Good examples of what can and cannot be done with auto_ptr can
165ffeaf689SAlexander Kabaev    *  be found in the libstdc++ testsuite.
166ca6500fcSAlexander Kabaev    *
167ca6500fcSAlexander Kabaev    *  @if maint
168ffeaf689SAlexander Kabaev    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
169ca6500fcSAlexander Kabaev    *  127.  auto_ptr<> conversion issues
170ca6500fcSAlexander Kabaev    *  These resolutions have all been incorporated.
171ca6500fcSAlexander Kabaev    *  @endif
17200db7afdSDavid E. O'Brien    */
173ca6500fcSAlexander Kabaev   template<typename _Tp>
17400db7afdSDavid E. O'Brien     class auto_ptr
17500db7afdSDavid E. O'Brien     {
17600db7afdSDavid E. O'Brien     private:
17700db7afdSDavid E. O'Brien       _Tp* _M_ptr;
17800db7afdSDavid E. O'Brien 
17900db7afdSDavid E. O'Brien     public:
180ca6500fcSAlexander Kabaev       /// The pointed-to type.
18100db7afdSDavid E. O'Brien       typedef _Tp element_type;
18200db7afdSDavid E. O'Brien 
183ca6500fcSAlexander Kabaev       /**
184ca6500fcSAlexander Kabaev        *  @brief  An %auto_ptr is usually constructed from a raw pointer.
185ca6500fcSAlexander Kabaev        *  @param  p  A pointer (defaults to NULL).
186ca6500fcSAlexander Kabaev        *
187ca6500fcSAlexander Kabaev        *  This object now @e owns the object pointed to by @a p.
188ca6500fcSAlexander Kabaev        */
189ca6500fcSAlexander Kabaev       explicit
throw()1901b86b14eSAlexander Kabaev       auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
19100db7afdSDavid E. O'Brien 
192ca6500fcSAlexander Kabaev       /**
193ca6500fcSAlexander Kabaev        *  @brief  An %auto_ptr can be constructed from another %auto_ptr.
194ca6500fcSAlexander Kabaev        *  @param  a  Another %auto_ptr of the same type.
195ca6500fcSAlexander Kabaev        *
1961b86b14eSAlexander Kabaev        *  This object now @e owns the object previously owned by @a a,
1971b86b14eSAlexander Kabaev        *  which has given up ownsership.
198ca6500fcSAlexander Kabaev        */
throw()1991b86b14eSAlexander Kabaev       auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
20000db7afdSDavid E. O'Brien 
201ca6500fcSAlexander Kabaev       /**
202ca6500fcSAlexander Kabaev        *  @brief  An %auto_ptr can be constructed from another %auto_ptr.
203ca6500fcSAlexander Kabaev        *  @param  a  Another %auto_ptr of a different but related type.
204ca6500fcSAlexander Kabaev        *
205ffeaf689SAlexander Kabaev        *  A pointer-to-Tp1 must be convertible to a
206ffeaf689SAlexander Kabaev        *  pointer-to-Tp/element_type.
207ca6500fcSAlexander Kabaev        *
2081b86b14eSAlexander Kabaev        *  This object now @e owns the object previously owned by @a a,
2091b86b14eSAlexander Kabaev        *  which has given up ownsership.
210ca6500fcSAlexander Kabaev        */
211ca6500fcSAlexander Kabaev       template<typename _Tp1>
auto_ptr(auto_ptr<_Tp1> & __a)2121b86b14eSAlexander Kabaev         auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
213ca6500fcSAlexander Kabaev 
214ca6500fcSAlexander Kabaev       /**
215ca6500fcSAlexander Kabaev        *  @brief  %auto_ptr assignment operator.
216ca6500fcSAlexander Kabaev        *  @param  a  Another %auto_ptr of the same type.
217ca6500fcSAlexander Kabaev        *
2181b86b14eSAlexander Kabaev        *  This object now @e owns the object previously owned by @a a,
2191b86b14eSAlexander Kabaev        *  which has given up ownsership.  The object that this one @e
2201b86b14eSAlexander Kabaev        *  used to own and track has been deleted.
221ca6500fcSAlexander Kabaev        */
222ca6500fcSAlexander Kabaev       auto_ptr&
throw()223ca6500fcSAlexander Kabaev       operator=(auto_ptr& __a) throw()
224ca6500fcSAlexander Kabaev       {
22500db7afdSDavid E. O'Brien 	reset(__a.release());
22600db7afdSDavid E. O'Brien 	return *this;
22700db7afdSDavid E. O'Brien       }
22800db7afdSDavid E. O'Brien 
229ca6500fcSAlexander Kabaev       /**
230ca6500fcSAlexander Kabaev        *  @brief  %auto_ptr assignment operator.
231ca6500fcSAlexander Kabaev        *  @param  a  Another %auto_ptr of a different but related type.
232ca6500fcSAlexander Kabaev        *
233ca6500fcSAlexander Kabaev        *  A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type.
234ca6500fcSAlexander Kabaev        *
2351b86b14eSAlexander Kabaev        *  This object now @e owns the object previously owned by @a a,
2361b86b14eSAlexander Kabaev        *  which has given up ownsership.  The object that this one @e
2371b86b14eSAlexander Kabaev        *  used to own and track has been deleted.
238ca6500fcSAlexander Kabaev        */
239ca6500fcSAlexander Kabaev       template<typename _Tp1>
240ca6500fcSAlexander Kabaev         auto_ptr&
throw()241ca6500fcSAlexander Kabaev         operator=(auto_ptr<_Tp1>& __a) throw()
242ca6500fcSAlexander Kabaev         {
24300db7afdSDavid E. O'Brien 	  reset(__a.release());
24400db7afdSDavid E. O'Brien 	  return *this;
24500db7afdSDavid E. O'Brien 	}
24600db7afdSDavid E. O'Brien 
247ca6500fcSAlexander Kabaev       /**
248ffeaf689SAlexander Kabaev        *  When the %auto_ptr goes out of scope, the object it owns is
249ffeaf689SAlexander Kabaev        *  deleted.  If it no longer owns anything (i.e., @c get() is
250ffeaf689SAlexander Kabaev        *  @c NULL), then this has no effect.
251ca6500fcSAlexander Kabaev        *
252ca6500fcSAlexander Kabaev        *  @if maint
253ca6500fcSAlexander Kabaev        *  The C++ standard says there is supposed to be an empty throw
254ca6500fcSAlexander Kabaev        *  specification here, but omitting it is standard conforming.  Its
255ca6500fcSAlexander Kabaev        *  presence can be detected only if _Tp::~_Tp() throws, but this is
256ca6500fcSAlexander Kabaev        *  prohibited.  [17.4.3.6]/2
257*f8a1b7d9SAlexander Kabaev        *  @endif
258ca6500fcSAlexander Kabaev        */
~auto_ptr()25900db7afdSDavid E. O'Brien       ~auto_ptr() { delete _M_ptr; }
26000db7afdSDavid E. O'Brien 
261ca6500fcSAlexander Kabaev       /**
262ca6500fcSAlexander Kabaev        *  @brief  Smart pointer dereferencing.
263ca6500fcSAlexander Kabaev        *
2641b86b14eSAlexander Kabaev        *  If this %auto_ptr no longer owns anything, then this
2651b86b14eSAlexander Kabaev        *  operation will crash.  (For a smart pointer, "no longer owns
2661b86b14eSAlexander Kabaev        *  anything" is the same as being a null pointer, and you know
2671b86b14eSAlexander Kabaev        *  what happens when you dereference one of those...)
268ca6500fcSAlexander Kabaev        */
269ca6500fcSAlexander Kabaev       element_type&
throw()270ffeaf689SAlexander Kabaev       operator*() const throw()
271ffeaf689SAlexander Kabaev       {
272ffeaf689SAlexander Kabaev 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
273ffeaf689SAlexander Kabaev 	return *_M_ptr;
274ffeaf689SAlexander Kabaev       }
275ca6500fcSAlexander Kabaev 
276ca6500fcSAlexander Kabaev       /**
277ca6500fcSAlexander Kabaev        *  @brief  Smart pointer dereferencing.
278ca6500fcSAlexander Kabaev        *
279ca6500fcSAlexander Kabaev        *  This returns the pointer itself, which the language then will
280ca6500fcSAlexander Kabaev        *  automatically cause to be dereferenced.
281ca6500fcSAlexander Kabaev        */
282ca6500fcSAlexander Kabaev       element_type*
283ffeaf689SAlexander Kabaev       operator->() const throw()
284ffeaf689SAlexander Kabaev       {
285ffeaf689SAlexander Kabaev 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
286ffeaf689SAlexander Kabaev 	return _M_ptr;
287ffeaf689SAlexander Kabaev       }
288ca6500fcSAlexander Kabaev 
289ca6500fcSAlexander Kabaev       /**
290ca6500fcSAlexander Kabaev        *  @brief  Bypassing the smart pointer.
291ca6500fcSAlexander Kabaev        *  @return  The raw pointer being managed.
292ca6500fcSAlexander Kabaev        *
293ca6500fcSAlexander Kabaev        *  You can get a copy of the pointer that this object owns, for
294ffeaf689SAlexander Kabaev        *  situations such as passing to a function which only accepts
295ffeaf689SAlexander Kabaev        *  a raw pointer.
296ca6500fcSAlexander Kabaev        *
297ca6500fcSAlexander Kabaev        *  @note  This %auto_ptr still owns the memory.
298ca6500fcSAlexander Kabaev        */
299ca6500fcSAlexander Kabaev       element_type*
get()300ca6500fcSAlexander Kabaev       get() const throw() { return _M_ptr; }
301ca6500fcSAlexander Kabaev 
302ca6500fcSAlexander Kabaev       /**
303ca6500fcSAlexander Kabaev        *  @brief  Bypassing the smart pointer.
304ca6500fcSAlexander Kabaev        *  @return  The raw pointer being managed.
305ca6500fcSAlexander Kabaev        *
306ca6500fcSAlexander Kabaev        *  You can get a copy of the pointer that this object owns, for
307ffeaf689SAlexander Kabaev        *  situations such as passing to a function which only accepts
308ffeaf689SAlexander Kabaev        *  a raw pointer.
309ca6500fcSAlexander Kabaev        *
310ca6500fcSAlexander Kabaev        *  @note  This %auto_ptr no longer owns the memory.  When this object
311ca6500fcSAlexander Kabaev        *  goes out of scope, nothing will happen.
312ca6500fcSAlexander Kabaev        */
313ca6500fcSAlexander Kabaev       element_type*
release()314ca6500fcSAlexander Kabaev       release() throw()
315ca6500fcSAlexander Kabaev       {
316ca6500fcSAlexander Kabaev 	element_type* __tmp = _M_ptr;
31700db7afdSDavid E. O'Brien 	_M_ptr = 0;
31800db7afdSDavid E. O'Brien 	return __tmp;
31900db7afdSDavid E. O'Brien       }
320ca6500fcSAlexander Kabaev 
321ca6500fcSAlexander Kabaev       /**
322ca6500fcSAlexander Kabaev        *  @brief  Forcibly deletes the managed object.
323ca6500fcSAlexander Kabaev        *  @param  p  A pointer (defaults to NULL).
324ca6500fcSAlexander Kabaev        *
325ffeaf689SAlexander Kabaev        *  This object now @e owns the object pointed to by @a p.  The
326ffeaf689SAlexander Kabaev        *  previous object has been deleted.
327ca6500fcSAlexander Kabaev        */
328ca6500fcSAlexander Kabaev       void
throw()329ca6500fcSAlexander Kabaev       reset(element_type* __p = 0) throw()
330ca6500fcSAlexander Kabaev       {
331ca6500fcSAlexander Kabaev 	if (__p != _M_ptr)
332ca6500fcSAlexander Kabaev 	  {
33300db7afdSDavid E. O'Brien 	    delete _M_ptr;
33400db7afdSDavid E. O'Brien 	    _M_ptr = __p;
33500db7afdSDavid E. O'Brien 	  }
33600db7afdSDavid E. O'Brien       }
33700db7afdSDavid E. O'Brien 
338*f8a1b7d9SAlexander Kabaev       /**
339ca6500fcSAlexander Kabaev        *  @brief  Automatic conversions
340ca6500fcSAlexander Kabaev        *
341ca6500fcSAlexander Kabaev        *  These operations convert an %auto_ptr into and from an auto_ptr_ref
342ca6500fcSAlexander Kabaev        *  automatically as needed.  This allows constructs such as
343ca6500fcSAlexander Kabaev        *  @code
344ca6500fcSAlexander Kabaev        *    auto_ptr<Derived>  func_returning_auto_ptr(.....);
345ca6500fcSAlexander Kabaev        *    ...
346ca6500fcSAlexander Kabaev        *    auto_ptr<Base> ptr = func_returning_auto_ptr(.....);
347ca6500fcSAlexander Kabaev        *  @endcode
348ca6500fcSAlexander Kabaev        */
throw()349ca6500fcSAlexander Kabaev       auto_ptr(auto_ptr_ref<element_type> __ref) throw()
35000db7afdSDavid E. O'Brien       : _M_ptr(__ref._M_ptr) { }
35100db7afdSDavid E. O'Brien 
352ca6500fcSAlexander Kabaev       auto_ptr&
throw()353ca6500fcSAlexander Kabaev       operator=(auto_ptr_ref<element_type> __ref) throw()
354ca6500fcSAlexander Kabaev       {
355ca6500fcSAlexander Kabaev 	if (__ref._M_ptr != this->get())
356ca6500fcSAlexander Kabaev 	  {
35700db7afdSDavid E. O'Brien 	    delete _M_ptr;
35800db7afdSDavid E. O'Brien 	    _M_ptr = __ref._M_ptr;
35900db7afdSDavid E. O'Brien 	  }
36000db7afdSDavid E. O'Brien 	return *this;
36100db7afdSDavid E. O'Brien       }
36200db7afdSDavid E. O'Brien 
363ca6500fcSAlexander Kabaev       template<typename _Tp1>
throw()364ca6500fcSAlexander Kabaev         operator auto_ptr_ref<_Tp1>() throw()
365ca6500fcSAlexander Kabaev         { return auto_ptr_ref<_Tp1>(this->release()); }
366ca6500fcSAlexander Kabaev 
367ca6500fcSAlexander Kabaev       template<typename _Tp1>
throw()368ca6500fcSAlexander Kabaev         operator auto_ptr<_Tp1>() throw()
36900db7afdSDavid E. O'Brien         { return auto_ptr<_Tp1>(this->release()); }
37000db7afdSDavid E. O'Brien   };
371*f8a1b7d9SAlexander Kabaev 
372*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
37300db7afdSDavid E. O'Brien 
374ffeaf689SAlexander Kabaev #endif /* _GLIBCXX_MEMORY */
375