|
Boost-Commit : |
From: srajko_at_[hidden]
Date: 2007-07-06 16:54:01
Author: srajko
Date: 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
New Revision: 7379
URL: http://svn.boost.org/trac/boost/changeset/7379
Log:
convert all class template reference, hyperlinks not all converted yet.
Text files modified:
sandbox/boost_docs/trunk/libs/smart_ptr/doc/intrusive_ptr.qbk | 389 ++++++++++++++++++++++
sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_array.qbk | 40 +
sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_ptr.qbk | 194 ++++++++++
sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_array.qbk | 175 +++++++++
sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_ptr.qbk | 703 +++++++++++++++++++++++++++++++++++++++
sandbox/boost_docs/trunk/libs/smart_ptr/doc/smart_ptr.qbk | 2
sandbox/boost_docs/trunk/libs/smart_ptr/doc/weak_ptr.qbk | 268 +++++++++++++++
7 files changed, 1751 insertions(+), 20 deletions(-)
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/intrusive_ptr.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/intrusive_ptr.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/intrusive_ptr.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,2 +1,389 @@
-[section:intrusive_ptr intrusive_ptr]
+[section:intrusive_ptr intrusive_ptr class template]
+
+[section Introduction]
+
+The [*intrusive_ptr] class template stores a pointer to an object with an embedded reference count. Every new [*intrusive_ptr] instance increments the reference count by using an unqualified call to the function intrusive_ptr_add_ref, passing it the pointer as an argument. Similarly, when an intrusive_ptr is destroyed, it calls intrusive_ptr_release; this function is responsible for destroying the object when its reference count drops to zero. The user is expected to provide suitable definitions of these two functions. On compilers that support argument-dependent lookup, intrusive_ptr_add_ref and intrusive_ptr_release should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace boost.
+
+The class template is parameterized on [*T], the type of the object pointed to. intrusive_ptr<T> can be implicitly converted to intrusive_ptr<U> whenever T* can be implicitly converted to U*.
+
+The main reasons to use intrusive_ptr are:
+* Some existing frameworks or OSes provide objects with embedded reference counts;
+* The memory footprint of intrusive_ptr is the same as the corresponding raw pointer;
+* intrusive_ptr<T> can be constructed from an arbitrary raw pointer of type T *.
+
+As a general rule, if it isn't obvious whether intrusive_ptr better fits your needs than shared_ptr, try a shared_ptr-based design first.
+
+[endsect]
+
+[section Synopsis]
+
+ namespace boost {
+
+ template<class T> class intrusive_ptr {
+
+ public:
+
+ typedef T [@#element_type element_type];
+
+ [@#constructors intrusive_ptr](); // never throws
+ [@#constructors intrusive_ptr](T * p, bool add_ref = true);
+
+ [@#constructors intrusive_ptr](intrusive_ptr const & r);
+ template<class Y> [@#constructors intrusive_ptr](intrusive_ptr<Y> const & r);
+
+ [@#destructor ~intrusive_ptr]();
+
+ intrusive_ptr & [@#assignment operator=](intrusive_ptr const & r);
+ template<class Y> intrusive_ptr & [@#assignment operator=](intrusive_ptr<Y> const & r);
+ intrusive_ptr & [@#assignment operator=](T * r);
+ void __reset__(T * r);
+
+ T & [@#indirection operator*]() const; // never throws
+ T * [@#indirection operator->]() const; // never throws
+ T * [@#get get]() const; // never throws
+
+ operator [@#conversions ['unspecified-bool-type]]() const; // never throws
+
+ void [@#swap swap](intrusive_ptr & b); // never throws
+ };
+
+ template<class T, class U>
+ bool [@#comparison operator==](intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+ template<class T, class U>
+ bool [@#comparison operator!=](intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+ template<class T>
+ bool [@#comparison operator==](intrusive_ptr<T> const & a, T * b); // never throws
+
+ template<class T>
+ bool [@#comparison operator!=](intrusive_ptr<T> const & a, T * b); // never throws
+
+ template<class T>
+ bool [@#comparison operator==](T * a, intrusive_ptr<T> const & b); // never throws
+
+ template<class T>
+ bool [@#comparison operator!=](T * a, intrusive_ptr<T> const & b); // never throws
+
+ template<class T, class U>
+ bool [@#comparison operator<](intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+ template<class T> void [@#free-swap swap](intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
+
+ template<class T> T * [@#get_pointer get_pointer](intrusive_ptr<T> const & p); // never throws
+
+ template<class T, class U>
+ intrusive_ptr<T> [@#static_pointer_cast static_pointer_cast](intrusive_ptr<U> const & r); // never throws
+
+ template<class T, class U>
+ intrusive_ptr<T> [@#const_pointer_cast const_pointer_cast](intrusive_ptr<U> const & r); // never throws
+
+ template<class T, class U>
+ intrusive_ptr<T> [@#dynamic_pointer_cast dynamic_pointer_cast](intrusive_ptr<U> const & r); // never throws
+
+ template<class E, class T, class Y>
+ std::basic_ostream<E, T> & [@#insertion-operator operator<<] (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
+
+ }
+
+[endsect]
+
+[section Members]
+
+[heading element_type]
+
+ typedef T element_type;
+
+[:
+
+Provides the type of the template parameter T.
+]
+
+[heading constructors]
+
+ intrusive_ptr(); // never throws
+
+[:
+
+[*Postconditions:] [^get() == 0].
+
+[*Throws:] nothing.
+]
+
+ intrusive_ptr(T * p, bool add_ref = true);
+
+[:
+
+[*Effects:] [^if(p != 0 && add_ref) intrusive_ptr_add_ref(p);].
+
+[*Postconditions:] [^get() == p].
+]
+
+
+ intrusive_ptr(intrusive_ptr const & r);
+ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
+
+[:
+
+[*Effects:] [^if(r.get() != 0) intrusive_ptr_add_ref(r.get());].
+
+[*Postconditions:] [^get() == r.get()].
+
+[heading destructor]
+
+ ~intrusive_ptr();
+
+[:
+
+[*Effects:] [^if(get() != 0) intrusive_ptr_release(get());].
+]
+
+[heading assignment]
+
+ intrusive_ptr & operator=(intrusive_ptr const & r);
+ template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
+ intrusive_ptr & operator=(T * r);
+
+[:
+
+[*Effects:] Equivalent to [^intrusive_ptr(r).swap(*this)].
+
+[*Returns:] [^*this].
+
+]
+
+[heading reset]
+
+ void reset(T * r);
+
+[:
+
+[*Effects:] Equivalent to [^intrusive_ptr(r).swap(*this)].
+]
+
+[heading indirection]
+
+T & operator*() const; // never throws
+
+[:
+
+[*Requirements:] [^get() != 0].
+
+[*Returns:] [^*get()].
+
+[*Throws:] nothing.
+]
+
+
+ T * operator->() const; // never throws
+
+[:
+
+[*Requirements:] [^get() != 0].
+
+[*Returns:] [^get()].
+
+[*Throws:] nothing.
+]
+
+[heading get]
+
+ T * get() const; // never throws
+
+[:
+
+[*Returns:] the stored pointer.
+
+[*Throws:] nothing.
+]
+
+[heading conversions]
+
+ operator ['unspecified-bool-type] () const; // never throws
+
+[:
+
+[*Returns:] an unspecified value that, when used in boolean contexts, is equivalent to [^get() != 0].
+
+[*Throws:] nothing.
+
+[*Notes:] This conversion operator allows [*intrusive_ptr] objects to be used in boolean contexts, like [^if (p && p->valid()) {}]. The actual target type is typically a pointer to a member function, avoiding many of the implicit conversion pitfalls.
+
+]
+
+[heading swap]
+
+ void swap(intrusive_ptr & b); // never throws
+
+[:
+
+[*Effects:] Exchanges the contents of the two smart pointers.
+
+[*Throws:] nothing.
+]
+
+[endsect]
+
+[section Free Functions]
+
+[heading comparison]
+
+ template<class T, class U>
+ bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a.get() == b.get()].
+
+[*Throws:] nothing.
+]
+
+ template<class T, class U>
+ bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a.get() != b.get()].
+
+[*Throws:] nothing.
+]
+
+ template<class T, class U>
+ bool operator==(intrusive_ptr<T> const & a, U * b); // never throws
+
+[:
+
+[*Returns:] [^a.get() == b].
+
+[*Throws:] nothing.
+]
+
+
+ template<class T, class U>
+ bool operator!=(intrusive_ptr<T> const & a, U * b); // never throws
+
+[:
+
+[*Returns:] [^a.get() != b].
+
+[*Throws:] nothing.
+]
+
+
+ template<class T, class U>
+ bool operator==(T * a, intrusive_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a == b.get()].
+
+[*Throws:] nothing.
+]
+
+
+ template<class T, class U>
+ bool operator!=(T * a, intrusive_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a != b.get()].
+
+[*Throws:] nothing.
+]
+
+
+ template<class T, class U>
+ bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^std::less<T *>()(a.get(), b.get())].
+
+[*Throws:] nothing.
+
+[*Notes:] Allows intrusive_ptr objects to be used as keys in associative containers.
+]
+
+[heading swap]
+
+ template<class T>
+ void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
+
+[:
+
+[*Effects:] Equivalent to [^a.swap(b)].
+
+[*Throws:] nothing.
+
+[*Notes:] Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+]
+
+[heading get_pointer]
+
+ template<class T>
+ T * get_pointer(intrusive_ptr<T> const & p); // never throws
+
+[:
+
+[*Returns:] [^p.get()].
+
+[*Throws:] nothing.
+
+[*Notes:] Provided as an aid to generic programming. Used by [@../bind/mem_fn.html mem_fn].
+]
+
+[heading static_pointer_cast]
+
+ template<class T, class U>
+ intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r); // never throws
+
+[:
+
+[*Returns:] [^intrusive_ptr<T>(static_cast<T*>(r.get()))].
+
+[*Throws:] nothing.
+]
+
+[heading const_pointer_cast]
+
+ template<class T, class U>
+ intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r); // never throws
+
+[:
+
+[*Returns:] [^intrusive_ptr<T>(const_cast<T*>(r.get()))].
+
+[*Throws:] nothing.
+]
+
+[heading dynamic_pointer_cast]
+
+ template<class T, class U>
+ intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r);
+
+[:
+
+[*Returns:] [^intrusive_ptr<T>(dynamic_cast<T*>(r.get()))].
+
+[*Throws:] nothing.
+]
+
+[heading operator<<]
+
+ template<class E, class T, class Y>
+ std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
+
+[:
+
+Effects: [^os << p.get();].
+
+[*Returns:] [^os].
+]
+
+[endsect]
+
+$Date: 2007/04/09 21:35:07 $
+
+Copyright 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file [@../../LICENSE_1_0.txt LICENSE_1_0.txt] or copy at [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt].
+
[endsect][/intrusive_ptr]
\ No newline at end of file
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_array.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_array.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_array.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,7 +1,17 @@
-[def __reset__ [link smart_ptr.reference.scoped_array.members.reset reset]
+[def __reset__ [link smart_ptr.reference.scoped_array.members.reset reset]]
+[def __element_type__ [link smart_ptr.reference.scoped_array.members.element_type element_type]]
+[def __ctor__ [link smart_ptr.reference.scoped_array.members.constructors scoped_array]]
+[def __destructor__ [link smart_ptr.reference.scoped_array.members.destructor ~scoped_array]]
+[def __operatorlbrb__ [link smart_ptr.reference.scoped_array.members.subscripting operator\[\]]]
+[def __get__ [link smart_ptr.reference.scoped_array.members.get]]
+[def __operatorconv__ [link smart_ptr.reference.scoped_array.members.conversions operator ['unspecified-bool-type]]]
+[def __swap__ [link smart_ptr.reference.scoped_array.members.swap swap]]
+[def __free_swap__ [link smart_ptr.reference.scoped_array.free_functions.swap swap]]
[section:scoped_array scoped_array class template]
+[section Introduction]
+
The __scoped_array__ class template stores a pointer to a dynamically allocated array. (Dynamically allocated arrays are allocated with the C++ [*new\[\]] expression.) The array pointed to is guaranteed to be deleted, either on destruction of the __scoped_array__, or via an explicit __reset__.
The __scoped_array__ template is a simple solution for simple needs. It supplies a basic "resource acquisition is initialization" facility, without shared-ownership or transfer-of-ownership semantics. Both its name and enforcement of semantics (by being __noncopyable__) signal its intent to retain ownership solely within the current scope. Because it is __noncopyable__, it is safer than __shared_array__ for pointers which should not be copied.
@@ -16,6 +26,8 @@
The class template is parameterized on [*T], the type of the object pointed to. [*T] must meet the smart pointer __common_requirements__.
+[endsect]
+
[section Synopsis]
namespace boost {
@@ -23,22 +35,22 @@
template<class T> class scoped_array : __noncopyable__ {
public:
- typedef T [@#element_type element_type];
+ typedef T __element_type__;
- explicit [@#ctor scoped_array](T * p = 0); // never throws
- [@#destructor ~scoped_array](); // never throws
+ explicit __ctor__(T * p = 0); // never throws
+ __destructor__(); // never throws
- void [@#reset reset](T * p = 0); // never throws
+ void __reset__(T * p = 0); // never throws
- T & [@#operator operator\[\]](std::ptrdiff_t i) const; // never throws
- T * [@#get get]() const; // never throws
+ T & __operatorlbrb__(std::ptrdiff_t i) const; // never throws
+ T * __get__() const; // never throws
- operator [@#conversions ['unspecified-bool-type]]() const; // never throws
+ __operatorconv__ () const; // never throws
- void [@#swap swap](scoped_array & b); // never throws
+ void __swap__(__scoped_array__ & b); // never throws
};
- template<class T> void [@#free-swap swap](scoped_array<T> & a, scoped_array<T> & b); // never throws
+ template<class T> void __free_swap__(scoped_array<T> & a, scoped_array<T> & b); // never throws
}
@@ -72,7 +84,7 @@
[heading subscripting]
- T & operator\[\](std::ptrdiff_t i) const; // never throws
+ T & operator[](std::ptrdiff_t i) const; // never throws
Returns a reference to element [*i] of the array pointed to by the stored pointer. Behavior is undefined and almost certainly undesirable if the stored pointer is 0, or if [*i] is less than 0 or is greater than or equal to the number of elements in the array.
@@ -84,9 +96,9 @@
[heading conversions]
- operator ['unspecified-bool-type] () const; // never throws
+ operator ``['unspecified-bool-type]`` () const; // never throws
-Returns an unspecified value that, when used in boolean contexts, is equivalent to [^get() != 0].
+Returns an unspecified value that, when used in boolean contexts, is equivalent to `__get__() != 0`.
[heading swap]
@@ -102,7 +114,7 @@
template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws
-Equivalent to [*a.swap(b)]. Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+Equivalent to `a.__swap__(b)`. Matches the interface of `*std::swap`. Provided as an aid to generic programming.
Revised 09 January 2003
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_ptr.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_ptr.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/scoped_ptr.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,2 +1,194 @@
-[section:scoped_ptr scoped_ptr]
+[def __reset__ [link smart_ptr.reference.scoped_ptr.members.reset reset]]
+[def __element_type__ [link smart_ptr.reference.scoped_ptr.members.element_type element_type]]
+[def __ctor__ [link smart_ptr.reference.scoped_ptr.members.constructors scoped_ptr]]
+[def __destructor__ [link smart_ptr.reference.scoped_ptr.members.destructor ~scoped_ptr]]
+[def __operatorlbrb__ [link smart_ptr.reference.scoped_ptr.members.subscripting operator\[\]]]
+[def __get__ [link smart_ptr.reference.scoped_ptr.members.get]]
+[def __operatorconv__ [link smart_ptr.reference.scoped_ptr.members.conversions operator ['unspecified-bool-type]]]
+[def __swap__ [link smart_ptr.reference.scoped_ptr.members.swap swap]]
+[def __free_swap__ [link smart_ptr.reference.scoped_ptr.free_functions.swap swap]]
+
+[def __example__ [link smart_ptr.reference.scoped_ptr.example example]]
+
+[section:scoped_ptr scoped_ptr class template]
+
+[section Introduction]
+
+The __scoped_ptr__ class template stores a pointer to a dynamically allocated object. (Dynamically allocated objects are allocated with the C++ [*new] expression.) The object pointed to is guaranteed to be deleted, either on destruction of the __scoped_ptr__, or via an explicit __reset__. See the __example__.
+
+The __scoped_ptr__ template is a simple solution for simple needs. It supplies a basic "resource acquisition is initialization" facility, without shared-ownership or transfer-of-ownership semantics. Both its name and enforcement of semantics (by being __noncopyable__) signal its intent to retain ownership solely within the current scope. Because it is __noncopyable__, it is safer than __shared_ptr__ or [*std::auto_ptr] for pointers which should not be copied.
+
+Because __scoped_ptr__ is simple, in its usual implementation every operation is as fast as for a built-in pointer and it has no more space overhead that a built-in pointer.
+
+scoped_ptr cannot be used in C++ Standard Library containers. Use __shared_ptr__ if you need a smart pointer that can.
+
+scoped_ptr cannot correctly hold a pointer to a dynamically allocated array. See __scoped_array__ for that usage.
+
+The class template is parameterized on [*T], the type of the object pointed to. [*T] must meet the smart pointer __common_requirements__.
+
+[endsect]
+
+[section Synopsis]
+
+ namespace boost {
+
+ template<class T> class scoped_ptr : __noncopyable__ {
+
+ public:
+ typedef T [@#element_type element_type];
+
+ explicit [@#constructors scoped_ptr](T * p = 0); // never throws
+ [@#destructor ~scoped_ptr](); // never throws
+
+ void __reset__(T * p = 0); // never throws
+
+ T & [@#indirection operator*]() const; // never throws
+ T * [@#indirection operator->]() const; // never throws
+ T * [@#get get]() const; // never throws
+
+ operator [@#conversions ['unspecified-bool-type]]() const; // never throws
+
+ void [@#swap swap](scoped_ptr & b); // never throws
+ };
+
+ template<class T> void [@#free-swap swap](scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws
+
+ }
+
+[endsect]
+
+[section Members]
+
+[heading element_type]
+
+ typedef T element_type;
+
+Provides the type of the stored pointer.
+
+[heading constructors]
+
+ explicit scoped_ptr(T * p = 0); // never throws
+
+Constructs a __scoped_ptr__, storing a copy of [*p], which must have been allocated via a C++ [*new] expression or be 0. [*T] is not required be a complete type. See the smart pointer __common_requirements__.
+
+[heading destructor]
+
+ ~scoped_ptr(); // never throws
+
+Destroys the object pointed to by the stored pointer, if any, as if by using [^delete this->get()].
+
+The guarantee that this does not throw exceptions depends on the requirement that the deleted object's destructor does not throw exceptions. See the smart pointer __common_requirements__.
+
+[heading reset]
+
+ void reset(T * p = 0); // never throws
+
+Deletes the object pointed to by the stored pointer and then stores a copy of p, which must have been allocated via a C++ [*new] expression or be 0. The guarantee that this does not throw exceptions depends on the requirement that the deleted object's destructor does not throw exceptions. See the smart pointer __common_requirements__.
+
+[heading indirection]
+
+ T & operator*() const; // never throws
+
+Returns a reference to the object pointed to by the stored pointer. Behavior is undefined if the stored pointer is 0.
+
+ T * operator->() const; // never throws
+
+Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
+
+[heading get]
+
+ T * get() const; // never throws
+
+Returns the stored pointer. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+[heading conversions]
+
+ operator ['unspecified-bool-type] () const; // never throws
+
+Returns an unspecified value that, when used in boolean contexts, is equivalent to [^get() != 0].
+
+[heading swap]
+
+ void swap(scoped_ptr & b); // never throws
+
+Exchanges the contents of the two smart pointers. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+[endsect]
+
+[section Free Functions]
+
+[heading swap]
+
+ template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws
+
+Equivalent to [*a.swap(b)]. Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+
+[endsect]
+
+[section Example]
+
+ Here's an example that uses __scoped_ptr__.
+
+ #include <boost/scoped_ptr.hpp>
+ #include <iostream>
+
+ struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };
+
+ class MyClass {
+ boost::scoped_ptr<int> ptr;
+ public:
+ MyClass() : ptr(new int) { *ptr = 0; }
+ int add_one() { return ++*ptr; }
+ };
+
+ int main()
+ {
+ boost::scoped_ptr<Shoe> x(new Shoe);
+ MyClass my_instance;
+ std::cout << my_instance.add_one() << '\n';
+ std::cout << my_instance.add_one() << '\n';
+ }
+
+The example program produces the beginning of a child's nursery rhyme:
+
+[:
+[pre
+1
+2
+Buckle my shoe
+]
+]
+[endsect]
+
+[section Rationale]
+
+The primary reason to use __scoped_ptr__ rather than [*auto_ptr] is to let readers of your code know that you intend "resource acquisition is initialization" to be applied only for the current scope, and have no intent to transfer ownership.
+
+A secondary reason to use __scoped_ptr__ is to prevent a later maintenance programmer from adding a function that transfers ownership by returning the [*auto_ptr], because the maintenance programmer saw [*auto_ptr], and assumed ownership could safely be transferred.
+
+Think of [*bool] vs [*int]. We all know that under the covers [*bool] is usually just an [*int]. Indeed, some argued against including [*bool] in the C++ standard because of that. But by coding [*bool] rather than [*int], you tell your readers what your intent is. Same with __scoped_ptr__; by using it you are signaling intent.
+
+It has been suggested that [*scoped_ptr<T>] is equivalent to [*std::auto_ptr<T> const]. Ed Brey pointed out, however, that __reset__ will not work on a [*std::auto_ptr<T> const.]
+
+[endsect]
+
+[section Handle/Body Idiom]
+
+One common usage of __scoped_ptr__ is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.
+
+The [@example/scoped_ptr_example_test.cpp scoped_ptr_example_test.cpp] sample program includes a header file, [@example/scoped_ptr_example.hpp scoped_ptr_example.hpp], which uses a [*scoped_ptr<>] to an incomplete type to hide the implementation. The instantiation of member functions which require a complete type occurs in the [@example/scoped_ptr_example.cpp scoped_ptr_example.cpp] implementation file.
+
+[endsect]
+
+[section Frequently Asked Questions]
+
+[*Q]. Why doesn't __scoped_ptr__ have a release() member?
+[*A]. When reading source code, it is valuable to be able to draw conclusions about program behavior based on the types being used. If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)
+
+[endsect]
+
+Revised 09 January 2003
+
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file [@../../LICENSE_1_0.txt LICENSE_1_0.txt] or copy at [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt].
+
[endsect][/scoped_ptr]
\ No newline at end of file
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_array.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_array.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_array.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,2 +1,175 @@
-[section:shared_array shared_array]
+[section:shared_array shared_array class template]
+
+[section Introduction]
+
+The __shared_array__ class template stores a pointer to a dynamically allocated array. (Dynamically allocated array are allocated with the C++ [*new[]] expression.) The object pointed to is guaranteed to be deleted when the last __shared_array__ pointing to it is destroyed or reset.
+
+Every __shared_array__ meets the [*CopyConstructible] and [*Assignable] requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that __shared_array__ works with the standard library's associative containers.
+
+Normally, a __shared_array__ cannot correctly hold a pointer to an object that has been allocated with the non-array form of new. See __shared_ptr__ for that usage.
+
+Because the implementation uses reference counting, cycles of __shared_array__ instances will not be reclaimed. For example, if [*main()] holds a __shared_array__ to [*A], which directly or indirectly holds a __shared_array__ back to [*A], [*A]'s use count will be 2. Destruction of the original __shared_array__ will leave [*A] dangling with a use count of 1.
+
+A __shared_ptr__ to a [*std::vector] is an alternative to a __shared_array__ that is a bit heavier duty but far more flexible.
+
+The class template is parameterized on [*T], the type of the object pointed to. [*T] must meet the smart pointer __common_requirements__.
+
+[endsect]
+
+[section Synopsis]
+
+ namespace boost {
+
+ template<class T> class shared_array {
+
+ public:
+ typedef T [@#element_type element_type];
+
+ explicit [@#constructors shared_array](T * p = 0);
+ template<class D> [@#constructors shared_array](T * p, D d);
+ [@#destructor ~shared_array](); // never throws
+
+ [@#constructors shared_array](shared_array const & r); // never throws
+
+ shared_array & [@#assignment operator=](shared_array const & r); // never throws
+
+ void __reset__(T * p = 0);
+ template<class D> void __reset__(T * p, D d);
+
+ T & [@#indexing operator[]](std::ptrdiff_t i) const() const; // never throws
+ T * [@#get get]() const; // never throws
+
+ bool [@#unique unique]() const; // never throws
+ long [@#use_count use_count]() const; // never throws
+
+ operator [@#conversions ['unspecified-bool-type]]() const; // never throws
+
+ void [@#swap swap](shared_array<T> & b); // never throws
+ };
+
+ template<class T>
+ bool [@#comparison operator==](shared_array<T> const & a, shared_array<T> const & b); // never throws
+ template<class T>
+ bool [@#comparison operator!=](shared_array<T> const & a, shared_array<T> const & b); // never throws
+ template<class T>
+ bool [@#comparison operator<](shared_array<T> const & a, shared_array<T> const & b); // never throws
+
+ template<class T> void [@#free-swap swap](shared_array<T> & a, shared_array<T> & b); // never throws
+
+ }
+
+[endsect]
+
+[section Members]
+
+[heading element_type]
+
+ typedef T element_type;
+
+Provides the type of the stored pointer.
+[heading constructors]
+
+ explicit shared_array(T * p = 0);
+
+Constructs a __shared_array__, storing a copy of [*p], which must be a pointer to an array that was allocated via a C++ [*new[]] expression or be 0. Afterwards, the __use_count__ is 1 (even if p == 0; see [@#destructor ~shared_array]). The only exception which may be thrown by this constructor is [*std::bad_alloc]. If an exception is thrown, [*delete[] p] is called.
+
+
+ template<class D> shared_array(T * p, D d);
+
+Constructs a __shared_array__, storing a copy of [*p] and of [*d]. Afterwards, the __use_count__ is 1. [*D]'s copy constructor and destructor must not throw. When the the time comes to delete the array pointed to by [*p], the object [*d] is used in the statement [*d(p)]. Invoking the object [*d] with parameter [*p] in this way must not throw. The only exception which may be thrown by this constructor is [*std::bad_alloc]. If an exception is thrown, [*d(p)] is called.
+
+ shared_array(shared_array const & r); // never throws
+
+Constructs a __shared_array__, as if by storing a copy of the pointer stored in [*r]. Afterwards, the __use_count__ for all copies is 1 more than the initial use count.
+
+[heading destructor]
+
+ ~shared_array(); // never throws
+
+Decrements the __use_count__. Then, if the use count is 0, deletes the array pointed to by the stored pointer. Note that [*delete[]] on a pointer with a value of 0 is harmless. [*T] need not be a complete type. The guarantee that this does not throw exceptions depends on the requirement that the deleted object's destructor does not throw exceptions. See the smart pointer __common_requirements__.
+
+[heading assignment]
+
+ shared_array & operator=(shared_array const & r); // never throws
+
+Constructs a new __shared_array__ as described [@#constructors above], then replaces this __shared_array__ with the new one, destroying the replaced object.
+
+[heading reset]
+
+ void reset(T * p = 0);
+
+Constructs a new __shared_array__ as described [@#constructors above], then replaces this __shared_array__ with the new one, destroying the replaced object. The only exception which may be thrown is [*std::bad_alloc]. If an exception is thrown, [*delete[] p] is called.
+
+ template<class D> void reset(T * p, D d);
+
+Constructs a new __shared_array__ as described [@#constructors above], then replaces this __shared_array__ with the new one, destroying the replaced object. [*D]'s copy constructor must not throw. The only exception which may be thrown is [*std::bad_alloc]. If an exception is thrown, [*d(p)] is called.
+
+[heading indexing]
+
+ T & operator[](std::ptrdiff_t i) const; // never throws
+
+Returns a reference to element [*i] of the array pointed to by the stored pointer. Behavior is undefined and almost certainly undesirable if the stored pointer is 0, or if [*i] is less than 0 or is greater than or equal to the number of elements in the array.
+
+[heading get]
+
+ T * get() const; // never throws
+
+Returns the stored pointer. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+[heading unique]
+
+ bool unique() const; // never throws
+
+Returns true if no other __shared_array__ is sharing ownership of the stored pointer, false otherwise. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+[heading use_count]
+
+ long use_count() const; // never throws
+
+Returns the number of __shared_array__ objects sharing ownership of the stored pointer. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+Because [*use_count] is not necessarily efficient to implement for implementations of __shared_array__ that do not use an explicit reference count, it might be removed from some future version. Thus it should be used for debugging purposes only, and not production code.
+
+[heading conversions]
+
+ operator ['unspecified-bool-type] () const; // never throws
+
+Returns an unspecified value that, when used in boolean contexts, is equivalent to [^get() != 0].
+
+[heading swap]
+
+ void swap(shared_ptr & b); // never throws
+
+Exchanges the contents of the two smart pointers. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+[endsect]
+
+[section Free Functions]
+
+[heading comparison]
+
+ template<class T>
+ bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws
+ template<class T>
+ bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws
+ template<class T>
+ bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws
+
+Compares the stored pointers of the two smart pointers. [*T] need not be a complete type. See the smart pointer __common_requirements__.
+
+The [*operator<] overload is provided to define an ordering so that __shared_array__ objects can be used in associative containers such as [*std::map]. The implementation uses [*std::less<T *>] to perform the comparison. This ensures that the comparison is handled correctly, since the standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel] paragraph 2) but [*std::less<>] on pointers is well-defined (20.3.3 [lib.comparisons] paragraph 8).
+
+[heading swap]
+
+ template<class T>
+ void swap(shared_array<T> & a, shared_array<T> & b) // never throws
+
+Equivalent to [*a.swap(b)]. Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+
+[endsect]
+
+Revised 09 January 2003
+
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file [@../../LICENSE_1_0.txt LICENSE_1_0.txt] or copy at [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt].
+
[endsect][/shared_array]
\ No newline at end of file
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_ptr.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_ptr.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/shared_ptr.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,2 +1,703 @@
-[section:shared_ptr shared_ptr]
+[section:shared_ptr shared_ptr class template]
+
+[section Introduction]
+
+The __shared_ptr__ class template stores a pointer to a dynamically allocated object, typically with a C++ new-expression. The object pointed to is guaranteed to be deleted when the last __shared_ptr__ pointing to it is destroyed or reset. See the __example__.
+
+Every __shared_ptr__ meets the [*CopyConstructible] and [*Assignable] requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that __shared_ptr__ works with the standard library's associative containers.
+
+Normally, a __shared_ptr__ cannot correctly hold a pointer to a dynamically allocated array. See __shared_array__ for that usage.
+
+Because the implementation uses reference counting, cycles of __shared_ptr__ instances will not be reclaimed. For example, if [*main()] holds a __shared_ptr__ to [*A], which directly or indirectly holds a __shared_ptr__ back to [*A], [*A]'s use count will be 2. Destruction of the original __shared_ptr__ will leave [*A] dangling with a use count of 1. Use __weak_ptr__ to "break cycles."
+
+The class template is parameterized on [*T], the type of the object pointed to. shared_ptr and most of its member functions place no requirements on T; it is allowed to be an incomplete type, or void. Member functions that do place additional requirements ([@#constructors constructors], __reset__) are explicitly documented below.
+
+shared_ptr<T> can be implicitly converted to shared_ptr<U> whenever T* can be implicitly converted to U*. In particular, shared_ptr<T> is implicitly convertible to shared_ptr<T const>, to shared_ptr<U> where U is an accessible base of T, and to shared_ptr<void>.
+
+shared_ptr is now part of TR1, the first C++ Library Technical Report. The latest draft of TR1 is available at the following location:
+
+[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf] (1.36Mb PDF)
+
+This implementation conforms to the TR1 specification, with the only exception that it resides in namespace [^boost] instead of [^std::tr1].
+[endsect]
+
+[section Best Practices]
+
+A simple guideline that nearly eliminates the possibility of memory leaks is: always use a named smart pointer variable to hold the result of new. Every occurence of the new keyword in the code should have the form:
+
+ shared_ptr<T> p(new Y);
+
+It is, of course, acceptable to use another smart pointer in place of shared_ptr above; having T and Y be the same type, or passing arguments to Y's constructor is also OK.
+
+If you observe this guideline, it naturally follows that you will have no explicit deletes; try/catch constructs will be rare.
+
+Avoid using unnamed shared_ptr temporaries to save typing; to see why this is dangerous, consider this example:
+
+ void f(shared_ptr<int>, int);
+ int g();
+
+ void ok()
+ {
+ shared_ptr<int> p(new int(2));
+ f(p, g());
+ }
+
+ void bad()
+ {
+ f(shared_ptr<int>(new int(2)), g());
+ }
+
+The function ok follows the guideline to the letter, whereas bad constructs the temporary shared_ptr in place, admitting the possibility of a memory leak. Since function arguments are evaluated in unspecified order, it is possible for new int(2) to be evaluated first, g() second, and we may never get to the shared_ptr constructor if g throws an exception. See [@http://www.gotw.ca/gotw/056.htm Herb Sutter's treatment] (also [@http://www.cuj.com/reference/articles/2002/0212/0212_sutter.htm here]) of the issue for more information.
+
+[endsect]
+
+[section Synopsis]
+
+ namespace boost {
+
+ class bad_weak_ptr: public std::exception;
+
+ template<class T> class __weak_ptr__;
+
+ template<class T> class shared_ptr {
+
+ public:
+
+ typedef T [@#element_type element_type];
+
+ [@#constructors shared_ptr](); // never throws
+ template<class Y> explicit [@#constructors shared_ptr](Y * p);
+ template<class Y, class D> [@#constructors shared_ptr](Y * p, D d);
+ template<class Y, class D, class A> [@#allocator_constructor shared_ptr](Y * p, D d, A a);
+ [@#destructor ~shared_ptr](); // never throws
+
+ [@#constructors shared_ptr](shared_ptr const & r); // never throws
+ template<class Y> [@#constructors shared_ptr](shared_ptr<Y> const & r); // never throws
+ template<class Y> [@#constructors shared_ptr](shared_ptr<Y> const & r, T * p); // never throws
+ template<class Y> explicit [@#constructors shared_ptr](__weak_ptr__<Y> const & r);
+ template<class Y> explicit [@#constructors shared_ptr](std::auto_ptr<Y> & r);
+
+ shared_ptr & [@#assignment operator=](shared_ptr const & r); // never throws
+ template<class Y> shared_ptr & [@#assignment operator=](shared_ptr<Y> const & r); // never throws
+ template<class Y> shared_ptr & [@#assignment operator=](std::auto_ptr<Y> & r);
+
+ void __reset__(); // never throws
+ template<class Y> void __reset__(Y * p);
+ template<class Y, class D> void __reset__(Y * p, D d);
+ template<class Y, class D, class A> void __reset__(Y * p, D d, A a);
+ template<class Y> void __reset__(shared_ptr<Y> const & r, T * p); // never throws
+
+ T & [@#indirection operator*]() const; // never throws
+ T * [@#indirection operator->]() const; // never throws
+ T * [@#get get]() const; // never throws
+
+ bool [@#unique unique]() const; // never throws
+ long [@#use_count use_count]() const; // never throws
+
+ operator [@#conversions ['unspecified-bool-type]]() const; // never throws
+
+ void [@#swap swap](shared_ptr & b); // never throws
+ };
+
+ template<class T, class U>
+ bool [@#comparison operator==](shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+ template<class T, class U>
+ bool [@#comparison operator!=](shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+ template<class T, class U>
+ bool [@#comparison operator<](shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+ template<class T> void [@#free-swap swap](shared_ptr<T> & a, shared_ptr<T> & b); // never throws
+
+ template<class T> T * [@#get_pointer get_pointer](shared_ptr<T> const & p); // never throws
+
+ template<class T, class U>
+ shared_ptr<T> [@#static_pointer_cast static_pointer_cast](shared_ptr<U> const & r); // never throws
+
+ template<class T, class U>
+ shared_ptr<T> [@#const_pointer_cast const_pointer_cast](shared_ptr<U> const & r); // never throws
+
+ template<class T, class U>
+ shared_ptr<T> [@#dynamic_pointer_cast dynamic_pointer_cast](shared_ptr<U> const & r); // never throws
+
+ template<class E, class T, class Y>
+ std::basic_ostream<E, T> & [@#insertion-operator operator<<] (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
+
+ template<class D, class T>
+ D * [@#get_deleter get_deleter](shared_ptr<T> const & p);
+ }
+
+[endsect]
+
+[section Members]
+
+[heading element_type]
+
+ typedef T element_type;
+
+Provides the type of the template parameter T.
+
+[heading constructors]
+
+ shared_ptr(); // never throws
+[:
+
+[*Effects:] Constructs an empty __shared_ptr__.
+
+[*Postconditions:] [^use_count() == 0 && get() == 0].
+
+[*Throws:] nothing.
+
+]
+
+[The nothrow guarantee is important, since reset() is specified in terms of the default constructor; this implies that the constructor must not allocate memory.]
+
+ template<class Y> explicit shared_ptr(Y * p);
+
+[:
+
+[*Requirements:] [*p] must be convertible to [*T *]. Y must be a complete type. The expression [^delete p] must be well-formed, must not invoke undefined behavior, and must not throw exceptions.
+
+[*Effects:] Constructs a __shared_ptr__ that owns the pointer [*p].
+
+[*Postconditions:] [^use_count() == 1 && get() == p].
+
+[*Throws:] std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
+
+[*Exception safety:] If an exception is thrown, [^delete p] is called.
+
+Notes: [*p] must be a pointer to an object that was allocated via a C++ [*new] expression or be 0. The postcondition that __use_count__ is 1 holds even if [*p] is 0; invoking delete on a pointer that has a value of 0 is harmless.
+]
+
+[This constructor has been changed to a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete with its original type, even when T does not have a virtual destructor, or is void.
+
+The optional intrusive counting support has been dropped as it exposes too much implementation details and doesn't interact well with weak_ptr. The current implementation uses a different mechanism, [@enable_shared_from_this.html enable_shared_from_this], to solve the "shared_ptr from this" problem.]
+
+ template<class Y, class D> shared_ptr(Y * p, D d);
+ template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
+
+[:
+
+[*Requirements:] [*p] must be convertible to [*T *]. D must be CopyConstructible. The copy constructor and destructor of [*D] must not throw. The expression [^d(p)] must be well-formed, must not invoke undefined behavior, and must not throw exceptions. A must be an Allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard.
+
+[*Effects:] Constructs a __shared_ptr__ that owns the pointer p and the deleter [*d]. The second constructor allocates memory using a copy of a.
+
+[*Postconditions:] [^use_count() == 1 && get() == p].
+
+[*Throws:] std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
+
+[*Exception safety:] If an exception is thrown, [^d(p)] is called.
+
+[*Notes:] When the the time comes to delete the object pointed to by [*p], the stored copy of d is invoked with the stored copy of p as an argument.
+]
+
+[Custom deallocators allow a factory function returning a shared_ptr to insulate the user from its memory allocation strategy. Since the deallocator 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" deallocator is useful when returning a shared_ptr to a statically allocated object, and other variations allow a shared_ptr to be used as a wrapper for another smart pointer, easing interoperability.
+
+The support for custom deallocators does not impose significant overhead. Other shared_ptr features still require a deallocator to be kept.
+
+The requirement that the copy constructor of [*D] does 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.
+
+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 operator(). A non-const reference won't bind to an rvalue at all. A good solution to this problem is the rvalue reference proposed in [@http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm N1377]/[@http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm N1385].]
+
+ shared_ptr(shared_ptr const & r); // never throws
+ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
+
+[:
+
+[*Effects:] If [*r] is empty, constructs an empty __shared_ptr__; otherwise, constructs a __shared_ptr__ that shares ownership with [*r].
+
+[*Postconditions:] [^get() == r.get() && use_count() == r.use_count()].
+
+[*Throws:] nothing.
+]
+
+ template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws
+
+[:
+
+[*Effects:] constructs a __shared_ptr__ that shares ownership with [*r] and stores [*p].
+
+[*Postconditions:] [^get() == p && use_count() == r.use_count()].
+
+[*Throws:] nothing.
+]
+
+ template<class Y> explicit shared_ptr(__weak_ptr__<Y> const & r);
+
+[:
+
+[*Effects:] Constructs a __shared_ptr__ that shares ownership with [*r] and stores a copy of the pointer stored in r.
+
+[*Postconditions:] [^use_count() == r.use_count()].
+
+[*Throws:] [*bad_weak_ptr] when [^r.use_count() == 0].
+
+[*Exception safety:] If an exception is thrown, the constructor has no effect.
+]
+
+ template<class Y> shared_ptr(std::auto_ptr<Y> & r);
+
+[:
+
+[*Effects:] Constructs a __shared_ptr__, as if by storing a copy of r.release().
+
+[*Postconditions:] [^use_count() == 1].
+
+[*Throws:] std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
+
+[*Exception safety:] If an exception is thrown, the constructor has no effect.
+]
+
+[This constructor takes a the source auto_ptr by reference and not by value, and cannot accept auto_ptr temporaries. This is by design, as the constructor offers the strong guarantee; an rvalue reference would solve this problem, too.]
+[heading destructor]
+
+ ~shared_ptr(); // never throws
+
+[:
+
+[*Effects:]
+* If *this is empty, or shares ownership with another shared_ptr instance ([^use_count() > 1]), there are no side effects.
+* Otherwise, if *this owns a pointer p and a deleter d, [^d(p)] is called.
+* Otherwise, *this owns a pointer p, and [^delete p] is called.
+
+[*Throws:] nothing.
+]
+
+[heading assignment]
+
+ shared_ptr & operator=(shared_ptr const & r); // never throws
+ template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
+ template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr(r).swap(*this)].
+
+[*Returns:] [^*this].
+
+[*Notes:] 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:
+
+ shared_ptr<int> p(new int);
+ shared_ptr<void> q(p);
+ p = p;
+ q = p;
+
+both assignments may be no-ops.
+]
+
+[heading reset]
+
+ void reset(); // never throws
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr().swap(*this)].
+
+
+ template<class Y> void reset(Y * p);
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr(p).swap(*this)].
+]
+
+ template<class Y, class D> void reset(Y * p, D d);
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr(p, d).swap(*this)].
+]
+
+ template<class Y, class D, class A> void reset(Y * p, D d, A a);
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr(p, d, a).swap(*this)].
+]
+
+ template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws
+
+[:
+
+[*Effects:] Equivalent to [^shared_ptr(r, p).swap(*this)].
+]
+[heading indirection]
+
+ T & operator*() const; // never throws
+
+[:
+
+[*Requirements:] The stored pointer must not be 0.
+
+[*Returns:] a reference to the object pointed to by the stored pointer.
+
+[*Throws:] nothing.
+]
+
+ T * operator->() const; // never throws
+
+[:
+
+[*Requirements:] The stored pointer must not be 0.
+
+[*Returns:] the stored pointer.
+
+[*Throws:] nothing.
+]
+[heading get]
+
+T * get() const; // never throws
+
+[:
+
+[*Returns:] the stored pointer.
+
+[*Throws:] nothing.
+]
+[heading unique]
+[pre
+bool unique() const; // never throws
+]
+[:
+
+[*Returns:] [^use_count() == 1].
+
+[*Throws:] nothing.
+
+[*Notes:] [^unique()] may be faster than [^use_count()]. If you are using [^unique()] to implement copy on write, do not rely on a specific value when the stored pointer is zero.
+]
+[heading use_count]
+
+ long use_count() const; // never throws
+
+[:
+
+[*Returns:] the number of __shared_ptr__ objects, *this included, that ['share ownership] with [**this], or an unspecified nonnegative value when *this is empty.
+
+[*Throws:] nothing.
+
+[*Notes:] [^use_count()] is not necessarily efficient. Use only for debugging and testing purposes, not for production code.
+]
+[heading conversions]
+[pre
+operator ['unspecified-bool-type] () const; // never throws
+]
+[:
+
+[*Returns:] an unspecified value that, when used in boolean contexts, is equivalent to [^get() != 0].
+
+[*Throws:] nothing.
+
+[*Notes:] This conversion operator allows __shared_ptr__ objects to be used in boolean contexts, like [^if (p && p->valid()) {}]. The actual target type is typically a pointer to a member function, avoiding many of the implicit conversion pitfalls.
+]
+
+[The conversion to bool is not merely syntactic sugar. It allows shared_ptrs to be declared in conditions when using [@#dynamic_pointer_cast dynamic_pointer_cast] or [@weak_ptr.htm#lock weak_ptr::lock].]
+
+[heading swap]
+
+ void swap(shared_ptr & b); // never throws
+
+[:
+
+[*Effects:] Exchanges the contents of the two smart pointers.
+
+[*Throws:] nothing.
+]
+[endsect]
+
+[section Free Functions]
+[heading comparison]
+
+ template<class T, class U>
+ bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a.get() == b.get()].
+
+[*Throws:] nothing.
+]
+
+
+ template<class T, class U>
+ bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] [^a.get() != b.get()].
+
+[*Throws:] nothing.
+]
+
+ template<class T, class U>
+ bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
+
+[:
+
+[*Returns:] an unspecified value such that
+* [*operator<] is a strict weak ordering as described in section 25.3 [^\[lib.alg.sorting\]] of the C++ standard;
+* under the equivalence relation defined by operator<, [^!(a < b) && !(b < a)], two shared_ptr instances are equivalent if and only if they share ownership or are both empty.
+
+[*Throws:] nothing.
+
+[*Notes:] Allows shared_ptr objects to be used as keys in associative containers.
+]
+
+[Operator< has been preferred over a std::less specialization for consistency and legality reasons, as std::less is required to return the results of operator<, and many standard algorithms use operator< instead of std::less for comparisons when a predicate is not supplied. Composite objects, like std::pair, also implement their operator< in terms of their contained subobjects' operator<.
+
+The rest of the comparison operators are omitted by design.]
+
+[heading swap]
+
+ template<class T>
+ void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
+
+[:
+
+[*Effects:] Equivalent to [^a.swap(b)].
+
+[*Throws:] nothing.
+
+[*Notes:] Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+]
+
+[swap is defined in the same namespace as shared_ptr as this is currently the only legal way to supply a swap function that has a chance to be used by the standard library.]
+
+[heading get_pointer]
+
+ template<class T>
+ T * get_pointer(shared_ptr<T> const & p); // never throws
+
+[:
+
+[*Returns:] [^p.get()].
+
+[*Throws:] nothing.
+
+[*Notes:] Provided as an aid to generic programming. Used by [@../bind/mem_fn.html mem_fn].
+]
+
+[heading static_pointer_cast]
+
+template<class T, class U>
+ shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws
+
+[:
+
+Requires: The expression [^static_cast<T*>(r.get())] must be well-formed.
+
+[*Returns:] If [*r] is ['empty], an ['empty] [*shared_ptr<T>]; otherwise, a shared_ptr<T> object that stores a copy of [^ static_cast<T*>(r.get())] and ['shares ownership] with [*r].
+
+[*Throws:] nothing.
+
+[*Notes:] the seemingly equivalent expression
+
+[^shared_ptr<T>(static_cast<T*>(r.get()))]
+
+will eventually result in undefined behavior, attempting to delete the same object twice.
+]
+
+[heading const_pointer_cast]
+
+ template<class T, class U>
+ shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws
+
+[:
+
+Requires: The expression [^const_cast<T*>(r.get())] must be well-formed.
+
+[*Returns:] If [*r] is ['empty], an ['empty] [*shared_ptr<T>]; otherwise, a shared_ptr<T> object that stores a copy of [^ const_cast<T*>(r.get())] and ['shares ownership] with [*r].
+
+[*Throws:] nothing.
+
+[*Notes:] the seemingly equivalent expression
+
+ shared_ptr<T>(const_cast<T*>(r.get()))
+
+will eventually result in undefined behavior, attempting to delete the same object twice.
+]
+
+[heading dynamic_pointer_cast]
+
+ template<class T, class U>
+ shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);
+
+[:
+
+Requires: The expression [^dynamic_cast<T*>(r.get())] must be well-formed and its behavior defined.
+
+[*Returns:]
+* When [^dynamic_cast<T*>(r.get())] returns a nonzero value, a shared_ptr<T> object that stores a copy of it and ['shares ownership] with r;
+* Otherwise, an ['empty] shared_ptr<T> object.
+
+[*Throws:] nothing.
+
+[*Notes:] the seemingly equivalent expression
+
+[^shared_ptr<T>(dynamic_cast<T*>(r.get()))]
+
+will eventually result in undefined behavior, attempting to delete the same object twice.
+]
+
+[heading operator<<]
+
+ template<class E, class T, class Y>
+ std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
+
+[:
+
+Effects: [^os << p.get();].
+
+[*Returns:] [*os].
+]
+
+[heading get_deleter]
+
+ template<class D, class T>
+ D * get_deleter(shared_ptr<T> const & p);
+
+[:
+
+[*Returns:] If *this owns a deleter d of type (cv-unqualified) D, returns [^&d]; otherwise returns 0.
+]
+
+[endsect]
+
+[section Example]
+
+See [@example/shared_ptr_example.cpp shared_ptr_example.cpp] for a complete example program. The program builds a [*std::vector] and [*std::set] of __shared_ptr__ objects.
+
+Note that after the containers have been populated, some of the __shared_ptr__ objects will have a use count of 1 rather than a use count of 2, since the set is a [*std::set] rather than a [*std::multiset], and thus does not contain duplicate entries. Furthermore, the use count may be even higher at various times while [*push_back] and [*insert] container operations are performed. More complicated yet, the container operations may throw exceptions under a variety of circumstances. Getting the memory management and exception handling in this example right without a smart pointer would be a nightmare.
+
+[endsect]
+
+[section Handle/Body Idiom]
+
+One common usage of __shared_ptr__ is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.
+
+The [@example/shared_ptr_example2_test.cpp shared_ptr_example2_test.cpp] sample program includes a header file, [@example/shared_ptr_example2.hpp shared_ptr_example2.hpp], which uses a [*shared_ptr<>] to an incomplete type to hide the implementation. The instantiation of member functions which require a complete type occurs in the [@example/shared_ptr_example2.cpp shared_ptr_example2.cpp] implementation file. Note that there is no need for an explicit destructor. Unlike ~scoped_ptr, ~shared_ptr does not require that [*T] be a complete type.
+
+[endsect]
+
+[section Thread Safety]
+
+shared_ptr objects offer the same level of thread safety as built-in types. A shared_ptr instance can be "read" (accessed using only const operations) simultaneously by multiple threads. Different shared_ptr instances can be "written to" (accessed using mutable operations such as operator= or reset) simultaneosly by multiple threads (even when these instances are copies, and share the same reference count underneath.)
+
+Any other simultaneous accesses result in undefined behavior.
+
+Examples:
+
+ shared_ptr<int> p(new int(42));
+
+ //--- Example 1 ---
+
+ // thread A
+ shared_ptr<int> p2(p); // reads p
+
+ // thread B
+ shared_ptr<int> p3(p); // OK, multiple reads are safe
+
+ //--- Example 2 ---
+
+ // thread A
+ p.reset(new int(1912)); // writes p
+
+ // thread B
+ p2.reset(); // OK, writes p2
+
+ //--- Example 3 ---
+
+ // thread A
+ p = p3; // reads p3, writes p
+
+ // thread B
+ p3.reset(); // writes p3; undefined, simultaneous read/write
+
+ //--- Example 4 ---
+
+ // thread A
+ p3 = p2; // reads p2, writes p3
+
+ // thread B
+ // p2 goes out of scope: undefined, the destructor is considered a "write access"
+
+ //--- Example 5 ---
+
+ // thread A
+ p3.reset(new int(1));
+
+ // thread B
+ p3.reset(new int(2)); // undefined, multiple writes
+
+]
+
+Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on the following platforms:
+* GNU GCC on x86 or x86-64;
+* GNU GCC on IA64;
+* Metrowerks CodeWarrior on PowerPC;
+* GNU GCC on PowerPC;
+* Windows.
+
+If your program is single-threaded and does not link to any libraries that might have used shared_ptr in its default configuration, you can #define the macro BOOST_SP_DISABLE_THREADS on a project-wide basis to switch to ordinary non-atomic reference count updates.
+
+(Defining BOOST_SP_DISABLE_THREADS in some, but not all, translation units is technically a violation of the One Definition Rule and undefined behavior. Nevertheless, the implementation attempts to do its best to accommodate the request to use non-atomic updates in those translation units. No guarantees, though.)
+
+You can define the macro BOOST_SP_USE_PTHREADS to turn off the lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based code.
+
+[endsect]
+
+[section Frequently Asked Questions]
+
+[*Q.] There are several variations of shared pointers, with different tradeoffs; why does the smart pointer library supply only a single implementation? It would be useful to be able to experiment with each type so as to find the most suitable for the job at hand?
+
+[*A.] An important goal of shared_ptr is to provide a standard shared-ownership pointer. Having a single pointer type is important for stable library interfaces, since different shared pointers typically cannot interoperate, i.e. a reference counted pointer (used by library A) cannot share ownership with a linked pointer (used by library B.)
+
+[*Q.] Why doesn't __shared_ptr__ have template parameters supplying traits or policies to allow extensive user customization?
+
+[*A.] Parameterization discourages users. The __shared_ptr__ template is carefully crafted to meet common needs without extensive parameterization. Some day a highly configurable smart pointer may be invented that is also very easy to use and very hard to misuse. Until then, __shared_ptr__ is the smart pointer of choice for a wide range of applications. (Those interested in policy based smart pointers should read [@http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1 Modern C++ Design] by Andrei Alexandrescu.)
+
+[*Q.] I am not convinced. Default parameters can be used where appropriate to hide the complexity. Again, why not policies?
+
+[*A.] Template parameters affect the type. See the answer to the first question above.
+
+[*Q.] Why doesn't __shared_ptr__ use a linked list implementation?
+
+[*A.] A linked list implementation does not offer enough advantages to offset the added cost of an extra pointer. See [@smarttests.htm timings] page. In addition, it is expensive to make a linked list implementation thread safe.
+
+[*Q.] Why doesn't __shared_ptr__ (or any of the other Boost smart pointers) supply an automatic conversion to [*T*]?
+
+[*A.] Automatic conversion is believed to be too error prone.
+
+[*Q.] Why does __shared_ptr__ supply use_count()?
+
+[*A.] As an aid to writing test cases and debugging displays. One of the progenitors had use_count(), and it was useful in tracking down bugs in a complex project that turned out to have cyclic-dependencies.
+
+[*Q.] Why doesn't __shared_ptr__ specify complexity requirements?
+
+[*A.] Because complexity requirements limit implementors and complicate the specification without apparent benefit to __shared_ptr__ users. For example, error-checking implementations might become non-conforming if they had to meet stringent complexity requirements.
+
+[*Q.] Why doesn't __shared_ptr__ provide a release() function?
+
+[*A.] __shared_ptr__ cannot give away ownership unless it's unique() because the other copy will still destroy the object.
+
+Consider:
+
+ shared_ptr<int> a(new int);
+ shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
+
+ int * p = a.release();
+
+ // Who owns p now? b will still call delete on it in its destructor.
+
+Furthermore, the pointer returned by [^release()] would be difficult to deallocate reliably, as the source __shared_ptr__ could have been created with a custom deleter.
+
+[*Q.] Why is [^operator->()] const, but its return value is a non-const pointer to the element type?
+
+[*A.] Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the object through it.__shared_ptr__ is "as close to raw pointers as possible but no closer".
+
+[endsect]
+
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file [@../../LICENSE_1_0.txt LICENSE_1_0.txt] or copy at [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt].
+
[endsect][/shared_ptr]
\ No newline at end of file
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/smart_ptr.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/smart_ptr.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/smart_ptr.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -31,7 +31,7 @@
[def __intrusive_ptr_hpp__ [@http://www.boost.org/boost/intrusive_ptr.hpp <boost/intrusive_ptr.hpp>]]
[def __exception-specification__ [@http://www.boost.org/more/lib_guide.htm#Exception-specification exception-specification]]
-[def __noncopyable__ [@http://www.boost.org/doc/html/utility/utility.htm#Class_noncopyable noncopyable]]
+[def __noncopyable__ [@http://www.boost.org/libs/utility/utility.htm#Class_noncopyable noncopyable]]
[def __auto_ptr__ [@http://en.wikipedia.org/wiki/Auto_ptr std::auto_ptr]]
[import ../test/smart_ptr_test.cpp]
Modified: sandbox/boost_docs/trunk/libs/smart_ptr/doc/weak_ptr.qbk
==============================================================================
--- sandbox/boost_docs/trunk/libs/smart_ptr/doc/weak_ptr.qbk (original)
+++ sandbox/boost_docs/trunk/libs/smart_ptr/doc/weak_ptr.qbk 2007-07-06 16:54:00 EDT (Fri, 06 Jul 2007)
@@ -1,2 +1,268 @@
-[section:weak_ptr weak_ptr]
+[section:weak_ptr weak_ptr class template]
+
+[section Introduction]
+
+The [*weak_ptr] class template stores a "weak reference" to an object that's already managed by a __shared_ptr__. To access the object, a weak_ptr can be converted to a shared_ptr using [@shared_ptr.htm#constructors the shared_ptr constructor] or the member function [@#lock lock]. When the last __shared_ptr__ to the object goes away and the object is deleted, the attempt to obtain a shared_ptr from the [*weak_ptr] instances that refer to the deleted object will fail: the constructor will throw an exception of type boost::bad_weak_ptr, and weak_ptr::lock will return an empty shared_ptr.
+
+Every [*weak_ptr] meets the [*CopyConstructible] and [*Assignable] requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that [*weak_ptr] works with the standard library's associative containers.
+
+weak_ptr operations never throw exceptions.
+
+The class template is parameterized on [*T], the type of the object pointed to.
+
+Compared to shared_ptr, weak_ptr provides a very limited subset of operations since accessing its stored pointer is often dangerous in multithreaded programs, and sometimes unsafe even within a single thread (that is, it may invoke undefined behavior.) Pretend for a moment that [*weak_ptr] has a [*get] member function that returns a raw pointer, and consider this innocent piece of code:
+
+ shared_ptr<int> p(new int(5));
+ weak_ptr<int> q(p);
+
+ // some time later
+
+ if(int * r = q.get())
+ {
+ // use *r
+ }
+
+Imagine that after the if, but immediately before r is used, another thread executes the statement [^p.reset()]. Now r is a dangling pointer.
+
+The solution to this problem is to create a temporary shared_ptr from q:
+
+ shared_ptr<int> p(new int(5));
+ weak_ptr<int> q(p);
+
+ // some time later
+
+ if(shared_ptr<int> r = q.[@#lock lock]())
+ {
+ // use *r
+ }
+
+Now r holds a reference to the object that was pointed by q. Even if [^p.reset()] is executed in another thread, the object will stay alive until r goes out of scope or is reset. By obtaining a shared_ptr to the object, we have effectively locked it against destruction.
+
+[endsect]
+
+[section Synopsis]
+
+ namespace boost {
+
+ template<class T> class weak_ptr {
+
+ public:
+ typedef T [@#element_type element_type];
+
+ [@#default-constructor weak_ptr]();
+
+ template<class Y> [@#constructors weak_ptr](shared_ptr<Y> const & r);
+ [@#constructors weak_ptr](weak_ptr const & r);
+ template<class Y> [@#constructors weak_ptr](weak_ptr<Y> const & r);
+
+ [@#destructor ~weak_ptr]();
+
+ weak_ptr & [@#assignment operator=](weak_ptr const & r);
+ template<class Y> weak_ptr & [@#assignment operator=](weak_ptr<Y> const & r);
+ template<class Y> weak_ptr & [@#assignment operator=](shared_ptr<Y> const & r);
+
+ long [@#use_count use_count]() const;
+ bool [@#expired expired]() const;
+ shared_ptr<T> [@#lock lock]() const;
+
+ void __reset__();
+ void [@#swap swap](weak_ptr<T> & b);
+ };
+
+ template<class T, class U>
+ bool [@#comparison operator<](weak_ptr<T> const & a, weak_ptr<U> const & b);
+
+ template<class T>
+ void [@#free-swap swap](weak_ptr<T> & a, weak_ptr<T> & b);
+ }
+
+[endsect]
+
+[section Members]
+
+[heading element_type]
+
+ typedef T element_type;
+
+[:
+
+Provides the type of the template parameter T.
+]
+
+[heading constructors]
+
+ weak_ptr();
+
+[:
+
+[*Effects:] Constructs an empty [*weak_ptr].
+
+[*Postconditions:] [^use_count() == 0].
+
+[*Throws:] nothing.
+]
+
+ template<class Y> weak_ptr(shared_ptr<Y> const & r);
+ weak_ptr(weak_ptr const & r);
+ template<class Y> weak_ptr(weak_ptr<Y> const & r);
+
+[:
+
+[*Effects:] If r is empty, constructs an empty weak_ptr; otherwise, constructs a [*weak_ptr] that shares ownership with r as if by storing a copy of the pointer stored in [*r].
+
+[*Postconditions:] [^use_count() == r.use_count()].
+
+[*Throws:] nothing.
+]
+
+[heading destructor]
+
+ ~weak_ptr();
+
+[:
+
+[*Effects:] Destroys this [*weak_ptr] but has no effect on the object its stored pointer points to.
+
+[*Throws:] nothing.
+]
+
+[heading assignment]
+
+ weak_ptr & operator=(weak_ptr const & r);
+ template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r);
+ template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r);
+
+[:
+
+[*Effects:] Equivalent to [^weak_ptr(r).swap(*this)].
+
+[*Throws:] nothing.
+
+[*Notes:] The implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary.
+]
+
+[heading use_count]
+
+ long use_count() const;
+
+[:
+
+[*Returns:] 0 if *this is empty; otherwise, the number of __shared_ptr__ objects that share ownership with *this.
+
+[*Throws:] nothing.
+
+[*Notes:] [^use_count()] is not necessarily efficient. Use only for debugging and testing purposes, not for production code.
+]
+
+[heading expired]
+
+ bool expired() const;
+
+[:
+
+[*Returns:] [^use_count() == 0].
+
+[*Throws:] nothing.
+
+[*Notes:] [^expired()] may be faster than [^use_count()].
+]
+
+[heading lock]
+
+ shared_ptr<T> lock() const;
+
+[:
+
+[*Returns:] [^expired()? shared_ptr<T>(): shared_ptr<T>(*this)].
+
+[*Throws:] nothing.
+]
+
+[heading reset]
+
+ void reset();
+
+[:
+
+[*Effects:] Equivalent to [^weak_ptr().swap(*this)].
+]
+
+[heading swap]
+
+ void swap(weak_ptr & b);
+
+[:
+
+[*Effects:] Exchanges the contents of the two smart pointers.
+
+[*Throws:] nothing.
+
+]
+
+[endsect]
+
+[section Free Functions]
+
+[heading comparison]
+
+ template<class T, class U>
+ bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);
+
+[:
+
+[*Returns:] an unspecified value such that
+* [*operator<] is a strict weak ordering as described in section 25.3 [^\[lib.alg.sorting\]] of the C++ standard;
+* under the equivalence relation defined by operator<, [^!(a < b) && !(b < a)], two weak_ptr instances are equivalent if and only if they share ownership or are both empty.
+
+[*Throws:] nothing.
+
+[*Notes:] Allows weak_ptr objects to be used as keys in associative containers.
+]
+
+[heading swap]
+
+ template<class T>
+ void swap(weak_ptr<T> & a, weak_ptr<T> & b)
+
+[:
+
+[*Effects:] Equivalent to [^a.swap(b)].
+
+[*Throws:] nothing.
+
+[*Notes:] Matches the interface of [*std::swap]. Provided as an aid to generic programming.
+]
+
+[endsect]
+
+[section Frequently Asked Questions]
+
+[*Q.] Can an object create a weak_ptr to itself in its constructor?
+
+[*A.] No. A weak_ptr can only be created from a shared_ptr, and at object construction time no shared_ptr to the object exists yet. Even if you could create a temporary shared_ptr to this, it would go out of scope at the end of the constructor, and all weak_ptr instances would instantly expire.
+
+The solution is to make the constructor private, and supply a factory function that returns a shared_ptr:
+
+ class X
+ {
+ private:
+
+ X();
+
+ public:
+
+ static shared_ptr<X> create()
+ {
+ shared_ptr<X> px(new X);
+ // create weak pointers from px here
+ return px;
+ }
+ };
+
+[endsect]
+
+$Date: 2007/06/06 16:39:52 $
+
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file [@../../LICENSE_1_0.txt LICENSE_1_0.txt] or copy at [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt].
+
[endsect][/weak_ptr]
\ No newline at end of file
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk