<html>
	<head>
		<title>A Proposal to Add General Purpose Smart Pointers to the Library Technical 
			Report</title>
		<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
		<meta http-equiv="Content-Language" content="en-us">
		<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
	</head>
	<body bgcolor="#ffffff">
		<ADDRESS>Document number: N1431=03-0013</ADDRESS>
		<ADDRESS>Programming Language C++, Library Subgroup</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>Peter Dimov &lt;<A href="mailto:pdimov@mmltd.net">pdimov@mmltd.net</A>&gt;</ADDRESS>
		<ADDRESS>Beman Dawes &lt;<A href="mailto:bdawes@acm.org">bdawes@acm.org</A>&gt;</ADDRESS>
		<ADDRESS>Greg Colvin &lt;<A href="mailto:greg@colvin.org">greg@colvin.org</A>&gt;</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>February 28, 2003</ADDRESS>
		<h1>A Proposal to Add General Purpose Smart Pointers to the Library Technical 
			Report</h1>
		<h2>I. Motivation</h2>
		<p>Resource management, particularly of dynamically allocated memory, has been a 
			serious concern since the days of the earliest digital computers. Many modern 
			computer languages (Python, Perl, Java) provide built-in facilities for 
			automatically managing dynamically allocated memory. In both the C and C++ 
			languages, leaving dynamic memory management choices up to the programmer is a 
			long-standing design decision.</p>
		<p>Use of a pointer-like object called a <i>smart-pointer</i> to manage dynamically 
			allocated memory has been the preferred approach in C++ for many years. Google 
			finds 153,000 references to the term "smart pointer", with the high-ranking 
			listings almost entirely in the context of C++ programming. Leading authors of 
			C++ related books often treat smart pointers in depth. Of the 50 plus C++ 
			libraries available on the Boost web site, the Boost Smart Pointer library is 
			the most commonly visited. Smart pointers are encountered with great frequency 
			in production code. There is clearly great interest and need for quality smart 
			pointers in the C++ community.</p>
		<p>The list of possible smart pointer features is extremely broad. The C++ Standard 
			Library currently provides a single smart pointer, <i>std::auto_ptr</i>, which 
			provides specific and focused transfer-of-ownership semantics. Arguably the 
			most common need, however, is for shared-ownership semantics. Because <i>std::auto_ptr</i>
			does not provide shared-ownership semantics, it cannot even be used with 
			Standard Library containers.</p>
		<p>This document proposes a smart-pointer with shared-ownership semantics which 
			meets a very broad spectrum of smart-pointer needs, is based on existing 
			practice, and has many other beneficial characteristics. An implementation is 
			available at <a href="http://www.boost.org/libs/smart_ptr">http://www.boost.org/libs/smart_ptr</a>.</p>
		<h3>A. Motivation for a shared-ownership smart pointer</h3>
		<p>A shared-ownership smart pointer:</p>
		<ul>
			<li>
			Is a reasonable default choice for many or even most smart pointer needs, 
			consistent with the spirit of the Standard Library.
			<li>
			Can be used in Standard Library containers, filling a major embarrassing gap in 
			the current Standard Library.
			<li>
				Has been reinvented thousands of times [<A href="#Google03">Google03</A>].
			<li>
				Is very hard to specify and implement correctly, particularly as regards 
				exception safety, thread safety, and weak pointers. See <A href="#Implementation-difficulty">
					Implementation difficulty</A> below.
			</li>
		</ul>
		<h3>B. Motivation for the <i>shared_ptr</i> shared-ownership smart pointer</h3>
		<p><i>[Rather than specifying memory management policy via class template parameters, 
				shared_ptr has an alternate constructor with a second argument supplying a 
				destruction policy functor. This is the key to understanding both the design 
				itself and several of the claimed advantages.]</i></p>
		<p>The proposed shared-ownership smart pointer:</p>
		<ul>
			<li>
			Has the same object type regardless of features used, greatly facilitating 
			interoperability between libraries, including third-party libraries.
			<li>
			Supports custom deallocators, allowing user-specified memory policies and 
			extending management to a wide range of object types, such as COM objects.
			<li>
			Supports weak pointers, allowing cycle breaking and supporting observer 
			applications such as caches.
			<li>
				Delivers exceptional expressive power without additional template 
				parameterization, easing use by novices and experts alike. [<a href="#Deleter">III.B.2</a>][<A href="#Dimov03">Dimov03</A>]<li>
			Supports encapsulation and implementation hiding via the ability to safely use 
			incomplete classes and protected nonvirtual base destructors, and the ability 
			to hide allocation details.
			<li>
			"Just works" in numerous tricky situations, such as calling the right 
			destructor and crossing load-unit/heap boundaries.
			<li>
			Requires no language support.<li>
			Does not prevent users or the Standard Library itself from later adding other 
			smart pointers to meet additional needs.
			<li>
			Allows several implementation techniques, leaving implementors room for 
			tradeoffs.
			<li>
				Reflects existing practice with a decade of refinement and use, including many 
				non-obvious enhancements. [<A href="#Colvin94">Colvin94</A>]
			<li>
				Is widely recommended in books, magazine articles, and newsgroup postings by 
				both C++ experts and everyday users.
			</li>
		</ul>
		<h3>C. Motivation for the <i>weak_ptr</i> shared-ownership-observer smart pointer</h3>
		<ul>
			<li>
				Supports data structures with cyclic pointers, with the benefit that either <i>weak_ptr</i>
				or <i>shared_ptr</i>
			covers all important shared-ownership use cases.
			<li>
				Supports observer idioms such as caches. Allows functions or classes to keep 
				references to objects without affecting their lifetime. (See [<A href="#Boehm02">Boehm02</A>] 
				for an example where using a <EM>shared_ptr</EM> instead of a <EM>weak_ptr</EM>
			as an observer leads to deadlock.)
			<li>
			Replaces unsafe uses of raw pointers, eliminating the possibility of following 
			a dangling pointer.
			<LI>
			Is very hard to specify and implement correctly.
			<li>
				Reflects existing practice with a decade of refinement and use. [<A href="#Ellis94">Ellis94</A>]
			</li>
		</ul>
		<h3><a name="Implementation-difficulty">D. Implementation difficulty</a></h3>
		<p>The Boost developers found a shared-ownership smart pointer exceedingly 
			difficult to implement correctly. Others have made the same observation. For 
			example, Scott Meyers [<A href="#Meyers01">Meyers01</A>] says:</p>
		<blockquote>
			<p>The STL itself contains no reference-counting smart pointer, and writing a good 
				one - one that works correctly all the time - is tricky enough that you don't 
				want to do it unless you have to. I published the code for a reference-counting 
				smart pointer in More Effective C++ in 1996, and despite basing it on 
				established smart pointer implementations and submitting it to extensive 
				pre-publication reviewing by experienced developers, a small parade of valid 
				bug reports has trickled in for years. The number of subtle ways in which 
				reference-counting smart pointers can fail is remarkable.</p>
		</blockquote>
		<h4>Example 1</h4>
		<blockquote><pre>shared_ptr&lt;X&gt; p(new X);</pre>
		</blockquote>
		<p>It is very common for even expert implementations to leak the X object when the 
			constructor throws an exception.</p>
		<h4>Example 2</h4>
		<blockquote><pre>p.reset(new X);</pre>
		</blockquote>
		<p>A variation of the above example. The behavior when reset throws should be to 
			delete the X object, and have no other effects, i.e. p must be left unchanged.</p>
		<h4>Example 3</h4>
		<p>Taken from Boost's shared_ptr_test.cpp:</p>
		<blockquote><pre>struct X
{
    boost::shared_ptr&lt;X&gt; next;
};

