Debug hook support, removed self-reset, fixed #%20links.

[SVN r16361]
This commit is contained in:
Peter Dimov
2002-11-21 13:10:18 +00:00
parent e555d33695
commit e32b2adfda
5 changed files with 69 additions and 41 deletions

View File

@ -9,7 +9,7 @@
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
// See http://www.boost.org/libs/smart_ptr/scoped_array.htm for documentation. // http://www.boost.org/libs/smart_ptr/scoped_array.htm
// //
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -20,6 +20,15 @@
namespace boost namespace boost
{ {
// Debug hooks
#if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
void sp_array_constructor_hook(void * p);
void sp_array_destructor_hook(void * p);
#endif
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit // is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex. // reset(). Use shared_array or std::vector if your needs are more complex.
@ -41,20 +50,23 @@ public:
explicit scoped_array(T * p = 0) : ptr(p) // never throws explicit scoped_array(T * p = 0) : ptr(p) // never throws
{ {
#if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
boost::sp_array_constructor_hook(ptr);
#endif
} }
~scoped_array() // never throws ~scoped_array() // never throws
{ {
checked_array_delete(ptr); #if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
boost::sp_array_destructor_hook(ptr);
#endif
boost::checked_array_delete(ptr);
} }
void reset(T * p = 0) // never throws void reset(T * p = 0) // never throws
{ {
if (ptr != p) BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
{ this_type(p).swap(*this);
checked_array_delete(ptr);
ptr = p;
}
} }
T & operator[](std::ptrdiff_t i) const // never throws T & operator[](std::ptrdiff_t i) const // never throws

View File

@ -9,7 +9,7 @@
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation. // http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
// //
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -22,6 +22,15 @@
namespace boost namespace boost
{ {
// Debug hooks
#if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
void sp_scalar_constructor_hook(void * p);
void sp_scalar_destructor_hook(void * p);
#endif
// scoped_ptr mimics a built-in pointer except that it guarantees deletion // scoped_ptr mimics a built-in pointer except that it guarantees deletion
// of the object pointed to, either on destruction of the scoped_ptr or via // of the object pointed to, either on destruction of the scoped_ptr or via
// an explicit reset(). scoped_ptr is a simple solution for simple needs; // an explicit reset(). scoped_ptr is a simple solution for simple needs;
@ -44,27 +53,34 @@ public:
explicit scoped_ptr(T * p = 0): ptr(p) // never throws explicit scoped_ptr(T * p = 0): ptr(p) // never throws
{ {
#if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook(ptr);
#endif
} }
#ifndef BOOST_NO_AUTO_PTR #ifndef BOOST_NO_AUTO_PTR
explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
{ {
#if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook(ptr);
#endif
} }
#endif #endif
~scoped_ptr() // never throws ~scoped_ptr() // never throws
{ {
checked_delete(ptr); #if defined(BOOST_ENABLE_SP_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook(ptr);
#endif
boost::checked_delete(ptr);
} }
void reset(T * p = 0) // never throws void reset(T * p = 0) // never throws
{ {
if(ptr != p) BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
{ this_type(p).swap(*this);
this_type(p).swap(*this);
}
} }
T & operator*() const // never throws T & operator*() const // never throws

View File

@ -29,7 +29,7 @@
heavier duty but far more flexible. A <b>boost::array</b> is an alternative heavier duty but far more flexible. A <b>boost::array</b> is an alternative
that does not use dynamic allocation.</p> that does not use dynamic allocation.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#Common requirements"> to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<pre>namespace boost { <pre>namespace boost {
@ -40,7 +40,7 @@
typedef T <a href="#element_type">element_type</a>; typedef T <a href="#element_type">element_type</a>;
explicit <a href="#ctor">scoped_array</a>(T * p = 0); // never throws explicit <a href="#ctor">scoped_array</a>(T * p = 0); // never throws
<a href="#~scoped_array">~scoped_array</a>(); // never throws <a href="#destructor">~scoped_array</a>(); // never throws
void <a href="#reset">reset</a>(T * p = 0); // never throws void <a href="#reset">reset</a>(T * p = 0); // never throws
@ -62,23 +62,23 @@
<pre>explicit scoped_array(T * p = 0); // never throws</pre> <pre>explicit scoped_array(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have <p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have
been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not
required be a complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements"> required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h3><a name="~scoped_array">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~scoped_array(); // never throws</pre> <pre>~scoped_array(); // never throws</pre>
<p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on <p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on
a pointer with a value of 0 is harmless. The guarantee that this does not throw a pointer with a value of 0 is harmless. The guarantee that this does not throw
exceptions depends on the requirement that the deleted array's objects' exceptions depends on the requirement that the deleted array's objects'
destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#Common requirements"> destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre> <pre>void reset(T * p = 0); // never throws</pre>
<p>If p is not equal to the stored pointer, deletes the array pointed to by the <p>
stored pointer and then stores a copy of p, which must have been allocated via Deletes the array pointed to by the stored pointer and then stores a copy of p,
a C++ <b>new[]</b> expression or be 0. The guarantee that this does not throw which must have been allocated via a C++ <b>new[]</b> expression or be 0. The
exceptions depends on the requirement that the deleted array's objects' guarantee that this does not throw exceptions depends on the requirement that
destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#Common requirements"> the deleted array's objects' destructors do not throw exceptions. See the smart
common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="operator[]">subscripting</a></h3> <h3><a name="operator[]">subscripting</a></h3>
<pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre> <pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<p>Returns a reference to element <b>i</b> of the array pointed to by the stored <p>Returns a reference to element <b>i</b> of the array pointed to by the stored
@ -88,11 +88,11 @@
<h3><a name="get">get</a></h3> <h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_array &amp; b); // never throws</pre> <pre>void swap(scoped_array &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>

View File

@ -29,7 +29,7 @@
allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for
that usage.</p> that usage.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#Common requirements"> to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<pre>namespace boost { <pre>namespace boost {
@ -62,7 +62,7 @@
<pre>explicit scoped_ptr(T * p = 0); // never throws</pre> <pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been <p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been
allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be
a complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements">common a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~scoped_ptr(); // never throws</pre> <pre>~scoped_ptr(); // never throws</pre>
@ -71,15 +71,15 @@
<P> <P>
The guarantee that this does not throw exceptions depends on the requirement 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 that the deleted object's destructor does not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</P> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</P>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre> <pre>void reset(T * p = 0); // never throws</pre>
<p>If p is not equal to the stored pointer, deletes the object pointed to by the <p>
stored pointer and then stores a copy of p, which must have been allocated via Deletes the object pointed to by the stored pointer and then stores a copy of
a C++ <b>new</b> expression or be 0. The guarantee that this does not throw p, which must have been allocated via a C++ <b>new</b> expression or be 0. The
exceptions depends on the requirement that the deleted object's destructor does guarantee that this does not throw exceptions depends on the requirement that
not throw exceptions. See the smart pointer <a href="smart_ptr.htm#Common requirements"> the deleted object's destructor does not throw exceptions. See the smart
common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="indirection">indirection</a></h3> <h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre> <pre>T &amp; operator*() const; // never throws</pre>
<p>Returns a reference to the object pointed to by the stored pointer. Behavior is <p>Returns a reference to the object pointed to by the stored pointer. Behavior is
@ -89,11 +89,11 @@
<h3><a name="get">get</a></h3> <h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_ptr &amp; b); // never throws</pre> <pre>void swap(scoped_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#Common requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>

View File

@ -56,7 +56,7 @@
versions of the smart pointer implementation.</p> versions of the smart pointer implementation.</p>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest <p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
to those curious about performance issues.</p> to those curious about performance issues.</p>
<h2><a name="Common requirements">Common Requirements</a></h2> <h2><a name="common_requirements">Common Requirements</a></h2>
<p>These smart pointer class templates have a template parameter, <b>T</b>, which <p>These smart pointer class templates have a template parameter, <b>T</b>, which
specifies the type of the object pointed to by the smart pointer. The behavior specifies the type of the object pointed to by the smart pointer. The behavior
of the smart pointer templates is undefined if the destructor or <b>operator delete</b> of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
@ -87,7 +87,7 @@
which resulted in the exception being thrown. This amounts to a guarantee that which resulted in the exception being thrown. This amounts to a guarantee that
there are no detectable side effects. Other functions never throw exceptions. there are no detectable side effects. Other functions never throw exceptions.
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
the <a href="#Common requirements">common requirements</a>) is <b>std::bad_alloc</b>, the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
and that is thrown only by functions which are explicitly documented as and that is thrown only by functions which are explicitly documented as
possibly throwing <b>std::bad_alloc</b>.</p> possibly throwing <b>std::bad_alloc</b>.</p>
<h2>Exception-specifications</h2> <h2>Exception-specifications</h2>
@ -99,7 +99,7 @@
// never throws</code>. // never throws</code>.
</p> </p>
<p>Functions which destroy objects of the pointed to type are prohibited from <p>Functions which destroy objects of the pointed to type are prohibited from
throwing exceptions by the <a href="#Common requirements">common requirements</a>.</p> throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
<h2>History and Acknowledgements</h2> <h2>History and Acknowledgements</h2>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing <p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>. bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
@ -156,7 +156,7 @@
users", and in the end we choose to supply only the direct implementation.</p> users", and in the end we choose to supply only the direct implementation.</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan <p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan
--> -->
4 February 2002<!--webbot bot="Timestamp" endspan i-checksum="40737" 4 February 2002<!--webbot bot="Timestamp" endspan i-checksum="40737"
--></p> --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.