void test()
{
    boost::shared_ptr&lt;X&gt; p(new X);
    p-&gt;next = boost::shared_ptr&lt;X&gt;(new X);
    p = p-&gt;next;
    BOOST_TEST(!p-&gt;next);
}</pre>
		</blockquote>
		<p>Again, it is surprising how many experts get this wrong.</p>
		<P><EM>weak_ptr</EM> represents an additional source of difficulty. Its stored 
			pointer can be invalidated literally at any time; even in strictly single 
			threaded and synchronous programs it is possible for the code to call a library 
			that calls back a routine invalidating a <EM>weak_ptr</EM>. As the value of a 
			pointer referring to deallocated storage is indeterminate (5.3.5/4), the <EM>weak_ptr</EM>
			implementation must take care not to access the stored pointer value after the <EM>weak_ptr</EM>
			has <EM>expired</EM>. Furthermore, the <EM>weak_ptr</EM> interface should 
			protect users from accidentally accessing a pointer to deallocated storage.</P>
		<h2>II. Impact On the Standard</h2>
		<p>This proposal is almost a pure library extension. It proposes changes to an 
			existing header, <code>&lt;memory&gt;</code>, but it does not require changes 
			to any standard classes or functions and it does not require changes to any of 
			the standard requirement tables. It does not require any changes in the core 
			language, and it has been implemented in standard C++. The proposal does not 
			depend on any other library extensions.
		</p>
		<h2>III. Design Decisions</h2>
		<h3>A. General Principles</h3>
		<h4>1. "As Close to Raw Pointers as Possible, but no Closer"</h4>
		<p>Ordinary C++ pointers have some interesting properties that make them suitable 
			for a wide range of tasks. It is possible to copy, assign, pass and return by 
			value. It is possible to "destroy" a pointer to an incomplete type. It is 
			possible to refer to any object's address using a pointer to <code>void</code>. 
			Pointers to derived classes are implicitly convertible to pointers to base 
			classes, and it is possible to use <code>static_cast</code> or <code>dynamic_cast</code>
			to perform the opposite conversion.</p>
		<P>The two main problems with ordinary pointers are the need for manual resource 
			management and the possibility of accessing an invalid (dangling) pointer.</P>
		<P>The proposed smart pointers retain the strengths of raw pointers, eliminating 
			their weaknesses. <EM>shared_ptr</EM> and <EM>weak_ptr</EM> fully support 
			incomplete types, cv-qualified types, and <code>void</code> as a template 
			parameter. They support derived-to-base implicit conversions. <EM>shared_ptr</EM>
			supports static and dynamic casts, and will automatically delete (or otherwise 
			release) the object it owns when the last <EM>shared_ptr</EM> instance is 
			destroyed. <EM>weak_ptr</EM> eliminates the possibility of accessing a dangling 
			pointer.</P>
		<h4>2. "Just Do the Right Thing"</h4>
		<p>The versatility described in the previous paragraphs can lead to some tricky 
			situations. A <EM>shared_ptr</EM> can be created in a shared library and then 
			destroyed by the application. By using implicit conversions, the last remaining <EM>
				shared_ptr</EM> instance to an object may turn out to have a template 
			parameter of <code>void</code>, a base with an inaccessible or nonvirtual 
			destructor, or an incomplete type.</p>
		<P>The general principle followed by the proposed design is that in such 
			situations, the implementation should "just do the right thing" and invoke the 
			proper destructor or <code>operator delete</code>. This implies that the 
			information necessary to properly destroy the managed object is fully captured 
			at the point where the smart pointer is constructed.</P>
		<h4>3. No Extra Parameters</h4>
		<p>Following the "as close as possible" principle, the proposed smart pointers have 
			a single template parameter, the type of the pointee. Avoiding additional 
			parameters ensures interoperability between libraries from different authors, 
			and also makes <EM>shared_ptr</EM> easier to use, teach and recommend.</p>
		<h4>4. The "Shares Ownership with" Equivalence Relation</h4>
		<p>The proposed text uses "<STRONG>p</STRONG> <EM>shares ownership with</EM> <STRONG>q</STRONG>" 
			to indicate that <STRONG>p</STRONG> and <STRONG>q</STRONG> have both originated 
			from the same smart pointer, and <EM>own</EM> the same object. "<EM>Shares 
				ownership with</EM>" is an equivalence relation. It is reflexive (<STRONG>p</STRONG>
			<EM>shares ownership with</EM> <STRONG>p</STRONG>), commutative (if <STRONG>p</STRONG>
			<EM>shares ownership with</EM> <STRONG>q</STRONG>, <STRONG>q</STRONG> also <EM>shares 
				ownership with</EM> <STRONG>p</STRONG>), and transitive (if <STRONG>p</STRONG>
			<EM>shares ownership with</EM> <STRONG>q</STRONG> and <STRONG>q</STRONG> <EM>shares 
				ownership with</EM> <STRONG>r</STRONG>, <STRONG>p</STRONG> <EM>shares ownership 
				with</EM> <STRONG>r</STRONG>). This relation divides all non-<EM>empty</EM> 
			smart pointers into equivalence classes. The number of <EM>shared_ptr</EM> instances 
			in <STRONG>p</STRONG>'s equivalence class can be obtained using <code>p.use_count()</code>. 
			The last <EM>shared_ptr</EM> instance in a given equivalence class is 
			responsible for destroying the <EM>owned</EM> object.</p>
		<P>In a typical counted implementation, two smart pointers <EM>share ownership</EM> 
			when they share the same reference count. In a linked list implementation, two 
			smart pointers share ownership when they are part of the same list.</P>
		<h4>5. The "Empty Pointer" Concept</h4>
		<p>Default-constructed smart pointers, and smart pointer instances that have been <code>
				reset()</code>, are called <EM>empty</EM> in the proposed text. It is 
			necessary to introduce this concept to offer the nothrow guarantee for <code>shared_ptr::shared_ptr()</code>,
			<code>shared_ptr::reset()</code>, <code>weak_ptr::weak_ptr()</code>, and <code>weak_ptr::reset()</code>.
			<code>p.reset()</code> for smart pointers is often used as an equivalent for <code>delete 
				p</code> for raw pointers, hence the need to guarantee that this operation 
			doesn't throw.</p>
		<P>The infrastructure required to keep track of ownership may need to dynamically 
			allocate memory. To ensure that default constructors and <code>reset()</code> do 
			not throw, these operations are allowed to skip this allocation, and produce <EM>empty</EM>
			smart pointers that do not track ownership, and do not fully support 
			ownership-related queries such as <code>use_count()</code>.</P>
		<P>One reasonable implementation of the <EM>empty</EM> pointer concept is to reuse 
			one or more statically allocated reference counts for default-constructed 
			pointer instances. Under this model, <EM>empty</EM> pointers do represent one 
			or more equivalence classes under the ownership equivalence relation described 
			in the previous section, and <code>use_count()</code> returns "realistic" 
			values that increase and decrease as additional <EM>empty</EM> pointers are 
			created or destroyed.</P>
		<P>Another approach, used in the Boost implementation, is to not allocate a 
			reference count at all for <EM>empty</EM> pointers, using a <code>NULL</code> pointer 
			to count as an "<EM>empty</EM> mark". Under this scheme <EM>empty</EM> pointers 
			have a constant <code>use_count()</code> (zero in the Boost implementation.)</P>
		<P>The specification has been carefully balanced to not disallow either 
			implementation, while at the same time offering as useful postconditions and 
			behavior as possible under those constraints.</P>
		<h3>B. shared_ptr</h3>
		<h4>1. Pointer Constructor</h4>
		<p>The <EM>shared_ptr</EM> constructor that takes a raw pointer is templated on the 
			pointer type, in order to capture as much information as possible at the point 
			of construction. This allows, for example, a <EM>shared_ptr&lt;void&gt;</EM> instance 
			constructed as:</p>
		<pre>shared_ptr&lt;void&gt; px(new X);</pre>
		<P>to properly invoke <code>~X</code> at destruction time, in accordance with the 
			"just do the right thing" principle.</P>
		<P>The templated constructor cannot be used to construct a <EM>shared_ptr</EM> from 
			the literal zero, or another integral constant expression with a value of zero, 
			since the type of the pointer cannot be determined. The <EM>shared_ptr</EM> equivalent 
			of <code>NULL</code> is obtained from the default constructor. In contexts 
			where it's important to obtain a <code>NULL</code> instance of a pointer type <code>
				P</code> in a generic way, the construct:</P>
		<pre>P p = P();</pre>
		<P>may be used instead of</P>
		<pre>P p(0);</pre>
		<p>Implementations are allowed to throw exceptions other than <code>std::bad_alloc</code>
			since on some platforms they might need to create a mutex to synchronize the 
			access to the ownership infrastructure.</p>
		<P>A common concern, dating back to [<A href="#Colvin94">Colvin94</A>], is that it 
			is very easy to violate the preconditions of smart pointer operations. This 
			proposal attempts to systematically eliminate undefined behavior possibilities 
			as long as the user is manipulating already valid <EM>shared_ptr</EM> (and <EM>weak_ptr</EM>) 
			instances, but using the pointer constructor correctly is still up to the user.</P>
		<P>One possible alternative is to eliminate this unsafe constructor, and instead 
			provide a family of factory functions of the form:</P>
		<pre>template&lt;class T&gt; shared_ptr&lt;T&gt; shared_new()
{
    return shared_ptr&lt;T&gt;(new T());
}

template&lt;class T, class A1&gt; shared_ptr&lt;T&gt; shared_new(A1 const &amp; a1)
{
    return shared_ptr&lt;T&gt;(new T(a1));
}

template&lt;class T, class A1, class A2&gt; shared_ptr&lt;T&gt; shared_new(A1 const &amp; a1, A2 const &amp; a2)
{
    return shared_ptr&lt;T&gt;(new T(a1, a2));
}
</pre>
		<P>This approach has not been adopted for the following reasons:</P>
		<UL>
			<LI>
				An important application of <EM>shared_ptr</EM>
			is to wrap existing raw pointer based interfaces;
			<LI>
			When a class has an inaccessible constructor, the factory function will fail to 
			compile;
			<LI>
				Forwarding an arbitrary list of arguments may be problematic [<A href="#Dimov02">Dimov02</A>];
			<LI>
				Widespread existing practice strongly favors the unprotected but powerful 
				pointer constructor approach.</LI></UL>
		<P>As an alternative, the Boost implementation offers an experimental debug mode [<A href="#Boost03a">Boost03a</A>] 
			that catches many common errors at runtime, including misuse of the pointer 
			constructor and invoking <code>delete</code> on a pointer managed by <EM>shared_ptr</EM>.</P>
		<h4>2. <a name="Deleter">Deleter</a> Constructor</h4>
		<p>Custom deleters allow a factory function returning a <EM>shared_ptr</EM> to 
			insulate the <EM>shared_ptr</EM> user from its memory allocation strategy. 
			Since the deleter is not part of the type, changing the allocation strategy 
			does not break source or binary compatibility, and does not require a client 
			recompilation. For example, a "no-op" deleter is useful when returning a <EM>shared_ptr</EM>
			to a statically allocated object. A deleter that invokes the <code>Release()</code>
			member function enables <EM>shared_ptr</EM> to hold a pointer to a COM object, 
			and other variations allow a <EM>shared_ptr</EM> to be used as a wrapper for 
			another smart pointer, easing interoperability. See [<A href="#Dimov03">Dimov03</A>] 
			for many other examples for the tremendous expressive power gained by the 
			custom deleter support.</EM></p>
		<P>In the Boost implementation, supporting custom deleters does not impose 
			additional memory overhead on the shared_ptr itself. See <a href="#Memory-footprint">
				Memory Footprint</a> [E.1]. Earlier <EM>shared_ptr</EM> versions did not 
			offer the deleter constructor, but in order to meet the "just do the right 
			thing" requirement (III.A.2), the implementation kept a deleter under the hood 
			anyway.</P>
		<P>The requirement for the copy constructor of <code>D</code> to not throw comes 
			from the pass by value. If the copy constructor throws, the pointer is leaked. 
			Removing the requirement requires a pass by (const) reference.</P>
		<P>The main problem with pass by reference lies in its interaction with rvalues. A 
			const reference may still cause a copy, and will require a const <code>D::operator()</code>. 
			A non-const reference won't bind to an rvalue at all. A good solution to this 
			problem is the rvalue reference proposed in [<A href="#Hinnant02">Hinnant02</A>].</P>
		<P>For the Boost implementation, an additional reason to avoid pass by reference 
			has been portability; pass by value handles functions and function references 
			well on a wide range of compilers.</P>
		<h4>3. weak_ptr Constructor</h4>
		<p><EM>shared_ptr</EM> provides a converting constructor from <EM>weak_ptr</EM>, 
			with the postcondition that the newly constructed <EM>shared_ptr</EM> shares 
			ownership with the <EM>weak_ptr</EM> argument (when non-<EM>empty</EM>.) In 
			other words, it is possible to copy a <EM>shared_ptr</EM> using an intermediate <EM>
				weak_ptr</EM>, and the copy and the original will share ownership. If this 
			postcondition cannot be met, as will happen if all <EM>shared_ptr</EM> instances 
			sharing ownership with the <EM>weak_ptr</EM> argument have been already 
			destroyed, the constructor throws an exception of type <EM>bad_weak_ptr</EM>.</p>
		<P>An alternative way of obtaining a <EM>shared_ptr</EM> from a <EM>weak_ptr</EM> is 
			to use <EM>weak_ptr</EM>'s member function <code>lock</code>. It indicates 
			failure by returning an <EM>empty</EM> <EM>shared_ptr</EM>.</P>
		<h4>4. std::auto_ptr Constructor</h4>
		<p><EM>shared_ptr</EM> provides a converting constructor from <EM>std::auto_ptr</EM>. 
			It is almost equivalent to calling <code>release()</code> on the source <EM>auto_ptr</EM>
			and using the raw pointer constructor; the only difference is that this 
			constructor provides the strong exception safety guarantee, and in case an 
			exception is thrown, it will leave the source <EM>auto_ptr</EM> unchanged. To 
			achieve this, the constructor takes the source by a non-const reference; pass 
			by value would be equivalent to using <code>release()</code>.</p>
		<P>If the "rvalue reference" proposed in [<A href="#Hinnant02">Hinnant02</A>] is 
			accepted, the constructor can take advantage of it in order to be able to take 
			an <EM>auto_ptr</EM> rvalue as an argument.</P>
		<h4>5. Assignment and <code>reset</code></h4>
		<p>Assignment and <code>reset</code> are specified in terms of construction and 
			swap, but the intent is to not preclude more efficient implementations that 
			have the same effects, hence the note.</p>
		<h4>6. <code>operator-&gt;</code></h4>
		<p><code>operator-&gt;</code> requires that <code>get() != 0</code> in order to 
			allow conforming implementations to assert in debug mode.</p>
		<h4>7. <code>use_count</code> and <code>unique</code></h4>
		<p><code>use_count</code> is provided as a testing and debugging aid rather than 
			for use in production code. It allows postconditions to be specified in a form 
			that can be tested by client code, and it has been proven useful in practice 
			when tracking down bugs in projects with complex ownership structures. 
			Production code should not rely on <code>use_count</code> as it may be 
			inefficient. While all known reasonable shared ownership implementations can 
			support <code>use_count</code>, not all can do so in an efficient manner.</p>
		<P>The common <code>use_count() == 1</code> query has been given its own name for 
			efficiency reasons, since some implementations can provide a constant time <code>unique()</code>
			but not a constant time <code>use_count()</code>.</P>
		<P>The return type of <code>use_count</code> is signed to avoid pitfalls such as <code>p.use_count() 
				&gt; -1</code> evaluating to <code>false</code> [<A href="#Lakos96">Lakos96</A>].</P>
		<h4>8. Conversion Operator</h4>
		<p>To meet the "convertible to <code>bool</code>" requirement, <EM>shared_ptr</EM> has 
			a conversion operator to an unspecified type (the Boost implementation uses a 
			pointer to member).</p>
		<P><code>std::basic_ios</code>'s approach of having a conversion to <code>void*</code>
			has been deemed unsuitable for a smart pointer. Such a conversion enables far 
			too many undesirable constructs to compile (one striking example is invoking <code>delete</code>
			with a <EM>shared_ptr</EM> operand.) When migrating code that uses raw pointers 
			to <EM>shared_ptr</EM>, it is important for constructs that were valid for the 
			original raw pointer based code, but are errors under the new design, to be 
			caught at compile time.</P>
		<h4>9. <code>operator&lt;</code></h4>
		<p><code>operator&lt;</code> does not compare the stored pointers. It is 
			implemented in terms of the ownership infrastructure. A typical counted 
			implementation would compare the count pointers (using <code>std::less</code> if 
			appropriate.)</p>
		<P>One reason to avoid stored pointer comparisons is consistency with <EM>weak_ptr</EM>, 
			where the value of the stored pointer may be (or become) indeterminate without 
			affecting the ordering provided by <code>operator&lt;</code>. Another 
			motivation for this <code>operator&lt;</code> behavior is support for the <code>std::map&lt; 
				shared_ptr&lt;X&gt;, V &gt;</code> <A href="http://www.boost.org/libs/smart_ptr/sp_techniques.html#extra_data">
				idiom</A> that associates data with objects managed by <EM>shared_ptr</EM> (with 
			an important special case being <code>X=void</code>.) [<A href="#Dimov03">Dimov03</A>]</P>
		<P>In most typical scenarios, a <code>std::map</code> with <EM>shared_ptr</EM> as 
			key would behave as if the stored pointers have been used. The exception is 
			that in some situations involving multiple or virtual inheritance, it is 
			possible for two pointers of the same type to point to different sub-objects 
			within the same object. Therefore, two <EM>shared_ptr</EM> instances storing 
			such pointers but sharing ownership will be considered equivalent by <code>operator&lt;</code>, 
			but may not compare equal when using <code>operator==</code> (defined as a 
			stored pointer comparison.)</P>
		<P>One additional benefit of this <code>operator&lt;</code> specification is that 
			it enables "does p share ownership with q" queries to be expressed as <code>!(p 
				&lt; q) &amp;&amp; !(q &lt; p)</code>.</P>
		<h4>10. <code>operator&lt;&lt;</code></h4>
		<p>A stream insertion operator is explicitly provided for <EM>shared_ptr</EM> since 
			the conversion operator may cause <EM>shared_ptr</EM> to be treated in stream 
			insertion contexts as if it were a <code>bool</code>.</p>
		<h4>11. Casts</h4>
		<p>Two cast functions, <code>static_pointer_cast</code> and <code>dynamic_pointer_cast</code>, 
			are provided for <EM>shared_ptr</EM>.</p>
		<P><code>static_pointer_cast</code> is useful when heterogeneous <EM>shared_ptr</EM>
			instances are temporarily stored in a container as <code>shared_ptr&lt;void&gt;</code>, 
			along with a corresponding function pointer or polymorphic function object 
			wrapper [<A href="#Gregor02">Gregor02</A>] that remembers the original type and 
			is able to use <code>static_pointer_cast</code> to obtain the original <EM>shared_ptr</EM>.</P>
		<P><code>dynamic_pointer_cast</code> is useful for passing <EM>shared_ptr</EM> instances 
			through a third-party library, then recognizing, and recovering, the original 
			value, as described in the original <code>dynamic_cast</code> rationale [<A href="#Stroustrup94">Stroustrup94</A>].</P>
		<P><code>reinterpret_cast</code> and <code>const_cast</code> equivalents have been 
			omitted since they have never been requested by users (although it's possible 
			to emulate a <code>reinterpret_pointer_cast</code> by using an intermediate <code>shared_ptr&lt;void&gt;</code>
			and a <code>static_pointer_cast</code>).</P>
		<P>The cast operations were originally named <code>shared_static_cast</code> and <code>shared_dynamic_cast</code>
			in the Boost implementation, but it soon became clear that other smart pointer 
			types can (and should) provide the same functionality, preferably in a generic 
			manner, and the functions were renamed to <code>*_pointer_cast</code> to 
			indicate wider applicability.</P>
		<h4>12. <code>get_deleter</code></h4>
		<p><code>get_deleter</code> is useful for libraries that create <EM>shared_ptr</EM> 
			instances for client code, and when the client passes a <EM>shared_ptr</EM> back, 
			need to determine whether that particular <EM>shared_ptr</EM> originated from 
			the library, and if so, need to access private data associated with the 
			instance that was stored in the deleter at creation.</p>
		<P>One example is a library that implements a predefined <EM>shared_ptr</EM>-based 
			interface. The library needs to interoperate with an existing infrastructure 
			that uses a different smart pointer for its resource management, and the <A href="http://www.boost.org/libs/smart_ptr/sp_techniques.html#another_sp">
				technique</A> described in [<A href="#Dimov03">Dimov03</A>] is used to wrap 
			the existing smart pointers with a <EM>shared_ptr</EM> "shell". When the 
			library receives a <EM>shared_ptr</EM> from the client, it can extract the 
			original wrapped smart pointer (if there is one) by using <code>get_deleter</code>.</P>
		<P>The <A href="http://www.boost.org/libs/python/">Boost.Python library</A> [<A href="#Abrahams02">Abrahams02</A>] 
			uses <code>get_deleter</code> to extract the original Python object from a <EM>shared_ptr</EM>.</P>
		<h3>C. weak_ptr</h3>
		<h4>1. Default Constructor</h4>
		<p>Default-constructed <EM>weak_ptr</EM> instances have a <code>use_count()</code> of 
			zero, and attempts to create a <EM>shared_ptr</EM> from such an instance will 
			fail with a <EM>bad_weak_ptr</EM> exception. This behavior supports some use 
			cases where a <EM>weak_ptr</EM> needs to be "two phase constructed", i.e. first 
			default-constructed, then initialized from a <EM>shared_ptr</EM> via 
			assignment. If a <EM>shared_ptr</EM> conversion is attempted before 
			initialization, an exception is the appropriate response. See, for example, the 
			"<A href="http://www.boost.org/libs/smart_ptr/sp_techniques.html#from_this"><EM>Obtaining 
					a <CODE>shared_ptr</CODE> to <CODE>this</CODE></EM></A>" technique in [<A href="#Dimov03">Dimov03</A>].</p>
		<h4>2. Converting Constructor</h4>
		<p>A converting constructor enables <code>weak_ptr&lt;Y&gt;</code> to be converted 
			to <code>weak_ptr&lt;T&gt;</code> when <code>Y*</code> is convertible to <code>T*</code>. 
			This is a standard "feature" of most smart pointer designs and would not 
			deserve mention except for the fact that in <EM>weak_ptr</EM>'s case it is easy 
			to produce an implementation with a subtle bug. When the source <EM>weak_ptr</EM>
			has expired, its stored pointer may refer to deallocated storage, its value may 
			be indeterminate, and the implicit conversion from <code>Y*</code> to <code>T*</code>
			may exhibit "observable" undefined behavior such as a core dump.</p>
		<P>Strictly speaking, this caveat applies to the copy constructor as well, but most 
			existing implementations allow an invalid pointer to be copied (and those that 
			don't can use <code>std::memcpy</code> to copy the pointer storage without 
			accessing its value). When <code>Y</code> inherits from <code>T</code> virtually, 
			however, most existing implementations will fail to convert an invalid pointer 
			of type <code>Y*</code> to <code>T*</code>.</P>
		<P>This constructor has been provided to support the useful <A href="http://www.boost.org/libs/smart_ptr/sp_techniques.html#extra_data">
				idiom</A> of using <code>std::map&lt; weak_ptr&lt;void&gt;, X &gt;</code> to 
			non-intrusively associate arbitrary data with existing <EM>shared_ptr</EM>-managed 
			objects.</P>
		<h4>3. <code>lock</code></h4>
		<p><EM>weak_ptr</EM> does not provide the usual smart pointer accessors <code>operator*</code>,
			<code>operator-&gt;</code>, or <code>get</code>. Any attempt to use their 
			return values would be inherently unsafe, as <EM>weak_ptr</EM>'s stored pointer 
			can be invalidated at any time. Instead, <EM>weak_ptr</EM> provides a member 
			function <code>lock</code> that returns a <EM>shared_ptr</EM>. The returned <EM>shared_ptr</EM>
			keeps the object alive, effectively locking it against deletion.</p>
		<P>The idiomatic way to access a <EM>weak_ptr</EM> is as shown below:</P>
		<pre>weak_ptr&lt;X&gt; target;

// ...

if(shared_ptr&lt;X&gt; px = target.lock())
{
  // use *px to fire at target
}
else
{
  // target lost (expired), acquire a new one
}
</pre>
		<h3>D. enable_shared_from_this</h3>
		<p>Experienced smart pointer users often need the ability to obtain a <EM>shared_ptr</EM>
			to <i>this</i> from within a member function. While the <A href="http://www.boost.org/libs/smart_ptr/sp_techniques.html#from_this">
				technique</A> described in [<A href="#Dimov03">Dimov03</A>] solves the 
			problem, this proposal provides direct support for this idiom via the <code>enable_shared_from_this</code>
			helper class template. Encapsulating the boilerplate code in a standard helper 
			has the additional benefit that users no longer need to manually initialize the 
			internal <EM>weak_ptr</EM> member; <EM>shared_ptr</EM> automatically recognizes 
			the <code>enable_shared_from_this</code> base class and performs the 
			initialization automatically.</p>
		<h3>E. Size and Performance</h3>
		<h4>1. <a name="Memory-footprint">Memory Footprint</a></h4>
		<p>In the Boost implementation, the size of <EM>shared_ptr</EM> (and <EM>weak_ptr</EM>) 
			is twice the size of a raw pointer. More precisely, <code>sizeof(shared_ptr&lt;T&gt;) 
				== sizeof(weak_ptr&lt;T&gt;) == sizeof(T*) + sizeof(C*)</code>, where <code>C</code>
			is a structure holding the reference counts and other information. This "twin 
			pointer" layout is typical for most existing reference counted smart pointers.</p>
		<P>The count structure <code>C</code> has the following members:</P>
		<UL>
			<LI>
				Virtual table pointer (<code>C</code>
			is polymorphic);
			<LI>
			Use count;
			<LI>
			Weak count;
			<LI>
			Mutex (for multithreaded builds);
			<LI>
			Original pointer passed to the constructor;
			<LI>
				Deleter.</LI></UL>
		<P>On a typical implementation where a pointer and a <code>long</code> are both 
			four bytes in size and no custom deleters are used, <code>sizeof(C)</code> is 
			20 in singlethreaded builds, 24 in multithreaded builds on Windows (the 
			implementation uses a custom spinlock-based mutex), and 44 on Linux using the 
			platform's <code>pthread_mutex_t</code>.</P>
		<P>It is possible to save four bytes when the deleter is an empty class (most 
			deleters are) by taking advantage of the empty base optimization, for example 
			by using a helper component such as <code><A href="http://www.boost.org/libs/utility/compressed_pair.htm">
					boost::compressed_pair</A></code> [<A href="#Boost00">Boost00</A>]. The 
			Boost implementation does not attempt to optimize away the deleter space in 
			order to minimize dependencies and maximize portability (<code>boost::shared_ptr</code>
			is a critical dependency for many Boost libraries and it is important for it to 
			work reliably on all supported platforms.)</P>
		<P>The mutex presents another target for platform-specific optimizations. On 
			Windows, we have been able to use a simple one-word spinlock instead of a 6 
			word <code>CRITICAL_SECTION</code>. The portable architecture of the 
			implementation that abstracts the mutex concept in a separate class prevents 
			further optimizations, like reusing the use count word as the spinlock, or 
			using the Windows API <code>InterlockedIncrement</code>, <code>InterlockedDecrement</code>, 
			and <code>InterlockedCompareExchange</code> primitives to attempt to eliminate 
			the mutex altogether. Nevertheless, we believe that such optimizations are 
			possible.</P>
		<P>The rest of the members of the count structure are a "necessary evil" as far as 
			size is concerned. The virtual table pointer is required for the polymorphic 
			behavior needed for destroying the original pointer using its original type, 
			and to support dynamic libraries on platforms such as Windows where the 
			application and the dynamic library can have their own incompatible versions of <code>
				::operator new</code> and <code>::operator delete</code>. The weak count 
			supports <EM>weak_ptr</EM>. The original pointer passed at construction time 
			needs to be remembered for <code>shared_ptr&lt;X&gt;</code> to be able to 
			correctly destroy the object when <code>X</code> is incomplete or <code>void</code>,
			<code>~X</code> is inaccessible, or <code>~X</code> is not virtual.</P>
		<P>An earlier, less featured, version of <code>boost::shared_ptr</code> used a 
			single <code>long</code> as <code>C</code>. The transition to the new version 
			having a much larger count structure went painlessly, and we registered no user 
			complaints.</P>
		<h4>2. Construction Performance</h4>
		<p>The Boost implementation allocates a reference count structure whenever a <EM>shared_ptr</EM>
			instance is constructed from a pointer, the typical case being:</p>
		<pre>shared_ptr&lt;X&gt; px(new X);</pre>
		<P>Note that in the common case there are two allocations being performed, an 
			object allocation (<code>new X</code>) and a count allocation.</P>
		<P>On a typical desktop machine (Athlon 1.4GHz running Windows XP), 1048576 (2<SUP>20</SUP>) 
			such statements take about 1.75 seconds, a more than adequate performance 
			considering that typical code rarely needs to repeatedly allocate so many 
			objects.</P>
		<P>We have also experimented with using a pool allocator for the count structure. 
			The same test is executed for about 1.15 seconds under the same implementation. 
			However, the additional step of reusing the same allocator for the object 
			allocation as well gives a result of about 0.78 seconds, with the likely 
			conclusion (also supported by [<A href="#Berger02">Berger02</A>]) that it would 
			be better to optimize the global <code>::operator new</code> allocator instead 
			of focusing on the internal allocations performed by <EM>shared_ptr</EM>.</P>
		<P>The source code used for the test is available as part of the Boost 
			implementation.</P>
		<h4>3. Copy Performance</h4>
		<p>In multi-threaded builds, the Boost implementation always synchronizes reference 
			count operations to make <EM>shared_ptr</EM> "as thread safe as an int", 
			consistent with the behavior of most standard libraries. This sometimes raises 
			performance concerns since in some cases users can guarantee that two <EM>shared_ptr</EM>
			instances that share ownership will never be accessed simultaneously from 
			different threads.</p>
		<P>The configuration described above is able to execute 8388608 (2<SUP>23</SUP>) <code>push_back</code>
			operations into a <code>std::vector&lt; shared_ptr&lt;int&gt; &gt;</code> (without 
			calling <code>reserve</code> first) in about 2.63 seconds in a single threaded 
			build, 5.44 seconds in a multi-threaded build. A factor of two increase seems 
			like a lot, but the difference rarely impacts real code, since it never needs 
			to repeatedly make so many <EM>shared_ptr</EM> copies.</P>
		<P>The source code used for the test is available as part of the Boost 
			implementation.</P>
		<h3>F. Alternatives</h3>
		<h4>1. Policy Based Smart Pointers</h4>
		<p>A policy-based smart pointer (PBSP) design, popularized by Andrei Alexandrescu [<a href="#Alexandrescu01">Alexandrescu01</a>],
			could provide all of the features in the current proposal plus could be 
			user-customizable to offer many other variations on the general smart pointer 
			theme.</p>
		<p>As attractive as PBSP might be, the authors of the current proposal believe:</p>
		<ul>
			<li>
			There is no currently available smart pointer design suitable for 
			standardization. Several Boost developers, with guidance from Andrei 
			Alexandrescu, are working on a possible Boost PBSP library, but it will be 
			several years at best before it can be considered mature.
			<li>
				Because parameterization discourages users and some PBSP designs require an 
				uncomfortably large number of template parameters, the best choice for 
				parameterization would benefit greatly from features not currently a part of 
				C++, particularly named template parameters and/or typedef templates.</li>
		</ul>
		<p>If and when a policy-based smart pointer design matures to the point where it is 
			suitable for standardization, a <i>std::shared_ptr</i> typedef template or 
			equivalent could be provided which delivers the same interface and semantics as 
			the current proposal. The interface and semantics of <i>std::shared_ptr</i> have 
			been refined over the years as the best choice for general shared-ownership 
			smart pointer use, including interlibrary communication. Thus any future PBSP 
			would almost certainly supply these common needs as the default policies. That 
			means that implementing a future version of <i>std::shared_ptr</i> as some form 
			of wrapper around a PBSP would always be an option should a PBSP become part of 
			some future standard.</p>
		<h4>2. Garbage Collection</h4>
		<p>The detailed rationale for not providing automatic garbage collection as the 
			default memory management technique for C++ is given by [<a href="#Stroustrup94a">Stroustrup94a</a>], 
			who states that "Optional garbage collection is, I think, the right approach 
			for C++".</p>
		<p>Because the current proposal is for a purely library solution, it is 
			complementary rather than competitive with any future proposal to add optional 
			garbage collection as a built-in feature of the language itself.</p>
		<P>The Boost implementation includes an experimental collector [<A href="#Boost03b">Boost03b</A>] 
			based on the algorithm described in [<A href="#Christopher84">Christopher84</A>] 
			that can be used to detect and free unreachable objects with cyclic <EM>shared_ptr</EM>
			references. We have only limited experience with this feature, and it is not 
			part of this proposal.</P>
		<h2>IV. Proposed Text</h2>
		<h3>A. Additions to header &lt;memory&gt; synopsis (20.4)</h3>
		<pre>  class bad_weak_ptr;

  template&lt;class T&gt; class shared_ptr;

  template&lt;class T, class U&gt;
    bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

  template&lt;class T, class U&gt;
    bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

  template&lt;class T, class U&gt;
    bool operator&lt;(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

  template&lt;class T&gt;
    void swap(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b);

  template&lt;class T, class U&gt;
    shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);

  template&lt;class T, class U&gt;
    shared_ptr&lt;T&gt; dynamic_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);

  template&lt;class E, class T, class Y&gt;
    basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (basic_ostream&lt;E, T&gt; &amp; os, shared_ptr&lt;Y&gt; const &amp; p);

  template&lt;class D, class T&gt;
    D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);

  template&lt;class T&gt; class weak_ptr;

  template&lt;class T, class U&gt;
    bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);

  template&lt;class T&gt;
    void swap</A>(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b);

  template&lt;class T&gt; class enable_shared_from_this;
</pre>
		<h3>B. Class <code>bad_weak_ptr</code></h3>
		<pre>    namespace std {
      class bad_weak_ptr: public exception
      {
      public:
        bad_weak_ptr();
      };
    }
</pre>
		<p>An exception of type <code>bad_weak_ptr</code> is thrown by the <code>shared_ptr</code>
			constructor taking a <code>weak_ptr</code>.</p>
		<pre>    bad_weak_ptr();
</pre>
		<p><b>Postconditions:</b> <code>what()</code> returns <code>"std::bad_weak_ptr"</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<h3>C. Class template <code>shared_ptr</code></h3>
		<p>The <code>shared_ptr</code> class template stores a pointer, usually obtained 
			via <code>new</code>. <code>shared_ptr</code> implements semantics of shared 
			ownership; the last remaining owner of the pointer is responsible for 
			destroying the object, or otherwise releasing the resources associated with the 
			stored pointer.</p>
		<pre>    namespace std {
      template&lt;class T&gt; class shared_ptr {
      public:
        typedef T element_type;

        <em>// constructors</em>
        shared_ptr();
        template&lt;class Y&gt; explicit shared_ptr(Y * p);
        template&lt;class Y, class D&gt; shared_ptr(Y * p, D d);
        shared_ptr(shared_ptr const &amp; r);
        template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r);
        template&lt;class Y&gt; explicit shared_ptr(weak_ptr&lt;Y&gt; const &amp; r);
        template&lt;class Y&gt; explicit shared_ptr(auto_ptr&lt;Y&gt; &amp; r);

        <em>// destructor</em>
        ~shared_ptr();

        <em>// assignment</em>
        shared_ptr &amp; operator=(shared_ptr const &amp; r);
        template&lt;class Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r);
        template&lt;class Y&gt; shared_ptr &amp; operator=(auto_ptr&lt;Y&gt; &amp; r);

        <em>// modifiers</em>
        void swap(shared_ptr &amp; r);
        void reset();
        template&lt;class Y&gt; void reset(Y * p);
        template&lt;class Y, class D&gt; void reset(Y * p, D d);

        <em>// observers</em>
        T * get() const;
        T &amp; operator*() const;
        T * operator-&gt;() const;
        long use_count() const;
        bool unique() const;
        operator <em>unspecified-bool-type</em>() const;
      };

      <em>// comparison</em>
      template&lt;class T, class U&gt;
        bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

      template&lt;class T, class U&gt;
        bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

      template&lt;class T, class U&gt;
        bool operator&lt;(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);

      <em>// other operators</em>
      template&lt;class E, class T, class Y&gt;
        basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (basic_ostream&lt;E, T&gt; &amp; os, shared_ptr&lt;Y&gt; const &amp; p);

      <em>// specialized algorithms</em>
      template&lt;class T&gt; void swap(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b);

      <em>// casts</em>
      template&lt;class T, class U&gt;
        shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);

      template&lt;class T, class U&gt;
        shared_ptr&lt;T&gt; dynamic_pointer_cast</A>(shared_ptr&lt;U&gt; const &amp; r);

      <em>// get_deleter</em>
      template&lt;class D, class T&gt;
        D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);
    }
</pre>
		<p><code>shared_ptr</code> is <code>CopyConstructible</code>, <code>Assignable</code>, 
			and <code>LessThanComparable</code>, allowing its use in standard containers. <code>
				shared_ptr</code> is convertible to <code>bool</code>, allowing its use in 
			boolean expressions and declarations in conditions.</p>
		<p>[<em>Example:</em></p>
		<pre>    if(shared_ptr&lt;X&gt; px = dynamic_pointer_cast&lt;X&gt;(py))
    {
      // do something with px
    }
</pre>
		<p><em>end example.</em>]</p>
		<h4><code>shared_ptr</code> constructors</h4>
		<pre>    shared_ptr();
</pre>
		<p><b>Effects:</b> Constructs an <EM>empty</EM> <code>shared_ptr</code>.</p>
		<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    template&lt;class Y&gt; explicit shared_ptr(Y * p);
</pre>
		<p><b>Requires:</b> <code>p</code> must be convertible to <code>T *</code>. <code>Y</code>
			must be a complete type. The expression <code>delete p</code> must be 
			well-formed, must not invoke undefined behavior, and must not throw exceptions.
		</p>
		<p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <EM>owns</EM> the 
			pointer <code>p</code>.</p>
		<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
		<p><b>Throws:</b> <code>bad_alloc</code> or an implementation-defined exception 
			when a resource other than memory could not be obtained.</p>
		<p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is 
			called.</p>
		<pre>    template&lt;class Y, class D&gt; shared_ptr(Y * p, D d);
</pre>
		<p><b>Requires:</b> <code>p</code> must be convertible to <code>T *</code>. <code>D</code>
			must be <code>CopyConstructible</code>. The copy constructor and destructor of <code>
				D</code> must not throw. The expression <code>d(p)</code> must be 
			well-formed, must not invoke undefined behavior, and must not throw exceptions.
		</p>
		<p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <EM>owns</EM> the 
			pointer <code>p</code> and the deleter <code>d</code>.</p>
		<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
		<p><b>Throws:</b> <code>bad_alloc</code> or an implementation-defined exception 
			when a resource other than memory could not be obtained.</p>
		<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>
		<pre>    shared_ptr(shared_ptr const &amp; r);
    template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r);
</pre>
		<p><b>Effects:</b> If <code>r</code> is <EM>empty</EM>, constructs an <EM>empty</EM>
			<code>shared_ptr</code>; otherwise, constructs a <code>shared_ptr</code> that <EM>shares 
				ownership</EM> with <code>r</code>.</p>
		<p><b>Postconditions:</b> <code>get() == r.get() &amp;&amp; use_count() == 
				r.use_count()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    template&lt;class Y&gt; explicit shared_ptr(weak_ptr&lt;Y&gt; const &amp; r);
</pre>
		<p><b>Effects:</b> If <code>r</code> is <EM>empty</EM>, constructs an <EM>empty</EM>
			<code>shared_ptr</code>; otherwise, constructs a <code>shared_ptr</code> that <EM>shares 
				ownership</EM> with <code>r</code> and stores a copy of the pointer stored 
			in <code>r</code>.</p>
		<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
		<p><b>Throws:</b> <code>bad_weak_ptr</code> when <code>r.use_count() == 0</code>.</p>
		<p><b>Exception safety:</b> If an exception is thrown, the constructor has no 
			effect.</p>
		<pre>    template&lt;class Y&gt; shared_ptr(auto_ptr&lt;Y&gt; &amp; r);
</pre>
		<p><b>Requires:</b> <code>r.release()</code> must be convertible to <code>T *</code>.
			<code>Y</code> must be a complete type. The expression <code>delete r.release()</code>
			must be well-formed, must not invoke undefined behavior, and must not throw 
			exceptions.
		</p>
		<P><B>Effects:</B> Constructs a <code>shared_ptr</code> that stores and <em>owns</em>
			<code>r.release()</code>.</P>
		<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
		<p><b>Throws:</b> <code>bad_alloc</code> or an implementation-defined exception 
			when a resource other than memory could not be obtained.</p>
		<P><B>Exception safety:</B> If an exception is thrown, the constructor has no 
			effect.</P>
		<h4><code>shared_ptr</code> destructor</h4>
		<pre>    ~shared_ptr();
</pre>
		<P><B>Effects:</B></P>
		<UL>
			<LI>
				If <code>*this</code> is <EM>empty</EM>, or <EM>shares ownership</EM> with 
				another <code>shared_ptr</code> instance (<code>use_count() &gt; 1</code>), 
			there are no side effects.
			<LI>
				Otherwise, if <code>*this</code> <EM>owns</EM> a pointer <code>p</code> and a 
				deleter <code>d</code>, <code>d(p)</code>
			is called.
			<LI>
				Otherwise, <code>*this</code> <EM>owns</EM> a pointer <code>p</code>, and <code>delete 
					p</code> is called.</LI></UL>
		<P><B>Throws:</B> nothing.</P>
		<h4><code>shared_ptr</code> assignment</h4>
		<pre>    shared_ptr &amp; operator=(shared_ptr const &amp; r);
    template&lt;class Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r);
    template&lt;class Y&gt; shared_ptr &amp; operator=(auto_ptr&lt;Y&gt; &amp; r);
</pre>
		<P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P>
		<P><B>Returns:</B> <code>*this</code>.</P>
		<P><B>Notes:</B> The use count updates caused by the temporary object construction 
			and destruction are not considered observable side effects, and the 
			implementation is free to meet the effects (and the implied guarantees) via 
			different means, without creating a temporary. In particular, in the example:</P>
		<pre>  shared_ptr&lt;int&gt; p(new int);
  shared_ptr&lt;void&gt; q(p);
  p = p;
  q = p;
</pre>
		<p>both assignments may be no-ops.</p>
		<h4><code>shared_ptr</code> modifiers</h4>
		<pre>    void swap(shared_ptr &amp; r);
</pre>
		<p><b>Effects:</b> Exchanges the contents of <code>*this</code> and <code>r</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    void reset();
</pre>
		<P><B>Effects:</B> Equivalent to <code>shared_ptr().swap(*this)</code>.</P>
		<pre>    template&lt;class Y&gt; void reset(Y * p);
</pre>
		<P><B>Effects:</B> Equivalent to <code>shared_ptr(p).swap(*this)</code>.</P>
		<pre>    template&lt;class Y, class D&gt; void reset(Y * p, D d);
</pre>
		<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
		<h4><code>shared_ptr</code> observers</h4>
		<pre>    T * get() const;
</pre>
		<p><b>Returns:</b> the stored pointer.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    T &amp; operator*() const;
</pre>
		<p><b>Requires:</b> <code>get() != 0</code>.</p>
		<p><b>Returns:</b> <code>*get()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<p><b>Notes:</b> When <code>T</code> is <code>void</code>, the return type of this 
			member function is unspecified, and an attempt to instantiate it renders the 
			program ill-formed.</p>
		<pre>    T * operator-&gt;() const;
</pre>
		<p><b>Requires:</b> <code>get() != 0</code>.</p>
		<p><b>Returns:</b> <code>get()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    long use_count() const;
</pre>
		<p><b>Returns:</b> the number of <code>shared_ptr</code> objects, <code>*this</code>
			included, that <i>share ownership</i> with <code>*this</code>, or an 
			unspecified nonnegative value when <code>*this</code> is <EM>empty</EM>.</p>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only 
			for debugging and testing purposes, not for production code.</P>
		<pre>    bool unique() const;
</pre>
		<p><b>Returns:</b> <code>use_count() == 1</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>. 
			If you are using <code>unique()</code> to implement copy on write, do not rely 
			on a specific value when <code>get() == 0</code>.</P>
		<pre>    operator <em>unspecified-bool-type</em> () const;
</pre>
		<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is 
			equivalent to <code>get() != 0</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be 
			used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>. 
			The actual target type is typically a pointer to a member function, avoiding 
			many of the implicit conversion pitfalls.</P>
		<h4><code>shared_ptr</code> comparison</h4>
		<pre>    template&lt;class T, class U&gt;
      bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);
</pre>
		<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    template&lt;class T, class U&gt;
      bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);
</pre>
		<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    template&lt;class T, class U&gt;
      bool operator&lt;(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b);
</pre>
		<p><b>Returns:</b> an unspecified value such that</p>
		<UL>
			<LI>
				<code>operator&lt;</code> is a strict weak ordering as described in section 
				25.3 <code>[lib.alg.sorting]</code>;
			<LI>
				under the equivalence relation defined by <code>operator&lt;</code>, <code>!(a &lt; 
					b) &amp;&amp; !(b &lt; a)</code>, two <code>shared_ptr</code> instances are 
				equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> Allows <code>shared_ptr</code> objects to be used as keys in 
			associative containers.</P>
		<h4><code>shared_ptr</code> operators</h4>
		<pre>    template&lt;class E, class T, class Y&gt;
      basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (basic_ostream&lt;E, T&gt; &amp; os, shared_ptr&lt;Y&gt; const &amp; p);
</pre>
		<p><STRONG>Effects:</STRONG> <code>os &lt;&lt; p.get();</code>.</p>
		<P><B>Returns:</B> <code>os</code>.</P>
		<h4><code>shared_ptr</code> specialized algorithms</h4>
		<pre>    template&lt;class T&gt;
      void swap(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b);
</pre>
		<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
		<P><B>Throws:</B> nothing.</P>
		<h4><code>shared_ptr</code> casts</h4>
		<pre>    template&lt;class T, class U&gt;
      shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);
</pre>
		<P><STRONG>Requires:</STRONG> The expression <code>static_cast&lt;T*&gt;(r.get())</code>
			must be well-formed.</P>
		<P><B>Returns:</B> If <code>r</code> is <em>empty</em>, an <em>empty</em> <code>shared_ptr&lt;T&gt;</code>; 
			otherwise, a <code>shared_ptr&lt;T&gt;</code> object that stores <code>static_cast&lt;T*&gt;(r.get())</code>
			and <em>shares ownership</em> with <code>r</code>.</P>
		<P><B>Throws:</B> nothing.</P>
		<P><B>Notes:</B> the seemingly equivalent expression</P>
		<p><code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code></p>
		<p>will eventually result in undefined behavior, attempting to delete the same 
			object twice.</p>
		<pre>    template&lt;class T, class U&gt;
      shared_ptr&lt;T&gt; dynamic_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);
</pre>
		<P><STRONG>Requires:</STRONG> The expression <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE>
			must be well-formed and its behavior defined.</P>
		<P><B>Returns:</B></P>
		<UL>
			<LI>
				When <CODE>dynamic_cast&lt;T*&gt;(r.get())</CODE> returns a nonzero value, a <code>shared_ptr&lt;T&gt;</code>
				object that stores a copy of it and <em>shares ownership</em> with <code>r</code>;
			<LI>
				Otherwise, an <em>empty</em> <code>shared_ptr&lt;T&gt;</code> object.</LI></UL>
		<P><B>Throws:</B> nothing.</P>
		<P><B>Notes:</B> the seemingly equivalent expression</P>
		<P><CODE>shared_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</CODE></P>
		<P>will eventually result in undefined behavior, attempting to delete the same 
			object twice.</P>
		<h4>get_deleter</h4>
		<pre>    template&lt;class D, class T&gt;
      D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);
</pre>
		<P><B>Returns:</B> If <code>*this</code> <EM>owns</EM> a deleter <code>d</code> of 
			type cv-unqualified <code>D</code>, returns <code>&amp;d</code>; otherwise 
			returns 0.</P>
		<P><B>Throws:</B> nothing.</P>
		<h3>D. Class template <code>weak_ptr</code></h3>
		<p>The <code>weak_ptr</code> class template stores a "weak reference" to an object 
			that's already managed by a <code>shared_ptr</code>. To access the object, a <code>weak_ptr</code>
			can be converted to a <code>shared_ptr</code> using the member function <code>lock</code>.</p>
		<pre>    namespace std {
      template&lt;class T&gt; class weak_ptr {

      public:
        typedef T element_type;

        <em>// constructors</em>
        weak_ptr();
        template&lt;class Y&gt; weak_ptr(shared_ptr&lt;Y&gt; const &amp; r);
        weak_ptr(weak_ptr const &amp; r);
        template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);

        <em>// destructor</em>
        ~weak_ptr();

        <em>// assignment</em>
        weak_ptr &amp; operator=(weak_ptr const &amp; r);
        template&lt;class Y&gt; weak_ptr &amp; operator=(weak_ptr&lt;Y&gt; const &amp; r);
        template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r);

        <em>// modifiers</em>
        void swap(weak_ptr &amp; r);
        void reset();

        <em>// observers</em>
        long use_count() const;
        bool expired() const;
        shared_ptr&lt;T&gt; lock() const;
      };

      <em>// comparison</em>
      template&lt;class T, class U&gt;
        bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);

      <em>// specialized algorithms</em>
      template&lt;class T&gt;
        void swap(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b);
    }
</pre>
		<p><code>weak_ptr</code> is <code>CopyConstructible</code>, <code>Assignable</code>, 
			and <code>LessThanComparable</code>, allowing its use in standard containers.</p>
		<h4><code>weak_ptr</code> constructors</h4>
		<pre>    weak_ptr();
</pre>
		<p><b>Effects:</b> Constructs an <EM>empty</EM> <code>weak_ptr</code>.</p>
		<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    template&lt;class Y&gt; weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r);
    weak_ptr(weak_ptr const &amp; r);
    template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);
</pre>
		<p><b>Effects:</b> If <code>r</code> is <EM>empty</EM>, constructs an <EM>empty</EM>
			<code>weak_ptr</code>; otherwise, constructs a <code>weak_ptr</code> that <EM>shares 
				ownership</EM> with <code>r</code> and stores a copy of the pointer stored 
			in <code>r</code>.</p>
		<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<h4><code>weak_ptr</code> destructor</h4>
		<pre>    ~weak_ptr();
</pre>
		<P><B>Effects:</B> Destroys this <code>weak_ptr</code> but has no effect on the 
			object its stored pointer points to.</P>
		<P><B>Throws:</B> nothing.</P>
		<h4><code>weak_ptr</code> assignment</h4>
		<pre>    weak_ptr &amp; operator=(weak_ptr const &amp; r);
    template&lt;class Y&gt; weak_ptr &amp; operator=(weak_ptr&lt;Y&gt; const &amp; r);
    template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r);
</pre>
		<P><B>Effects:</B> Equivalent to <code>weak_ptr(r).swap(*this)</code>.</P>
		<P><B>Throws:</B> nothing.</P>
		<P><B>Notes:</B> The implementation is free to meet the effects (and the implied 
			guarantees) via different means, without creating a temporary.</P>
		<h4><code>weak_ptr</code> modifiers</h4>
		<pre>    void swap(weak_ptr &amp; r);
</pre>
		<p><b>Effects:</b> Exchanges the contents of <code>*this</code> and <code>r</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<pre>    void reset();
</pre>
		<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
		<h4><code>weak_ptr</code> observers</h4>
		<pre>    long use_count() const;
</pre>
		<p><b>Returns:</b> if <code>*this</code> is <EM>empty</EM>, an unspecified 
			nonnegative value; otherwise, the number of <code>shared_ptr</code> instances 
			that <EM>share ownership</EM> with <code>*this</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only 
			for debugging and testing purposes, not for production code.</P>
		<pre>    bool expired() const;
</pre>
		<p><b>Returns:</b> <code>use_count() == 0</code>.</p>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
		<pre>    shared_ptr&lt;T&gt; lock() const;
</pre>
		<P><B>Returns:</B> <code>expired()? shared_ptr&lt;T&gt;(): shared_ptr&lt;T&gt;(*this)</code>.</P>
		<P><B>Throws:</B> nothing.</P>
		<h4><code>weak_ptr</code> comparison</h4>
		<pre>    template&lt;class T, class U&gt;
      bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);
</pre>
		<p><b>Returns:</b> an unspecified value such that</p>
		<UL>
			<LI>
				<code>operator&lt;</code> is a strict weak ordering as described in section 
				25.3 <code>[lib.alg.sorting]</code>;
			<LI>
				under the equivalence relation defined by <code>operator&lt;</code>, <code>!(a &lt; 
					b) &amp;&amp; !(b &lt; a)</code>, two <code>weak_ptr</code> instances are 
				equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
		<p><b>Throws:</b> nothing.</p>
		<P><B>Notes:</B> Allows <code>weak_ptr</code> objects to be used as keys in 
			associative containers.</P>
		<h4><code>weak_ptr</code> specialized algorithms</h4>
		<pre>    template&lt;class T&gt;
      void swap(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b)
</pre>
		<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
		<P><B>Throws:</B> nothing.</P>
		<h3>E. Class template <code>enable_shared_from_this</code></h3>
		<p>A class can derive from the <code>enable_shared_from_this</code> class template, 
			passing itself as a template parameter, to inherit the <code>shared_from_this</code>
			member functions that obtain a <EM>shared_ptr</EM> instance pointing to <code>this</code>.</p>
		<pre>    namespace std {
      template&lt;class T&gt; class enable_shared_from_this {
      public:
        shared_ptr&lt;T&gt; shared_from_this();
        shared_ptr&lt;T const&gt; shared_from_this() const;
      };
    }
</pre>
		<pre>    template&lt;class T&gt; shared_ptr&lt;T&gt; 
      enable_shared_from_this&lt;T&gt;::shared_from_this();
    template&lt;class T&gt; shared_ptr&lt;T const&gt; 
      enable_shared_from_this&lt;T&gt;::shared_from_this() const;
</pre>
		<p><b>Requires:</b> <code>enable_shared_from_this&lt;T&gt;</code> must be an 
			accessible base class of <code>T</code>. <code>*this</code> must be a subobject 
			of an instance <code>t</code> of type <code>T</code> . There must exist at 
			least one <code>shared_ptr</code> instance <code>p</code> that <EM>owns</EM> <code>&amp;t</code>.
		</p>
		<p><b>Returns:</b> A <code>shared_ptr&lt;T&gt;</code> instance <code>r</code> that <EM>shares 
				ownership with</EM> <code>p</code>.
		</p>
		<p><b>Postconditions:</b> <code>r.get() == this</code>.
		</p>
		<h2>V. References</h2>
		<p>[<a name="Abrahams02">Abrahams02</a>] Dave Abrahams et al, <i>Boost.Python library 
				documentation</i>, October 2002. Available online at <A href="http://www.boost.org/libs/python/">
				http://www.boost.org/libs/python/</A></p>
		<p>[<a name="Alexandrescu01">Alexandrescu01</a>] Andrei Alexandrescu, <i><a href="http://www.awl.com/cseng/titles/0-201-70431-5">
					Modern C++ Design</a></i>, Addison Wesley, ISBN 0-201-70431-5.</p>
		<p>[<a name="Berger02">Berger02</a>] Emery D. Berger, Benjamin G. Zorn, Kathryn S. 
			McKinley, <i>Reconsidering Custom Memory Allocation</i>, ACM SIGPLAN Notices, 
			Vol. 37, Issue 11, November 2002. Available online at <A href="ftp://ftp.cs.utexas.edu/pub/emery/papers/reconsidering-custom.pdf">
				ftp://ftp.cs.utexas.edu/pub/emery/papers/reconsidering-custom.pdf</A></p>
		<p>[<a name="Boehm02">Boehm02</a>] Hans-J. Boehm, <i>Destructors, Finalizers, and 
				Synchronization</i>, HP Labs Technical Report HPL-2002-335, December 2002. 
			Available online at <a href="http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html">
				http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html</a></p>
		<p>[<a name="Boost00">Boost00</a>] Boost compressed_pair utility component 
			documentation. Available online at <a href="http://www.boost.org/libs/utility/compressed_pair.htm">
				http://www.boost.org/libs/utility/compressed_pair.htm</a></p>
		<p>[<a name="Boost03a">Boost03a</a>] Boost Smart Pointer Library, source file <em>sp_debug_hooks.cpp</em>. 
			Available online at <a href="http://www.boost.org/libs/smart_ptr/src/sp_debug_hooks.cpp">
				http://www.boost.org/libs/smart_ptr/src/sp_debug_hooks.cpp</a></p>
		<p>[<a name="Boost03b">Boost03b</a>] Boost Smart Pointer Library, source file <em>sp_collector.cpp</em>. 
			Available online at <a href="http://www.boost.org/libs/smart_ptr/src/sp_collector.cpp">
				http://www.boost.org/libs/smart_ptr/src/sp_collector.cpp</a></p>
		<p>[<a name="Christopher84">Christopher84</a>] Thomas W. Christopher, <i>Reference 
				Count Garbage Collection</i>, Software - Practice and Experience, Vol. 
			14(6), pp. 503-507, June 1984.</p>
		<p>[<a name="Colvin94">Colvin94</a>] Gregory Colvin, <i>Exception Safe Smart Pointers</i>, 
			C++ committee document N0555=94-168, July 1994. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
				http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf</a></p>
		<p>[<a name="Dimov02">Dimov02</a>] Peter Dimov, Howard E. Hinnant, Dave Abrahams, <i>The 
				Forwarding Problem: Arguments</i>, C++ committee document N1385=02-0043, 
			September 2002. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">
				http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm</a></p>
		<p>[<a name="Dimov03">Dimov03</a>] Peter Dimov, <i>Smart Pointer Programming Techniques</i>, 
			March 2003. Available online at <a href="http://www.boost.org/libs/smart_ptr/sp_techniques.html">
				http://www.boost.org/libs/smart_ptr/sp_techniques.html</a></p>
		<p>[<a name="Ellis94">Ellis94</a>] John R. Ellis and David L. Detlefs, <i>Safe, 
				Efficient Garbage Collection for C++</i>, Usenix Proceedings, February 
			1994. This paper includes an extensive discussion of weak pointers and an 
			extensive bibliography. Available online at <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
				http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a</a></p>
		<p>[<a name="Google03">Google03</a>] Searching <a href="http://www.google.com">www.google.com</a>
			for "reference counted smart pointer" yields 2,400 entries. Anyone doubting 
			that shared-ownership smart pointers have been reinvented a large number of 
			times should read a random selection of these entries.</p>
		<p>[<a name="Gregor02">Gregor02</a>] Douglas Gregor, <em>A Proposal to add a 
				Polymorphic Function Object Wrapper to the Standard Library</em>, C++ 
			committee document N1402=02-0060, October 2002. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.htm">
				http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.htm</a></p>
		<p>[<a name="Hinnant02">Hinnant02</a>] Howard E. Hinnant, Peter Dimov, and Dave 
			Abrahams, <em>A Proposal to Add Move Semantics Support to the C++ Language</em>, 
			C++ committee document N1377=02-0035, September 2002. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
				http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm</a></p>
		<p>[<a name="Lakos96">Lakos96</a>] John Lakos, <i><a href="http://www.awl.com/cseng/titles/0-201-63362-0/">
					Large-Scale C++ Software Design</a></i>, section 9.2.2, page 637, 
			Addison-Wesley, July 1996, ISBN 0-201-63362-0.</p>
		<p>[<a name="Meyers01">Meyers01</a>] Scott Meyers, <i><a href="http://www.awl.com/cseng/titles/0-201-74962-9/">
					Effective STL</a></i>, page 39, Addison-Wesley, June 2001, ISBN 
			0-201-74962-9.</p>
		<p>[<a name="Stroustrup94">Stroustrup94</a>] Bjarne Stroustrup, <i><A href="http://www.research.att.com/~bs/dne.html">
					The Design and Evolution of C++</A></i>, section 14.2.1, page 307, 
			Addison Wesley, ISBN 0-201-54330-3, March 1994.</p>
		<p>[<a name="Stroustrup94a">Stroustrup94a</a>] Bjarne Stroustrup, <i><A href="http://www.research.att.com/~bs/dne.html">
					The Design and Evolution of C++</A></i>, section 10.7.1, page 220, 
			Addison Wesley, ISBN 0-201-54330-3, March 1994, with quote confirmed via 
			private email, February, 2003.</p>
		<p>&nbsp;</p>
	</body>
</html>
