From 0dfb4dad0fe54957c1000f9131972831ae4da130 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 12 Jun 2017 01:58:08 +0300 Subject: [PATCH] Start rewriting documentation in asciidoc --- compatibility.htm | 88 --- doc/Jamfile | 26 + doc/asciidoctor.jam | 50 ++ doc/smart_ptr-docinfo-footer.html | 33 + doc/smart_ptr.adoc | 70 ++ doc/smart_ptr/enable_shared_from_this.adoc | 15 + doc/smart_ptr/history.adoc | 89 +++ doc/smart_ptr/introduction.adoc | 49 ++ doc/smart_ptr/intrusive_ptr.adoc | 15 + doc/smart_ptr/intrusive_ref_counter.adoc | 15 + doc/smart_ptr/make_shared.adoc | 15 + doc/smart_ptr/make_unique.adoc | 15 + doc/smart_ptr/pointer_cast.adoc | 15 + doc/smart_ptr/pointer_to_other.adoc | 15 + doc/smart_ptr/scoped_array.adoc | 15 + doc/smart_ptr/scoped_ptr.adoc | 15 + doc/smart_ptr/shared_array.adoc | 15 + doc/smart_ptr/shared_ptr.adoc | 15 + doc/smart_ptr/techniques.adoc | 15 + doc/smart_ptr/weak_ptr.adoc | 15 + enable_shared_from_this.html | 110 --- gccspeed.gif | Bin 6603 -> 0 bytes index.html | 12 +- intrusive_ptr.html | 320 -------- intrusive_ref_counter.html | 94 --- make_shared.html | 119 --- make_shared_array.html | 393 ---------- make_unique.html | 184 ----- msvcspeed.gif | Bin 6169 -> 0 bytes pointer_cast.html | 183 ----- pointer_to_other.html | 108 --- scoped_array.htm | 115 --- scoped_ptr.htm | 180 ----- shared_array.htm | 183 ----- shared_ptr.htm | 858 --------------------- smart_ptr.htm | 224 ------ smarttest.zip | Bin 11513 -> 0 bytes smarttests.htm | 542 ------------- sp_techniques.html | 765 ------------------ weak_ptr.htm | 240 ------ 40 files changed, 518 insertions(+), 4712 deletions(-) delete mode 100644 compatibility.htm create mode 100644 doc/Jamfile create mode 100644 doc/asciidoctor.jam create mode 100644 doc/smart_ptr-docinfo-footer.html create mode 100644 doc/smart_ptr.adoc create mode 100644 doc/smart_ptr/enable_shared_from_this.adoc create mode 100644 doc/smart_ptr/history.adoc create mode 100644 doc/smart_ptr/introduction.adoc create mode 100644 doc/smart_ptr/intrusive_ptr.adoc create mode 100644 doc/smart_ptr/intrusive_ref_counter.adoc create mode 100644 doc/smart_ptr/make_shared.adoc create mode 100644 doc/smart_ptr/make_unique.adoc create mode 100644 doc/smart_ptr/pointer_cast.adoc create mode 100644 doc/smart_ptr/pointer_to_other.adoc create mode 100644 doc/smart_ptr/scoped_array.adoc create mode 100644 doc/smart_ptr/scoped_ptr.adoc create mode 100644 doc/smart_ptr/shared_array.adoc create mode 100644 doc/smart_ptr/shared_ptr.adoc create mode 100644 doc/smart_ptr/techniques.adoc create mode 100644 doc/smart_ptr/weak_ptr.adoc delete mode 100644 enable_shared_from_this.html delete mode 100644 gccspeed.gif delete mode 100644 intrusive_ptr.html delete mode 100644 intrusive_ref_counter.html delete mode 100644 make_shared.html delete mode 100644 make_shared_array.html delete mode 100644 make_unique.html delete mode 100644 msvcspeed.gif delete mode 100644 pointer_cast.html delete mode 100644 pointer_to_other.html delete mode 100644 scoped_array.htm delete mode 100644 scoped_ptr.htm delete mode 100644 shared_array.htm delete mode 100644 shared_ptr.htm delete mode 100644 smart_ptr.htm delete mode 100644 smarttest.zip delete mode 100644 smarttests.htm delete mode 100644 sp_techniques.html delete mode 100644 weak_ptr.htm diff --git a/compatibility.htm b/compatibility.htm deleted file mode 100644 index 6f57e4d..0000000 --- a/compatibility.htm +++ /dev/null @@ -1,88 +0,0 @@ - - - - Smart Pointer Changes - - - -

boost.png (6897 bytes)Smart Pointer Changes

-

The February 2002 change to the Boost smart pointers introduced a number of - changes. Since the previous version of the smart pointers was in use for a long - time, it's useful to have a detailed list of what changed from a library user's - point of view.

-

Note that for compilers that don't support member templates well enough, a - separate implementation is used that lacks many of the new features and is more - like the old version.

-

Features Requiring Code Changes to Take Advantage

- -

Features That Improve Robustness

- -

Implementation Details

- -
-

$Date$

-

Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/doc/Jamfile b/doc/Jamfile new file mode 100644 index 0000000..b6d2c35 --- /dev/null +++ b/doc/Jamfile @@ -0,0 +1,26 @@ +# Copyright 2017 Peter Dimov +# +# Distributed under the Boost Software License, Version 1.0. +# +# See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt + +project doc/smart_ptr ; + +import asciidoctor ; + +html smart_ptr.html : smart_ptr.adoc ; + +install html_ : smart_ptr.html : html ; + +pdf smart_ptr.pdf : smart_ptr.adoc ; +explicit smart_ptr.pdf ; + +install pdf_ : smart_ptr.pdf : pdf ; +explicit pdf_ ; + +############################################################################### +alias boostdoc ; +explicit boostdoc ; +alias boostrelease : html_ ; +explicit boostrelease ; diff --git a/doc/asciidoctor.jam b/doc/asciidoctor.jam new file mode 100644 index 0000000..488670d --- /dev/null +++ b/doc/asciidoctor.jam @@ -0,0 +1,50 @@ +# Copyright 2017 Peter Dimov +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import type ; +import scanner ; +import generators ; +import boostbook ; + +# File type + +type.register ASCIIDOC : asciidoc adoc ; + +# Define dependency scanner + +class asciidoc-scanner : common-scanner +{ + rule pattern ( ) + { + return "include::([^[]+)\\[" ; + } +} + +scanner.register asciidoc-scanner : include ; +type.set-scanner ASCIIDOC : asciidoc-scanner ; + +# Define generators + +generators.register-standard asciidoctor.asciidoc-to-html : ASCIIDOC : HTML ; +generators.register-standard asciidoctor.asciidoc-to-pdf : ASCIIDOC : PDF ; +# generators.register-standard asciidoctor.asciidoc-to-docbook : ASCIIDOC : DOCBOOK ; + +# Define actions + +actions asciidoc-to-html +{ + asciidoctor -b html -o $(1) $(2) +} + +actions asciidoc-to-pdf +{ + asciidoctor -r asciidoctor-pdf -b pdf -o $(1) $(2) +} + +actions asciidoc-to-docbook +{ + asciidoctor -b docbook -o $(1) $(2) +} diff --git a/doc/smart_ptr-docinfo-footer.html b/doc/smart_ptr-docinfo-footer.html new file mode 100644 index 0000000..8cf495c --- /dev/null +++ b/doc/smart_ptr-docinfo-footer.html @@ -0,0 +1,33 @@ + + + diff --git a/doc/smart_ptr.adoc b/doc/smart_ptr.adoc new file mode 100644 index 0000000..e85479b --- /dev/null +++ b/doc/smart_ptr.adoc @@ -0,0 +1,70 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +# Boost.SmartPtr: Smart Pointer Library +Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes +:toc: left +:toclevels: 3 +:idprefix: +:listing-caption: Code Example +:table-caption: Illustration +:docinfo: private-footer + +:leveloffset: +1 + +include::smart_ptr/introduction.adoc[] + +include::smart_ptr/scoped_ptr.adoc[] + +include::smart_ptr/scoped_array.adoc[] + +include::smart_ptr/shared_ptr.adoc[] + +include::smart_ptr/weak_ptr.adoc[] + +include::smart_ptr/make_shared.adoc[] + +include::smart_ptr/enable_shared_from_this.adoc[] + +include::smart_ptr/make_unique.adoc[] + +include::smart_ptr/intrusive_ptr.adoc[] + +include::smart_ptr/intrusive_ref_counter.adoc[] + +include::smart_ptr/pointer_cast.adoc[] + +include::smart_ptr/pointer_to_other.adoc[] + +// appendix +include::smart_ptr/techniques.adoc[] + +// appendix +include::smart_ptr/history.adoc[] + +// appendix, deprecated +include::smart_ptr/shared_array.adoc[] + +:leveloffset: -1 + +[appendix] +## Copyright and License + +This documentation is + +* Copyright 1999 Greg Colvin +* Copyright 1999 Beman Dawes +* Copyright 2002 Darin Adler +* Copyright 2003-2017 Peter Dimov +* Copyright 2005, 2006 Ion Gaztañaga +* Copyright 2008 Frank Mori Hess +* Copyright 2012-2017 Glen Fernandes +* Copyright 2013 Andrey Semashev + +and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. diff --git a/doc/smart_ptr/enable_shared_from_this.adoc b/doc/smart_ptr/enable_shared_from_this.adoc new file mode 100644 index 0000000..5b385cb --- /dev/null +++ b/doc/smart_ptr/enable_shared_from_this.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#enable_shared_from_this] +# enable_shared_from_this +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/history.adoc b/doc/smart_ptr/history.adoc new file mode 100644 index 0000000..ffdb9af --- /dev/null +++ b/doc/smart_ptr/history.adoc @@ -0,0 +1,89 @@ +//// +Copyright 1999 Greg Colvin and Beman Dawes +Copyright 2002 Darin Adler +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[appendix,#history] +# History and Acknowledgments +:idprefix: + +## Summer 1994 + +Greg Colvin http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf[proposed] +to the {cpp} Standards Committee classes named `auto_ptr` and `counted_ptr` which were very +similar to what we now call `scoped_ptr` and `shared_ptr`. In one of the very few cases +where the Library Working Group's recommendations were not followed by the full committee, +`counted_ptr` was rejected and surprising transfer-of-ownership semantics were added to `auto_ptr`. + +## October 1998 + +Beman Dawes proposed reviving the original semantics under the names `safe_ptr` and `counted_ptr`, +meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, +Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new class +names were finalized, it was decided that there was no need to exactly follow the `std::auto_ptr` +interface, and various function signatures and semantics were finalized. + +Over the next three months, several implementations were considered for `shared_ptr`, and discussed +on the http://www.boost.org/[boost.org] mailing list. The implementation questions revolved around +the reference count which must be kept, either attached to the pointed to object, or detached elsewhere. +Each of those variants have themselves two major variants: + +* Direct detached: the `shared_ptr` contains a pointer to the object, and a pointer to the count. +* Indirect detached: the `shared_ptr` contains a pointer to a helper object, which in turn contains a pointer to the object and the count. +* Embedded attached: the count is a member of the object pointed to. +* Placement attached: the count is attached via operator new manipulations. + +Each implementation technique has advantages and disadvantages. We went so far as to run various timings +of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little +measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kühl +suggested an elegant partial template specialization technique to allow users to choose which implementation +they preferred, and that was also experimented with. + +But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose +to supply only the direct implementation. + +## May 1999 + +In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements. + +## September 1999 + +Luis Coelho provided `shared_ptr::swap` and `shared_array::swap`. + +## November 1999 + +Darin Adler provided `operator ==`, `operator !=`, and `std::swap` and `std::less` specializations for shared types. + +## May 2001 + +Vladimir Prus suggested requiring a complete type on destruction. Refinement evolved in discussions including Dave Abrahams, +Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others. + +## January 2002 + +Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding +`weak_ptr`. + +## November 2012 + +Glen Fernandes provided implementations of `make_shared` and `allocate_shared` for arrays. They achieve a single allocation +for an array that can be initialized with constructor arguments or initializer lists as well as overloads for default initialization +and no value initialization. + +## February 2014 + +Glen Fernandes updated overloads of `make_shared` and `allocate_shared` to conform to the specification in {cpp} standard paper +http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html[N3870], +and implemented `make_unique` for arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and array implementations, +respectively, to resolve {cpp} standard library defect 2070. + +## February 2017 + +Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more optimal and more maintainable implementation. + diff --git a/doc/smart_ptr/introduction.adoc b/doc/smart_ptr/introduction.adoc new file mode 100644 index 0000000..dec424e --- /dev/null +++ b/doc/smart_ptr/introduction.adoc @@ -0,0 +1,49 @@ +//// +Copyright 1999 Greg Colvin and Beman Dawes +Copyright 2002 Darin Adler +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#introduction] +# Introduction +:toc: +:toc-title: +:idprefix: + +Smart pointers are objects which store pointers to dynamically allocated (heap) objects. +They behave much like built-in {cpp} pointers except that they automatically delete the object +pointed to at the appropriate time. Smart pointers are particularly useful in the face of +exceptions as they ensure proper destruction of dynamically allocated objects. They can also be +used to keep track of dynamically allocated objects shared by multiple owners. + +Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for +deletion of the object when it is no longer needed. As such, they are examples of the "resource +acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language", +3rd edition, Section 14.4, Resource Management. + +This library provides five smart pointer class templates: + +* `scoped_ptr`, used to contain ownership of a dynamically allocated object to the current scope; +* `scoped_array`, which provides scoped ownership for a dynamically allocated array; +* `shared_ptr`, a versatile tool for managing shared ownership of an object or array; +* `weak_ptr`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr; +* `intrusive_ptr`, a pointer to objects with an embedded reference count. + +`shared_ptr` and `weak_ptr` are part of the {cpp} standard since its 2011 iteration. + +In addition, the library contains the following supporting utility functions and classes: + +* `make_shared`, a factory function for creating objects that returns a `shared_ptr`; +* `make_unique`, a factory function returning `std::unique_ptr`; +* `enable_shared_from_this`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`; +* `pointer_to_other`, a helper trait for converting one smart pointer type to another; +* `static_pointer_cast` and companions, generic smart pointer casts; +* `intrusive_ref_counter`, a helper base class containing a reference count. + +As a general rule, the destructor or `operator delete` for an object managed by pointers in the library +are not allowed to throw exceptions. diff --git a/doc/smart_ptr/intrusive_ptr.adoc b/doc/smart_ptr/intrusive_ptr.adoc new file mode 100644 index 0000000..6bf4843 --- /dev/null +++ b/doc/smart_ptr/intrusive_ptr.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#intrusive_ptr] +# intrusive_ptr +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/intrusive_ref_counter.adoc b/doc/smart_ptr/intrusive_ref_counter.adoc new file mode 100644 index 0000000..4a9885a --- /dev/null +++ b/doc/smart_ptr/intrusive_ref_counter.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#intrusive_ref_counter] +# intrusive_ref_counter +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/make_shared.adoc b/doc/smart_ptr/make_shared.adoc new file mode 100644 index 0000000..2531cfe --- /dev/null +++ b/doc/smart_ptr/make_shared.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#make_shared] +# make_shared +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/make_unique.adoc b/doc/smart_ptr/make_unique.adoc new file mode 100644 index 0000000..9cfec90 --- /dev/null +++ b/doc/smart_ptr/make_unique.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#make_unique] +# make_unique +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/pointer_cast.adoc b/doc/smart_ptr/pointer_cast.adoc new file mode 100644 index 0000000..3041eeb --- /dev/null +++ b/doc/smart_ptr/pointer_cast.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#pointer_cast] +# Generic Pointer Casts +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/pointer_to_other.adoc b/doc/smart_ptr/pointer_to_other.adoc new file mode 100644 index 0000000..4c4f74d --- /dev/null +++ b/doc/smart_ptr/pointer_to_other.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#pointer_to_other] +# pointer_to_other +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/scoped_array.adoc b/doc/smart_ptr/scoped_array.adoc new file mode 100644 index 0000000..9374caa --- /dev/null +++ b/doc/smart_ptr/scoped_array.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#scoped_array] +# scoped_array +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/scoped_ptr.adoc b/doc/smart_ptr/scoped_ptr.adoc new file mode 100644 index 0000000..ba71827 --- /dev/null +++ b/doc/smart_ptr/scoped_ptr.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#scoped_ptr] +# scoped_ptr +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/shared_array.adoc b/doc/smart_ptr/shared_array.adoc new file mode 100644 index 0000000..564747f --- /dev/null +++ b/doc/smart_ptr/shared_array.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[appendix,#shared_array] +# shared_array (deprecated) +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/shared_ptr.adoc b/doc/smart_ptr/shared_ptr.adoc new file mode 100644 index 0000000..50e38a0 --- /dev/null +++ b/doc/smart_ptr/shared_ptr.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#shared_ptr] +# shared_ptr +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/techniques.adoc b/doc/smart_ptr/techniques.adoc new file mode 100644 index 0000000..13a9b18 --- /dev/null +++ b/doc/smart_ptr/techniques.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[appendix,#techniques] +# Smart Pointer Programming Techniques +:toc: +:toc-title: +:idprefix: + diff --git a/doc/smart_ptr/weak_ptr.adoc b/doc/smart_ptr/weak_ptr.adoc new file mode 100644 index 0000000..ceb28cf --- /dev/null +++ b/doc/smart_ptr/weak_ptr.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2017 Peter Dimov + +Distributed under the Boost Software License, Version 1.0. + +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +//// + +[#weak_ptr] +# weak_ptr +:toc: +:toc-title: +:idprefix: + diff --git a/enable_shared_from_this.html b/enable_shared_from_this.html deleted file mode 100644 index f04f312..0000000 --- a/enable_shared_from_this.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - enable_shared_from_this - - - -

boost.png (6897 bytes)enable_shared_from_this

-

Purpose

-

- The header <boost/enable_shared_from_this.hpp> defines - the class template enable_shared_from_this. It is used as a - base class that allows a shared_ptr or - a weak_ptr to the current object to be obtained - from within a member function. -

-

enable_shared_from_this<T> defines two member functions - called shared_from_this that return a shared_ptr<T> - and shared_ptr<T const>, depending on constness, to this. - It also defines two member functions called weak_from_this that return - a corresponding weak_ptr. -

-

Example

-
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/shared_ptr.hpp>
-#include <cassert>
-
-class Y: public boost::enable_shared_from_this<Y>
-{
-public:
-
-    boost::shared_ptr<Y> f()
-    {
-        return shared_from_this();
-    }
-};
-
-int main()
-{
-    boost::shared_ptr<Y> p(new Y);
-    boost::shared_ptr<Y> q = p->f();
-    assert(p == q);
-    assert(!(p < q || q < p)); // p and q must share ownership
-}
-
-

Synopsis

-
-namespace boost
-{
-
-template<class T> class enable_shared_from_this
-{
-public:
-
-    shared_ptr<T> shared_from_this();
-    shared_ptr<T const> shared_from_this() const;
-
-    weak_ptr<T> weak_from_this() noexcept;
-    weak_ptr<T const> weak_from_this() const noexcept;
-}
-
-}
-
-

template<class T> shared_ptr<T> - enable_shared_from_this<T>::shared_from_this();

-

template<class T> shared_ptr<T const> - enable_shared_from_this<T>::shared_from_this() const;

-
-

- Requires: enable_shared_from_this<T> must be an - accessible base class of T. *this must be a subobject - of an instance t of type T. -

-

- Returns: If a shared_ptr instance p that owns - t exists, a shared_ptr<T> instance r that shares - ownership with p. -

-

- Postconditions: r.get() == this. -

-

- Throws: bad_weak_ptr when no shared_ptr owns *this. -

-
-

template<class T> weak_ptr<T> - enable_shared_from_this<T>::weak_from_this() noexcept;

-

template<class T> weak_ptr<T const> - enable_shared_from_this<T>::weak_from_this() const noexcept;

-
-

- Requires: enable_shared_from_this<T> must be an - accessible base class of T. *this must be a subobject - of an instance t of type T. -

-

- Returns: If a shared_ptr instance p that owns - t exists or has existed in the past, a weak_ptr<T> instance - r that shares ownership with p. Otherwise, an empty weak_ptr. -

-
-
-

- Copyright © 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/gccspeed.gif b/gccspeed.gif deleted file mode 100644 index d78c06bbf8b6b72380950b597c32ada51e5186b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6603 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 XE|U^`I^D$cj~KekmiOo=FjxZs3WTu? diff --git a/index.html b/index.html index 0551e3c..7afe664 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - + -Smart Pointers - - + - + +

Automatic redirection failed, please go to -smart_ptr.htm. +doc/html/smart_ptr.html. +

>(std::allocator<int>(), 8); - - -
-

template<class T, class A>
shared_ptr<T> -allocate_shared(const A& a);

-
-
Returns:
-
A shared_ptr to a value-initialized object of type -E[N].
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::allocate_shared<int[8]>(std::allocator<int>());
-
-
-
-

template<class T, class A>
shared_ptr<T> -allocate_shared(const A& a, std::size_t n, -const E& v);

-
-
Returns:
-
A shared_ptr to an object of type -E[size], where each array element of type E is -initialized to v.
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::allocate_shared<double[]>(std::allocator<double>(), 8, 1.0);
-
-
-
-

template<class T, class A>
shared_ptr<T> -allocate_shared(const A& a, const E& v);

-
-
Returns:
-
A shared_ptr to an object of type E[N], -where each array element of type E is initialized to -v.
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::allocate_shared<double[8]>(std::allocator<double>(), 1.0);
-
-
-
-

template<class T, class A>
shared_ptr<T> -allocate_shared_noinit(const A& a, std::size_t n);

-
-
Returns:
-
A shared_ptr to a default-initialized object of type -E[size].
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::allocate_shared_noinit<int[]>(std::allocator<int>(), 8);
-
-
-
-

template<class T, class A>
shared_ptr<T> -allocate_shared_noinit(const A& a);

-
-
Returns:
-
A shared_ptr to a default-initialized object of type -E[N].
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::allocate_shared_noinit<int[8]>(std::allocator<int>());
-
-
-
-

template<class T>
shared_ptr<T> -make_shared(std::size_t n);

-
-
Returns:
-
allocate_shared<T>(std::allocator<S>(), n);
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::make_shared<int[]>(8);
-
-
-
-

template<class T>
shared_ptr<T> -make_shared();

-
-
Returns:
-
allocate_shared<T>(std::allocator<S>());
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::make_shared<int[8]>();
-
-
-
-

template<class T>
shared_ptr<T> -make_shared(std::size_t n, const E& v);

-
-
Returns:
-
allocate_shared<T>(std::allocator<S>(), n, v);
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::make_shared<double[]>(8, 1.0);
-
-
-
-

template<class T>
shared_ptr<T> -make_shared(const E& v);

-
-
Returns:
-
allocate_shared<T>(std::allocator<S>(), v);
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::make_shared<double[8]>(1.0);
-
-
-

template<class T>
shared_ptr<T> -make_shared_noinit(std::size_t n);

-
-
Returns:
-
allocate_shared_noinit<T>(std::allocator<S>(), n);
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::make_shared_noinit<int[]>(8);
-
-
-
-

template<class T>
shared_ptr<T> -make_shared_noinit();

-
-
Returns:
-
allocate_shared_noinit<T>(std::allocator<S>());
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[N].
-
Example:
-
boost::make_shared_noinit<int[8]>();
-
-
- -
-

History

-
-
Boost 1.64
-
Glen Fernandes rewrote allocate_shared and make_shared for a more -optimal and more maintainable implementation.
-
Boost 1.56
-
Glen Fernandes updated overloads of make_shared and allocate_shared -to conform to the specification in C++ standard paper -N3870, including resolving C++ standard library -defect report DR 2070.
-
Boost 1.53
-
Glen Fernandes contributed implementations of make_shared and -allocate_shared for arrays.
-
-
-
-

References

-
    -
  1. N3870, -Extending make_shared to Support Arrays, Revision 1, Peter Dimov -& Glen Fernandes, January, 2014.
  2. -
  3. DR 2070, - -allocate_shared should use allocator_traits<A>::construct, -Jonathan Wakely, July, 2011.
  4. -
-
-
-Copyright 2012-2017 Glen Fernandes. Distributed under the -Boost Software License, -Version 1.0. - - diff --git a/make_unique.html b/make_unique.html deleted file mode 100644 index fdd5fd9..0000000 --- a/make_unique.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - -make_unique - - -

make_unique

- -
-

Introduction

-

-The header file <boost/make_unique.hpp> provides overloads of -function template make_unique for convenient creation of -std::unique_ptr objects. -

-
-
-

Synopsis

-
-

Header <boost/smart_ptr/make_unique.hpp>

-namespace boost { -
-template<class T>
std::unique_ptr<T> -make_unique();
-
-
-template<class T, class... Args>
std::unique_ptr<T> -make_unique(Args&&... args);
-
-
-template<class T>
std::unique_ptr<T> -make_unique(T&& value);
-
-
-template<class T>
std::unique_ptr<T> -make_unique(std::size_t size);
-
-
-template<class T>
std::unique_ptr<T> -make_unique_noinit();
-
-
-template<class T>
std::unique_ptr<T> -make_unique_noinit(std::size_t size);
-
-} -
-
-
-

Common Requirements

-

template<class T, Args>
-std::unique_ptr<T> make_unique(args);

-
-
Effects:
-
Allocates storage for an object of type T (or -E[size] when T is E[], where -size is determined from args as specified by -the concrete overload). The storage is initialized from -args as specified by the concrete overload. If an exception -is thrown, the functions have no effect.
-
Returns:
-
A std::unique_ptr instance that stores and owns the -address of the newly allocated and constructed object.
-
Postconditions:
-
r.get() != 0, where r is the return -value.
-
Throws:
-
std::bad_alloc, or an exception thrown from the -initialization of the object.
-
Remarks:
-
-
    -
  • When an object of a scalar type T is specified to be initialized to -a value value, or to T(args...), where -args... is a list of constructor arguments, -make_unique shall perform this initialization via the -expression new T(value) or new T(args...) -respectively.
  • -
  • When an object of type T is specified to be -value-initialized, make_unique shall perform this -initialization via the expression new T().
  • -
  • When an object of type T is specified to be -default-initialized, make_unique_noinit shall perform this -initialization via the expression new T.
  • -
-
-
-
-
-

Free functions

-
-

template<class T, class... Args>
-std::unique_ptr<T> -make_unique(Args&&... args);

-
-
Returns:
-
A std::unique_ptr to an object of type T, -initialized to std::forward<Args>(args)....
-
Remarks:
-
This overload shall only participate in overload resolution when -T is not an array type.
-
Example:
-
boost::make_unique<double>(1.0);
-
-
-
-

template<class T>
std::unique_ptr<T> -make_unique(T&& value);

-
-
Returns:
-
A std::unique_ptr to an object of type T, -initialized to std::move(value).
-
Remarks:
-
This overload shall only participate in overload resolution when -T is not an array type.
-
Example:
-
boost::make_unique<point>({1.0, -1.0});
-
-
-

template<class T>
std::unique_ptr<T> -make_unique(std::size_t size);

-
-
Returns:
-
A std::unique_ptr to a value-initialized object of type -E[size].
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::make_unique<int[]>(8);
-
-
-
-

template<class T>
std::unique_ptr<T> -make_unique_noinit();

-
-
Returns:
-
A std::unique_ptr to a default-initialized object of -type T.
-
Remarks:
-
This overload shall only participate in overload resolution when -T is not an array type.
-
Example:
-
boost::make_unique_noinit<std::tm>();
-
-
-
-

template<class T>
std::unique_ptr<T> -make_unique_noinit(std::size_t size);

-
-
Returns:
-
A std::unique_ptr to a default-initialized object of -type E[size].
-
Remarks:
-
This overload shall only participate in overload resolution when -T is of the form E[].
-
Example:
-
boost::make_unique_noinit<char[]>(64);
-
-
-
-
-

History

-
-
Boost 1.56
-
Glen Fernandes contributed implementations of make_unique for -scalars and arrays
-
-
-
-Copyright 2012-2014 Glen Fernandes. Distributed under the -Boost Software License, -Version 1.0. - - diff --git a/msvcspeed.gif b/msvcspeed.gif deleted file mode 100644 index 56295ee9a506c65a672bf105bb1a0f357377f579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6169 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 - - - pointer_cast - - - -

boost.png (6897 bytes)pointer_cast

-

The pointer cast functions (boost::static_pointer_cast boost::dynamic_pointer_cast - boost::reinterpret_pointer_cast boost::const_pointer_cast) - provide a way to write generic pointer castings for raw pointers, std::shared_ptr and std::unique_ptr. The functions - are defined in boost/pointer_cast.hpp.

-

There is test/example code in pointer_cast_test.cpp.

-

Rationale

-

Boost smart pointers usually overload those functions to provide a mechanism to - emulate pointers casts. For example, boost::shared_ptr<...> implements - a static pointer cast this way:

-
-template<class T, class U>
-    shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
-
-

Pointer cast functions from boost/pointer_cast.hpp - are overloads of boost::static_pointer_cast, boost::dynamic_pointer_cast, - boost::reinterpret_pointer_cast and boost::const_pointer_cast - for raw pointers, std::shared_ptr and std::unique_ptr. This way when developing - pointer type independent classes, for example, memory managers or shared memory compatible classes, the same - code can be used for raw and smart pointers.

-

Synopsis

-
-
-namespace boost {
-
-template<class T, class U>
-inline T* static_pointer_cast(U *ptr)
-  { return static_cast<T*>(ptr); }
-
-template<class T, class U>
-inline T* dynamic_pointer_cast(U *ptr)
-  { return dynamic_cast<T*>(ptr); }
-
-template<class T, class U>
-inline T* const_pointer_cast(U *ptr)
-  { return const_cast<T*>(ptr); }
-
-template<class T, class U>
-inline T* reinterpret_pointer_cast(U *ptr)
-  { return reinterpret_cast<T*>(ptr); }
-
-template<class T, class U>
-inline std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U> const& r);
-
-template<class T, class U>
-inline std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> const& r);
-
-template<class T, class U>
-inline std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U> const& r);
-
-template<class T, class U>
-inline std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U> const& r);
-
-template<class T, class U>
-inline std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U>&& r);
-
-template<class T, class U>
-inline std::unique_ptr<T> dynamic_pointer_cast(std::unique_ptr<U>&& r);
-
-template<class T, class U>
-inline std::unique_ptr<T> const_pointer_cast(std::unique_ptr<U>&& r);
-
-template<class T, class U>
-inline std::unique_ptr<T> reinterpret_pointer_cast(std::unique_ptr<U>&& r);
-  
-} // namespace boost
-
-
-

As you can see from the above synopsis, the pointer cast functions for raw pointers are just - wrappers around standard C++ cast operators.

- -

The pointer casts for std::shared_ptr are aliases of the corresponding standard - functions with the same names and equivalent to the - functions taking boost::shared_ptr.

- -

The pointer casts for std::unique_ptr are documented below.

- -

static_pointer_cast

-
template<class T, class U>
-  unique_ptr<T> static_pointer_cast(unique_ptr<U>&& r); // never throws
-
-

Requires: The expression static_cast<T*>( (U*)0 ) - must be well-formed.

-

Returns: unique_ptr<T>( static_cast<typename unique_ptr<T>::element_type*>(r.release()) ).

-

Throws: nothing.

-

Notes: the seemingly equivalent expression - unique_ptr<T>(static_cast<T*>(r.get())) - will eventually result in undefined behavior, attempting to delete the same - object twice.

-
-

const_pointer_cast

-
template<class T, class U>
-  unique_ptr<T> const_pointer_cast(unique_ptr<U>&& r); // never throws
-
-

Requires: The expression const_cast<T*>( (U*)0 ) - must be well-formed.

-

Returns: unique_ptr<T>( const_cast<typename unique_ptr<T>::element_type*>(r.release()) ).

-

Throws: nothing.

-
-

dynamic_pointer_cast

-
template<class T, class U>
-  unique_ptr<T> dynamic_pointer_cast(unique_ptr<U>&& r);
-
-

Requires: The expression dynamic_cast<T*>( (U*)0 ) - must be well-formed. T must have a virtual destructor.

-

Returns:

-
    -
  • - When dynamic_cast<typename unique_ptr<T>::element_type*>(r.get()) returns a nonzero value, - unique_ptr<T>(dynamic_cast<typename unique_ptr<T>::element_type*>(r.release()));
  • -
  • - Otherwise, unique_ptr<T>().
-

Throws: nothing.

-
-

reinterpret_pointer_cast

-
template<class T, class U>
-  unique_ptr<T> reinterpret_pointer_cast(unique_ptr<U>&& r); // never throws
-
-

Requires: The expression reinterpret_cast<T*>( (U*)0 ) - must be well-formed.

-

Returns: unique_ptr<T>( reinterpret_cast<typename unique_ptr<T>::element_type*>(r.release()) ).

-

Throws: nothing.

-
- -

Example

-
-
-#include <boost/pointer_cast.hpp>
-#include <boost/shared_ptr.hpp>
-
-class base
-{
-public:
-
-   virtual ~base()
-   {
-   }
-};
-
-class derived: public base
-{
-};
-
-template <class BasePtr>
-void check_if_it_is_derived(const BasePtr &ptr)
-{
-   assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
-}
-
-int main()
-{
-   // Create a raw and a shared_ptr
-
-   base *ptr = new derived;
-   boost::shared_ptr<base> sptr(new derived);
-   
-   // Check that base pointer points actually to derived class
-
-   check_if_it_is_derived(ptr);
-   check_if_it_is_derived(sptr);
-   
-   // Ok!
-   
-   delete ptr;
-   return 0;
-}
-
-

The example demonstrates how the generic pointer casts help us create pointer - independent code.

-
-

Copyright 2005 Ion Gaztañaga. Use, modification, and distribution are subject to - the Boost Software License, Version 1.0. (See accompanying file - LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)

- - diff --git a/pointer_to_other.html b/pointer_to_other.html deleted file mode 100644 index e9be750..0000000 --- a/pointer_to_other.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - pointer_to_other - - - -

boost.png (6897 bytes)pointer_to_other

-

- The pointer to other utility provides a way, given a source pointer type, - to obtain a pointer of the same type to another pointee type. The utility is - defined in boost/pointer_to_other.hpp.

-

There is test/example code in pointer_to_other_test.cpp.

-

Contents

- -

Rationale

-

When building pointer independent classes, like memory managers, allocators, or - containers, there is often a need to define pointers generically, so that if a - template parameter represents a pointer (for example, a raw or smart pointer to - an int), we can define another pointer of the same type to another pointee (a - raw or smart pointer to a float.)

-
template <class IntPtr>
-class FloatPointerHolder
-{   
-   // Let's define a pointer to a float
-   typedef typename boost::pointer_to_other
-      <IntPtr, float>::type float_ptr_t;
-   float_ptr_t float_ptr;
-};
-

Synopsis

-
-namespace boost {
-
-template<class T, class U>
-   struct pointer_to_other;
-
-template<class T, class U, template <class> class Sp>
-   struct pointer_to_other< Sp<T>, U >
-{
-   typedef Sp<U> type;
-};
-
-template<class T, class T2, class U,
-        template <class, class> class Sp>
-   struct pointer_to_other< Sp<T, T2>, U >
-{
-   typedef Sp<U, T2> type;
-};
-
-template<class T, class T2, class T3, class U,
-        template <class, class, class> class Sp>
-struct pointer_to_other< Sp<T, T2, T3>, U >
-{
-   typedef Sp<U, T2, T3> type;
-};
-
-template<class T, class U>
-struct pointer_to_other< T*, U > 
-{
-   typedef U* type;
-};
-
-} // namespace boost
-

If these definitions are not correct for a specific smart pointer, we can define - a specialization of pointer_to_other.

-

Example

-
// Let's define a memory allocator that can
-// work with raw and smart pointers
-
-#include <boost/pointer_to_other.hpp>
-
-template <class VoidPtr>
-class memory_allocator
-{
-   // Predefine a memory_block 
-   struct block;
-
-   // Define a pointer to a memory_block from a void pointer
-   // If VoidPtr is void *, block_ptr_t is block*
-   // If VoidPtr is smart_ptr<void>, block_ptr_t is smart_ptr<block>
-   typedef typename boost::pointer_to_other      
-            <VoidPtr, block>::type block_ptr_t;
-            
-   struct block
-   {
-      std::size_t size;
-      block_ptr_t next_block;
-   };
-
-   block_ptr_t free_blocks;
-};
-

As we can see, using pointer_to_other we can create pointer independent code.

-
-

$Date$

-

Copyright 2005, 2006 Ion Gaztañaga and Peter Dimov. Use, modification, - and distribution are subject to the Boost Software License, Version 1.0.
- (See accompanying file LICENSE_1_0.txt or a - copy at < http://www.boost.org/LICENSE_1_0.txt>.)

- - diff --git a/scoped_array.htm b/scoped_array.htm deleted file mode 100644 index 3624e5d..0000000 --- a/scoped_array.htm +++ /dev/null @@ -1,115 +0,0 @@ - - - - scoped_array - - - -

boost.png (6897 bytes)scoped_array class template

-

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.

-

Because scoped_array is so simple, in its usual implementation every - operation is as fast as a built-in array pointer and it has no more space - overhead that a built-in array pointer.

-

It cannot be used in C++ standard library containers. See - shared_array if scoped_array does not meet your needs.

-

It cannot correctly hold a pointer to a single object. See scoped_ptr - for that usage.

-

A std::vector is an alternative to a scoped_array that is a bit - heavier duty but far more flexible. A boost::array is an alternative - that does not use dynamic allocation.

-

The class template is parameterized on T, the type of the object pointed - to. T must meet the smart pointer - common requirements.

-

Synopsis

-
namespace boost {
-
-  template<class T> class scoped_array : noncopyable {
-
-    public:
-      typedef T element_type;
-
-      explicit scoped_array(T * p = 0); // never throws
-      ~scoped_array(); // never throws
-
-      void reset(T * p = 0); // never throws
-
-      T & operator[](std::ptrdiff_t i) const; // never throws
-      T * get() const; // never throws
-     
-      operator unspecified-bool-type() const; // never throws
-
-      void swap(scoped_array & b); // never throws
-  };
-
-  template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws
-
-}
-

Members

-

- element_type

-
typedef T element_type;
-

Provides the type of the stored pointer.

-

constructors

-
explicit scoped_array(T * p = 0); // never throws
-

Constructs a scoped_array, 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.

-

destructor

-
~scoped_array(); // never throws
-

Deletes the array pointed to by the stored pointer. Note that delete[] on - 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' - destructors do not throw exceptions. See the smart pointer - common requirements.

-

reset

-
void reset(T * p = 0); // never throws
-

- Deletes the array 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 array's objects' destructors do not throw exceptions. See the smart - pointer common requirements.

-

subscripting

-
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.

-

get

-
T * get() const; // never throws
-

Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.

-

conversions

-
operator unspecified-bool-type () const; // never throws
-

Returns an unspecified value that, when used in boolean contexts, is equivalent - to get() != 0.

-

swap

-
void swap(scoped_array & b); // never throws
-

Exchanges the contents of the two smart pointers. T need not be a - complete type. See the smart pointer common - requirements.

-

Free Functions

-

swap

-
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.

-
-

$Date$

-

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 or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/scoped_ptr.htm b/scoped_ptr.htm deleted file mode 100644 index 1dbfbce..0000000 --- a/scoped_ptr.htm +++ /dev/null @@ -1,180 +0,0 @@ - - - - scoped_ptr - - - -

boost.png (6897 bytes)scoped_ptr class template

-

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.

-

Synopsis

-
namespace boost {
-
-  template<class T> class scoped_ptr : noncopyable {
-
-   public:
-     typedef T element_type;
-
-     explicit scoped_ptr(T * p = 0); // never throws
-     ~scoped_ptr(); // never throws
-
-     void reset(T * p = 0); // never throws
-
-     T & operator*() const; // never throws
-     T * operator->() const; // never throws
-     T * get() const; // never throws
-     
-     operator unspecified-bool-type() const; // never throws
-
-     void swap(scoped_ptr & b); // never throws
-  };
-
-  template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws
-
-}
-

Members

-

element_type

-
typedef T element_type;
-

Provides the type of the stored pointer.

-

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.

-

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.

-

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.

-

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.

-

get

-
T * get() const; // never throws
-

Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.

-

conversions

-
operator unspecified-bool-type () const; // never throws
-

Returns an unspecified value that, when used in boolean contexts, is equivalent - to get() != 0.

-

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.

-

Free Functions

-

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.

-

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:

-
-
1
-2
-Buckle my shoe
-
-

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.

-

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 scoped_ptr_example_test.cpp - sample program includes a header file, 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 scoped_ptr_example.cpp - implementation file.

-

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)

-
-

$Date

-

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 or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/shared_array.htm b/shared_array.htm deleted file mode 100644 index 8fa5a7f..0000000 --- a/shared_array.htm +++ /dev/null @@ -1,183 +0,0 @@ - - - - shared_array - - - -

boost.png (6897 bytes)shared_array class template

-

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.

-

Synopsis

-
namespace boost {
-
-  template<class T> class shared_array {
-
-    public:
-      typedef T element_type;
-
-      explicit shared_array(T * p = 0);
-      template<class D> shared_array(T * p, D d);
-      ~shared_array(); // never throws
-
-      shared_array(shared_array const & r); // never throws
-
-      shared_array & operator=(shared_array const & r); // never throws
-
-      void reset(T * p = 0);
-      template<class D> void reset(T * p, D d);
-
-      T & operator[](std::ptrdiff_t i) const; // never throws
-      T * get() const; // never throws
-
-      bool unique() const; // never throws
-      long use_count() const; // never throws
-
-      operator unspecified-bool-type() const; // never throws
-
-      void swap(shared_array<T> & 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
-  template<class T>
-    bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws
-
-  template<class T> void swap(shared_array<T> & a, shared_array<T> & b); // never throws
-
-}
-

Members

-

element_type

-
typedef T element_type;
-

Provides the type of the stored pointer.

-

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 - ~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.

-

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.

-

assignment

-
shared_array & operator=(shared_array const & r); // never throws
-

Constructs a new shared_array as described above, - then replaces this shared_array with the new one, destroying the - replaced object.

-

reset

-
void reset(T * p = 0);
-

Constructs a new shared_array as described 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 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.

-

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.

-

get

-
T * get() const; // never throws
-

Returns the stored pointer. T need not be a complete type. See the smart - pointer common requirements.

-

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.

-

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.

-

conversions

-
operator unspecified-bool-type () const; // never throws
-

Returns an unspecified value that, when used in boolean contexts, is equivalent - to get() != 0.

-

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.

-

Free Functions

-

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).

-

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.

-
-

$Date$

-

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 or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/shared_ptr.htm b/shared_ptr.htm deleted file mode 100644 index 1cd0bc4..0000000 --- a/shared_ptr.htm +++ /dev/null @@ -1,858 +0,0 @@ - - - - shared_ptr - - - -

boost.png (6897 bytes)shared_ptr class template

-

Introduction
- Best Practices
- Synopsis
- Members
- Free Functions
- Example
- Handle/Body Idiom
- Thread Safety
- Frequently Asked Questions
- Smart Pointer Timings
- Programming Techniques

-

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.

-
Example:
shared_ptr<X> p1( new X );
-shared_ptr<void> p2( new int(5) );
-
- -

shared_ptr deletes the exact pointer that has been passed at construction time, - complete with its original type, regardless of the template parameter. In the second example above, - when p2 is destroyed or reset, it will call delete on the original int* - that has been passed to the constructor, even though p2 itself is of type - shared_ptr<void> and stores a pointer of type void*.

- -

Every shared_ptr meets the CopyConstructible, MoveConstructible, - CopyAssignable and MoveAssignable - requirements of the C++ Standard Library, and can be used in standard - library containers. Comparison operators are supplied so that shared_ptr - works with the standard library's associative containers.

-

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, 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 the C++11 Standard, as std::shared_ptr.

-

Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically - allocated array. This is accomplished by using an array type (T[] or T[N]) as - the template parameter. There is almost no difference between using an unsized array, T[], - and a sized array, T[N]; the latter just enables operator[] to perform a range check - on the index.

-
Example:
shared_ptr<double[1024]> p1( new double[1024] );
-shared_ptr<double[]> p2( new double[n] );
-
- -

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 delete statements; 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_ptrconstructor if g throws an exception. - See Herb Sutter's treatment (also - here) of the issue for more information.

-

The exception safety problem described above may also be eliminated by using - the make_shared - or allocate_shared - factory functions defined in boost/make_shared.hpp. - These factory functions also provide an efficiency benefit by consolidating allocations.

-

Synopsis

-
namespace boost {
-
-  class bad_weak_ptr: public std::exception;
-
-  template<class T> class weak_ptr;
-
-  template<class T> class shared_ptr {
-
-    public:
-
-      typedef see below element_type;
-
-      shared_ptr(); // never throws
-      shared_ptr(std::nullptr_t); // never throws
-
-      template<class Y> explicit shared_ptr(Y * p);
-      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);
-      template<class D> shared_ptr(std::nullptr_t p, D d);
-      template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);
-
-      ~shared_ptr(); // never throws
-
-      shared_ptr(shared_ptr const & r); // never throws
-      template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
-
-      shared_ptr(shared_ptr && r); // never throws
-      template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws
-
-      template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws
-
-      template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p); // never throws
-
-      template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
-
-      template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
-      template<class Y> shared_ptr(std::auto_ptr<Y> && r);
-
-      template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);
-
-      shared_ptr & operator=(shared_ptr const & r); // never throws
-      template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
-
-      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);
-      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);
-
-      template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);
-
-      shared_ptr & operator=(std::nullptr_t); // never throws
-
-      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, element_type * p); // never throws
-
-      T & operator*() const; // never throws; only valid when T is not an array type
-      T * operator->() const; // never throws; only valid when T is not an array type
-
-      element_type & operator[](std::ptrdiff_t i) const; // never throws; only valid when T is an array type
-
-      element_type * get() const; // never throws
-
-      bool unique() const; // never throws
-      long use_count() const; // never throws
-
-      explicit operator bool() const; // never throws
-
-      void swap(shared_ptr & b); // never throws
-      
-      template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws
-      template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws
-  };
-
-  template<class T, class U>
-    bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
-
-  template<class T, class U>
-    bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
-
-  template<class T, class U>
-    bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
-
-  template<class T>
-    bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws
-
-  template<class T>
-    bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws
-
-  template<class T>
-    bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws
-
-  template<class T>
-    bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws
-
-  template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
-
-  template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws
-
-  template<class T, class U>
-    shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws
-
-  template<class T, class U>
-    shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws
-
-  template<class T, class U>
-    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws
-
-  template<class T, class U>
-    shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws
-
-  template<class E, class T, class Y>
-    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
-
-  template<class D, class T>
-    D * get_deleter(shared_ptr<T> const & p);
-}
-

Members

-

element_type

-
typedef ... element_type;
-
-

element_type is T when T is not an array type, - and U when T is U[] or U[N].

-
-

default constructor

-
shared_ptr(); // never throws
-shared_ptr(std::nullptr_t); // 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.]

-

pointer constructor

-
template<class Y> explicit shared_ptr(Y * p);
-
-

Requirements: - Y must be a complete type. - The expression delete[] p, when T is an array type, or delete p, - when T is not an array type, - must be well-formed, must not invoke undefined behavior, and must not throw exceptions. - When T is U[N], Y (*) [N] must be convertible to T*; - when T is U[], Y (*) [] must be convertible to T*; - otherwise, Y* must be convertible to T*. -

-

Effects: - When T is not an array type, constructs a shared_ptr that owns - the pointer p. - Otherwise, constructs a shared_ptr that owns - p and a deleter of an unspecified type that calls delete[] p.

-

Postconditions: use_count() == 1 && get() == p. - If T is not an array type and p is unambiguously convertible to - enable_shared_from_this<V>* - for some V, p->shared_from_this() returns a copy of - *this.

-

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 calls - delete[] p, when T is an array type, - or delete p, when T is not an array type.

-

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 is 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.]

-

constructors taking a deleter

-
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);
-template<class D> shared_ptr(std::nullptr_t p, D d);
-template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);
-
-

Requirements: - 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. - When T is U[N], Y (*) [N] must be convertible to T*; - when T is U[], Y (*) [] must be convertible to T*; - otherwise, Y* must be convertible to T*. -

-

Effects: Constructs a shared_ptr that owns the pointer - p and the deleter d. The constructors taking an allocator a - allocate memory using a copy of a.

-

Postconditions: use_count() == 1 && get() == p. - If T is not an array type and p is unambiguously convertible to - enable_shared_from_this<V>* - for some V, p->shared_from_this() returns a copy of - *this.

-

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 would leak.]

-

copy and converting constructors

-
shared_ptr(shared_ptr const & r); // never throws
-template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
-
-

Requires: Y* should be convertible to T*.

-

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.

-
-

move constructors

-
shared_ptr(shared_ptr && r); // never throws
-template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws
-
-

Requires: Y* should be convertible to T*.

-

Effects: Move-constructs a shared_ptr from r.

-

Postconditions: *this contains the old value of r. r is empty and r.get() == 0.

-

Throws: nothing.

-
-

aliasing constructor

-
template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * 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.

-
-

aliasing move constructor

-
template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p); // never throws
-
-

- Effects: Move-constructs a shared_ptr from r, while - storing p instead. -

-

Postconditions: get() == p and use_count() equals the old count of r. r is empty and r.get() == 0.

-

Throws: nothing.

-
-

weak_ptr constructor

-
template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
-
-

Requires: Y* should be convertible to T*.

-

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.

-
-

auto_ptr constructors

-
template<class Y> shared_ptr(std::auto_ptr<Y> & r);
-template<class Y> shared_ptr(std::auto_ptr<Y> && r);
-
-

Requires: Y* should be convertible to T*.

-

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.

-
-

unique_ptr constructor

-
template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);
-
-

Requires: Y* should be convertible to T*.

-

Effects: - Equivalent to shared_ptr(r.release(), r.get_deleter()) when D is not a reference type. - Otherwise, equivalent to shared_ptr(r.release(), del), where del is a deleter - that stores the reference rd returned from r.get_deleter() and del(p) calls rd(p).

-

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.

-
-

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.

-
-

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.

-
-
shared_ptr & operator=(shared_ptr && r); // never throws
-template<class Y> shared_ptr & operator=(shared_ptr<Y> && r); // never throws
-template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);
-template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);
-
-

Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).

-

Returns: *this.

-
-
shared_ptr & operator=(std::nullptr_t); // never throws
-
-

Effects: Equivalent to shared_ptr().swap(*this).

-

Returns: *this.

-
-

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, element_type * p); // never throws
-
-

Effects: Equivalent to shared_ptr(r, p).swap(*this).

-
-

indirection

-
T & operator*() const; // never throws
-
-

Requirements: T should not be an array type. 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: T should not be an array type. The stored pointer must not be 0.

-

Returns: the stored pointer.

-

Throws: nothing.

-
-
element_type & operator[](std::ptrdiff_t i) const; // never throws
-
-

Requirements: T should be an array type. The stored pointer must not be 0. - i >= 0. If T is U[N], i < N.

-

Returns: get()[i].

-

Throws: nothing.

-
-

get

-
element_type * get() const; // never throws
-
-

Returns: the stored pointer.

-

Throws: nothing.

-
-

unique

-
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.

-
-

use_count

-
long use_count() const; // never throws
-
-

Returns: the number of shared_ptr objects, *this included, - that share ownership with *this, or 0 when *this - is empty.

-

Throws: nothing.

-

Notes: use_count() is not necessarily efficient. Use only - for debugging and testing purposes, not for production code.

-
-

conversions

-
explicit operator bool() const; // never throws
-
-

Returns: get() != 0.

-

Throws: nothing.

-

Notes: This conversion operator allows shared_ptr objects to be - used in boolean contexts, like if(p && p->valid()) {}.

-
-

[The conversion to bool is not merely syntactic sugar. It allows shared_ptrs - to be declared in conditions when using dynamic_pointer_cast - or weak_ptr::lock.]

-

swap

-
void swap(shared_ptr & b); // never throws
-
-

Effects: Exchanges the contents of the two smart pointers.

-

Throws: nothing.

-
-

swap

-
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws
-template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws
-
-

Effects: See the description of operator<.

-

Throws: nothing.

-
-

Free Functions

-

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>
-  bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws
-template<class T>
-  bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws
-
-

Returns: p.get() == 0.

-

Throws: nothing.

-
-
template<class T>
-  bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws
-template<class T>
-  bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws
-
-

Returns: p.get() != 0.

-

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.]

-

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.]

-

get_pointer

-
template<class T>
-  typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws
-
-

Returns: p.get().

-

Throws: nothing.

-

Notes: Provided as an aid to generic programming. Used by - mem_fn.

-
-

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*>( (U*)0 ) - must be well-formed.

-

Returns: shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

-

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.

-
-

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*>( (U*)0 ) - must be well-formed.

-

Returns: shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

-

Throws: nothing.

-
-

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*>( (U*)0 ) - must be well-formed.

-

Returns:

-
    -
  • - When dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) returns a nonzero value p, - shared_ptr<T>(r, p);
  • -
  • - Otherwise, shared_ptr<T>().
-

Throws: nothing.

-
-

reinterpret_pointer_cast

-
template<class T, class U>
-  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws
-
-

Requires: The expression reinterpret_cast<T*>( (U*)0 ) - must be well-formed.

-

Returns: shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

-

Throws: nothing.

-
-

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.

-
-

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.

-

Throws: nothing.

-
-

Example

-

See 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.

-

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 shared_ptr_example2_test.cpp - sample program includes a header file, 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 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.

-

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) simultaneously 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 most common platforms.

-

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.

-

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 - 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 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". -

-
-

$Date$

-

Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005, 2012, 2013 Peter Dimov. Distributed under the Boost Software License, - Version 1.0. See accompanying file LICENSE_1_0.txt - or copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/smart_ptr.htm b/smart_ptr.htm deleted file mode 100644 index 0388cc7..0000000 --- a/smart_ptr.htm +++ /dev/null @@ -1,224 +0,0 @@ - - - - Smart Pointers - - - -

boost.png (6897 bytes)Smart Pointers

-

Introduction
- Common Requirements
- Exception Safety
- Exception-specifications
- History and Acknowledgements
- References

-

Introduction

-

Smart pointers are objects which store pointers to dynamically allocated (heap) - objects. They behave much like built-in C++ pointers except that they - automatically delete the object pointed to at the appropriate time. Smart - pointers are particularly useful in the face of exceptions as they ensure - proper destruction of dynamically allocated objects. They can also be used to - keep track of dynamically allocated objects shared by multiple owners.

-

Conceptually, smart pointers are seen as owning the object pointed to, and thus - responsible for deletion of the object when it is no longer needed.

-

The smart pointer library provides six smart pointer class templates:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
scoped_ptr<boost/scoped_ptr.hpp>Simple sole ownership of single objects. Noncopyable.
scoped_array<boost/scoped_array.hpp>Simple sole ownership of arrays. Noncopyable.
shared_ptr<boost/shared_ptr.hpp>Object ownership shared among multiple pointers.
shared_array<boost/shared_array.hpp>Array ownership shared among multiple pointers.
weak_ptr<boost/weak_ptr.hpp>Non-owning observers of an object owned by shared_ptr.
intrusive_ptr<boost/intrusive_ptr.hpp>Shared ownership of objects with an embedded reference count.
-
-

These templates are designed to complement the std::auto_ptr template.

-

They are examples of the "resource acquisition is initialization" idiom - described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, - Section 14.4, Resource Management.

-

Additionally, the smart pointer library provides efficient factory functions - for creating smart pointer objects:

-
- - - - - - - - - - - - - - - - -
make_shared, allocate_shared for objects<boost/make_shared.hpp>Efficient creation of shared_ptr objects.
make_shared, allocate_shared for arrays<boost/make_shared.hpp>Efficient creation of shared_ptr arrays.
make_unique<boost/make_unique.hpp>Creation of unique_ptr objects and arrays.
-
-

A test program, smart_ptr_test.cpp, is - provided to verify correct operation.

-

A page on compatibility with older versions of - the Boost smart pointer library describes some of the changes since earlier - versions of the smart pointer implementation.

-

A page on smart pointer timings will be of interest - to those curious about performance issues.

-

A page on smart pointer programming techniques lists - some advanced applications of shared_ptr and weak_ptr.

-

Common Requirements

-

These smart pointer class templates have a template parameter, T, which - 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 operator delete - for objects of type T throw exceptions.

-

T may be an incomplete type at the point of smart pointer declaration. - Unless otherwise specified, it is required that T be a complete type at - points of smart pointer instantiation. Implementations are required to diagnose - (treat as an error) all violations of this requirement, including deletion of - an incomplete type. See the description of the - checked_delete function template.

-

Note that shared_ptr does not have this restriction, as most of - its member functions do not require T to be a complete type.

-

Rationale

-

The requirements on T are carefully crafted to maximize safety yet allow - handle-body (also called pimpl) and similar idioms. In these idioms a smart - pointer may appear in translation units where T is an incomplete type. - This separates interface from implementation and hides implementation from - translation units which merely use the interface. Examples described in the - documentation for specific smart pointers illustrate use of smart pointers in - these idioms.

-

Note that scoped_ptr requires that T be a complete type at - destruction time, but shared_ptr does not.

-

Exception Safety

-

Several functions in these smart pointer classes are specified as having "no - effect" or "no effect except such-and-such" if an exception is thrown. This - means that when an exception is thrown by an object of one of these classes, - the entire program state remains the same as it was prior to the function call - which resulted in the exception being thrown. This amounts to a guarantee that - there are no detectable side effects. Other functions never throw exceptions. - The only exception ever thrown by functions which do throw (assuming T meets - the common requirements) is std::bad_alloc, - and that is thrown only by functions which are explicitly documented as - possibly throwing std::bad_alloc.

-

Exception-specifications

-

Exception-specifications are not used; see - exception-specification rationale.

-

All the smart pointer templates contain member functions which can never throw - exceptions, because they neither throw exceptions themselves nor call other - functions which may throw exceptions. These members are indicated by a comment: - // never throws. -

-

Functions which destroy objects of the pointed to type are prohibited from - throwing exceptions by the common requirements.

-

History and Acknowledgements

-

February 2017. Glen Fernandes rewrote allocate_shared - and make_shared for arrays for a more optimal and more - maintainable implementation.

-

February 2014. Glen Fernandes updated overloads of make_shared and - allocate_shared to conform to the specification in C++ standard paper - [D&F-14], and implemented make_unique for - arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and - array implementations, respectively, to resolve C++ standard library defect - 2070.

-

November 2012. Glen Fernandes provided implementations of make_shared - and allocate_shared for arrays. They achieve a single allocation for an - array that can be initialized with constructor arguments or initializer lists - as well as overloads for default initialization and no value initialization. - See the make_shared and allocate_shared for - arrays page for more information.

-

January 2002. Peter Dimov reworked all four classes, adding features, fixing - bugs, and splitting them into four separate headers, and added weak_ptr. - See the compatibility page for a summary of the - changes.

-

May 2001. Vladimir Prus suggested requiring a complete type on destruction. - Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman - Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and - others.

-

November 1999. Darin Adler provided operator ==, operator !=, and std::swap - and std::less specializations for shared types.

-

September 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap

-

May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a - number of suggestions resulting in numerous improvements.

-

October 1998. Beman Dawes proposed reviving the original semantics under the - names safe_ptr and counted_ptr, meeting of Per Andersson, Matt - Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, - Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new - class names were finalized, it was decided that there was no need to exactly - follow the std::auto_ptr interface, and various function signatures and - semantics were finalized.

-

Over the next three months, several implementations were considered for shared_ptr, - and discussed on the boost.org mailing list. - The implementation questions revolved around the reference count which must be - kept, either attached to the pointed to object, or detached elsewhere. Each of - those variants have themselves two major variants: -

    -
  • - Direct detached: the shared_ptr contains a pointer to the object, and a pointer - to the count. -
  • - Indirect detached: the shared_ptr contains a pointer to a helper object, which - in turn contains a pointer to the object and the count. -
  • - Embedded attached: the count is a member of the object pointed to. -
  • - Placement attached: the count is attached via operator new manipulations.
  • -
-

Each implementation technique has advantages and disadvantages. We went so far - as to run various timings of the direct and indirect approaches, and found that - at least on Intel Pentium chips there was very little measurable difference. - Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar - Kühl suggested an elegant partial template specialization technique to allow - users to choose which implementation they preferred, and that was also - experimented with.

-

But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage - users", and in the end we choose to supply only the direct implementation.

-

Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named auto_ptr - and counted_ptr which were very similar to what we now call scoped_ptr - and shared_ptr. [Col-94] In one of the very few - cases where the Library Working Group's recommendations were not followed by - the full committee, counted_ptr was rejected and surprising - transfer-of-ownership semantics were added to auto_ptr.

-

References

-

[D&F-14] Peter Dimov & Glen Fernandes, - Extending make_shared to Support Arrays, Revision 1, C++ committee document N3870, - January, 2014.

-

[Col-94] Gregory Colvin, - Exception Safe Smart Pointers, C++ committee document 94-168/N0555, - July, 1994.

-

[E&D-94] John R. Ellis & David L. Detlefs, - Safe, Efficient Garbage Collection for C++, Usenix Proceedings, - February, 1994. This paper includes an extensive discussion of weak pointers - and an extensive bibliography.

-
-

$Date$

-

Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Distributed under the Boost Software License, Version 1.0. See accompanying - file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/smarttest.zip b/smarttest.zip deleted file mode 100644 index 2464b1046d1f8bdb59c05843bb0e04b8e26ec56b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11513 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 ISZRZJ0Kbrpg8%>k diff --git a/smarttests.htm b/smarttests.htm deleted file mode 100644 index 2551ae4..0000000 --- a/smarttests.htm +++ /dev/null @@ -1,542 +0,0 @@ - - - - - -Smart Pointer Timings - - - - - -

boost.png (6897 bytes)Smart Pointer Timings

- -

In late January 2000, Mark Borgerding put forward a suggestion to boost for - a new design of smart pointer whereby an intrusive doubly linked list is used - to join together all instances of smart pointers sharing a given raw pointer. - This allowed avoidance of the costly heap allocation of a reference count that - occurred in the initial construction of the then current version of boost::shared_ptr. - Of course, nothing is for free and the benefit here was gained at the expense - of increased size and more costly copy operations. A debate ensued on the boost - mailing list and the tests which this page describes were performed to provide - a guide for current and future investigations into smart pointer implementation - strategies.

-

Thanks are due to Dave Abrahams, -Gavin Collings, -Greg Colvin and -Beman Dawes - for test code and trial implementations, the final version of which can be found - in .zip format here.

-

Description

-

Two tests were run: the first aimed to obtain timings for two basic individual - operations:

-
    -
  1. Initial construction from raw pointer.
  2. -
  3. An amortized copy operation consisting of half an assignment and half a - copy construction - designed to reflect average usage.
  4. -
-

The second attempted to gain more insight into normal usage by timing the fill - and sort algorithms for vectors and lists filled with the various smart pointers.

-

Five smart pointer implementation strategies were tested:

-
    -
  1. Counted pointer using a heap allocated reference count, this is referred - to as simple counted.
  2. -
  3. Counted pointer using a special purpose allocator for the reference count - - special counted.
  4. -
  5. Counted pointer using an intrusive reference count - intrusive.
  6. -
  7. Linked pointer as described above - linked.
  8. -
  9. Cyclic pointer, a counted implementation using a std::deque for allocation - with provision for weak pointers and garbage collection of cycles of pointers - - cyclic.
  10. -
-

on two compilers:

-
    -
  1. MSVC 6.0 service pack 3, using default release optimization mode (/O2 - - optimized for speed, no inlining of functions defined outside a class body - unless specified as inline).
  2. -
  3. gcc 2.95.2 using full optimization (-O3 -DNDEBUG).
  4. -
-

Additionally, generated pointer sizes (taking into account struct alignment) - were compared, as were generated code sizes for MSVC mainly by manual inspection - of generated assembly code - a necessity due to function inlining.

-

All tests were run on a PII-200 running Windows NT version 4.0

-

 

-

Operation Timing Test Results

-

The following graphs show the overall time in nanoseconds to acquire a pointer - (default construction) perform n amortized copy operations on it and finally - release it. The initial allocation time for the contained pointer is not included, - although the time for it's deallocation is. The contained pointer pointed to - a trivial class, but for the inclusion of an intrusive reference count for the - benefit of the intrusive counted shared pointer. A dumb pointer (i.e. a smart - pointer that simply acquires and releases its contained pointer with no extra - overhead) and a raw pointer were also included for comparison.

- - - - - - - - - - - - - - - - - - - - - - - - - - -
   
  MSVC speed graph 
   
 GCC speed graph 
   
-

 

-

Fitting straight lines to the above plots gives the following figures for initialization - and amortized copy operation for the two compilers (times in nanoseconds, errors - at two standard deviations) : -

-

 

-

MSVC

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
initialization
-
copy operation
-
simple counted
-
3000 +/- 170104 +/- 31
-
special counted
-
1330 +/- 5085 +/- 9
-
intrusive
-
1000 +/- 2071 +/- 3
linked970 +/- 60136 +/- 10
cyclic1290 +/- 70112 +/- 12
dumb1020 +/- 2010 +/- 4
-
raw
-
1038 +/- 3010 +/- 5
-

 

-

GCC

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
initialization
-
copy operation
-
simple counted
-
4620 +/- 150301 +/- 28
-
special counted
-
1990 +/- 40264 +/- 7
-
intrusive
-
1590 +/- 70181 +/- 12
linked1470 +/- 140345 +/- 26
cyclic2180 +/- 100330 +/- 18
dumb1590 +/- 7074 +/- 12
-
raw
-
1430 +/- 6027 +/- 11
-

Note that the above times include a certain amount of loop overhead etc. for - each operation. An estimate of the pure smart pointer operation time 'overhead' - can be obtained by subtracting the dumb or raw figure from the smart pointer - time of interest.

-

Detail

-

The test involved iterating a loop which creates raw pointers. These were then - shared among a varying number (set size) of smart pointers. A range of set sizes - was used and then a line fitted to get a linear relation with number of initializations - and copy-operations. A spreadsheet was used for the line fit, and to produce - the performance graphs above.

-

 

-

Container Test Results

-

To gain some insight in to operation within real life programs, this test was - devised. Smart pointers were used to fill standard containers which were then - sorted.

-

In this case, the contained pointer pointed to a class which initializes a - private data member to a random value in its default constructor. This value - is used subsequently for the sort comparison test. The class also contains an - intrusive reference count for the benefit of the intrusive counted pointer.

-

All times are in seconds for 300,000 contained pointers.

-

GCC

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 vectorlist
-
-
-
fill
-
sortfillsort
-
simple counted
-
46.542.4447.093.22
-
special counted
-
14.022.837.283.21
-
intrusive
-
12.151.917.993.08
linked12.462.328.143.27
cyclic22.603.191.633.18
-
raw
-
11.810.2427.510.77
-

 

-

MSVC

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 vectorlist
-
-
-
fill
-
sortfillsort
-
simple counted
-
1.832.371.864.85
-
special counted
-
1.042.351.384.58
-
intrusive
-
1.041.841.164.29
linked1.082.001.214.33
cyclic1.382.841.474.73
-
raw
-
0.670.281.241.81
-

 

-

Code Size

-

The following code sizes were determined by inspection of generated code for - MSVC only. Sizes are given in the form N / M / I where:

-
    -
  • N is the instruction count of the operation
  • -
  • M is the size of the code in bytes
  • -
  • I determines whether generated code was inlined or not I = inline, O = "outline"
  • -
-

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
ptr()
-
ptr(p)ptr(ptr)op=() -
~ptr()
-
-
simple counted
-
38/110/O38/110/O9/23/I22/57/I17/40/I
-
special counted
-
50/141/O50/141/O9/23/I23/64/I13/38/I
-
intrusive
-
1/2/I3/6/I3/6/I6/11/I6/11/I
-
linked
-
5/19/I5/15/I10/30/I27/59/I14/38/I
-

During the code inspection, a couple of minor points were noticed: -

-
    -
  • Function inlining was critical to performance.
  • -
  • For MSVC, at least, a "delete 0" caused execution of 11 assembly - instructions, including a function call. So in cases where performance is - at an absolute premium it can be worth inserting the extra manual test.
  • -
-

 

-

Data Size

-

The following smart pointer sizes were obtained in bytes

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
MSVC
-
-
GCC
-
-
simple counted
-
-
8
-
-
8
-
-
special counted
-
-
8
-
-
12
-
-
intrusive
-
-
4
-
-
4
-
-
linked
-
-
12
-
-
12
-
-
cyclic
-
-
8
-
-
8
-
-

 

-

Summary

-

The timing results mainly speak for themselves: clearly an intrusive pointer - outperforms all others and a simple heap based counted pointer has poor performance - relative to other implementations. The selection of an optimal non-intrusive - smart pointer implementation is more application dependent, however. Where small - numbers of copies are expected, it is likely that the linked implementation - will be favoured. Conversely, for larger numbers of copies a counted pointer - with some type of special purpose allocator looks like a win. Other factors - to bear in mind are: -

-
    -
  • Deterministic individual, as opposed to amortized, operation time. This - weighs against any implementation depending on an allocator.
  • -
  • Multithreaded synchronization. This weighs against an implementation which - spreads its information as in the case of linked pointer.
  • -
-
-

$Date$

-

© Copyright Gavin Collings 2000. Permission to copy, use, modify, sell -and distribute this document is granted provided this copyright notice appears in all -copies. This document is provided "as is" without express or implied warranty, -and with no claim as to its suitability for any purpose.

- - diff --git a/sp_techniques.html b/sp_techniques.html deleted file mode 100644 index 7e0ce8f..0000000 --- a/sp_techniques.html +++ /dev/null @@ -1,765 +0,0 @@ - - - - Smart Pointer Programming Techniques - - - -

boost.png (6897 bytes)Smart Pointer Programming Techniques

-

Using incomplete classes for implementation hiding
- The "Pimpl" idiom
- Using abstract classes for implementation hiding
- Preventing delete px.get()
- Using a shared_ptr to hold a pointer to an array
- Encapsulating allocation details, wrapping factory - functions
- Using a shared_ptr to hold a pointer to a statically - allocated object
- Using a shared_ptr to hold a pointer to a COM object
- Using a shared_ptr to hold a pointer to an object - with an embedded reference count
- Using a shared_ptr to hold another shared - ownership smart pointer
- Obtaining a shared_ptr from a raw pointer
- Obtaining a shared_ptr (weak_ptr) - to this in a constructor
- Obtaining a shared_ptr to this
- Using shared_ptr as a smart counted handle
- Using shared_ptr to execute code on block - exit
- Using shared_ptr<void> to hold an arbitrary - object
- Associating arbitrary data with heterogeneous shared_ptr - instances
- Using shared_ptr as a CopyConstructible mutex lock
- Using shared_ptr to wrap member function calls
- Delayed deallocation
- Weak pointers to objects not managed by a shared_ptr
-

-

Using incomplete classes for implementation hiding

-

A proven technique (that works in C, too) for separating interface from - implementation is to use a pointer to an incomplete class as an opaque handle:

-
class FILE;
-
-FILE * fopen(char const * name, char const * mode);
-void fread(FILE * f, void * data, size_t size);
-void fclose(FILE * f);
-
-

It is possible to express the above interface using shared_ptr, - eliminating the need to manually call fclose:

-
class FILE;
-
-shared_ptr<FILE> fopen(char const * name, char const * mode);
-void fread(shared_ptr<FILE> f, void * data, size_t size);
-
-

This technique relies on shared_ptr's ability to execute a custom - deleter, eliminating the explicit call to fclose, and on the fact - that shared_ptr<X> can be copied and destroyed when X - is incomplete.

-

The "Pimpl" idiom

-

A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. - The incomplete class is not exposed to the user; it is hidden behind a - forwarding facade. shared_ptr can be used to implement a "Pimpl":

-
// file.hpp:
-
-class file
-{
-private:
-
-    class impl;
-    shared_ptr<impl> pimpl_;
-
-public:
-
-    file(char const * name, char const * mode);
-
-    // compiler generated members are fine and useful
-
-    void read(void * data, size_t size);
-};
-
-
// file.cpp:
-
-#include "file.hpp"
-
-class file::impl
-{
-private:
-
-    impl(impl const &);
-    impl & operator=(impl const &);
-
-    // private data
-
-public:
-
-    impl(char const * name, char const * mode) { ... }
-    ~impl() { ... }
-    void read(void * data, size_t size) { ... }
-};
-
-file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
-{
-}
-
-void file::read(void * data, size_t size)
-{
-    pimpl_->read(data, size);
-}
-
-

The key thing to note here is that the compiler-generated copy constructor, - assignment operator, and destructor all have a sensible meaning. As a result, - file is CopyConstructible and Assignable, - allowing its use in standard containers.

-

Using abstract classes for implementation hiding

-

Another widely used C++ idiom for separating inteface and implementation is to - use abstract base classes and factory functions. The abstract classes are - sometimes called "interfaces" and the pattern is known as "interface-based - programming". Again, shared_ptr can be used as the return type of - the factory functions:

-
// X.hpp:
-
-class X
-{
-public:
-
-    virtual void f() = 0;
-    virtual void g() = 0;
-
-protected:
-
-    ~X() {}
-};
-
-shared_ptr<X> createX();
-
-
-- X.cpp:
-
-class X_impl: public X
-{
-private:
-
-    X_impl(X_impl const &);
-    X_impl & operator=(X_impl const &);
-
-public:
-
-    virtual void f()
-    {
-      // ...
-    }
-
-    virtual void g()
-    {
-      // ...
-    }
-};
-
-shared_ptr<X> createX()
-{
-    shared_ptr<X> px(new X_impl);
-    return px;
-}
-
-

A key property of shared_ptr is that the allocation, construction, deallocation, - and destruction details are captured at the point of construction, inside the - factory function. Note the protected and nonvirtual destructor in the example - above. The client code cannot, and does not need to, delete a pointer to X; - the shared_ptr<X> instance returned from createX - will correctly call ~X_impl.

-

Preventing delete px.get()

-

It is often desirable to prevent client code from deleting a pointer that is - being managed by shared_ptr. The previous technique showed one - possible approach, using a protected destructor. Another alternative is to use - a private deleter:

-
class X
-{
-private:
-
-    ~X();
-
-    class deleter;
-    friend class deleter;
-
-    class deleter
-    {
-    public:
-
-        void operator()(X * p) { delete p; }
-    };
-
-public:
-
-    static shared_ptr<X> create()
-    {
-        shared_ptr<X> px(new X, X::deleter());
-        return px;
-    }
-};
-
-

Using a shared_ptr to hold a pointer to an array

-

A shared_ptr can be used to hold a pointer to an array allocated - with new[]:

-
shared_ptr<X> px(new X[1], checked_array_deleter<X>());
-
-

Note, however, that shared_array is - often preferable, if this is an option. It has an array-specific interface, - without operator* and operator->, and does not - allow pointer conversions.

-

Encapsulating allocation details, wrapping factory - functions

-

shared_ptr can be used in creating C++ wrappers over existing C - style library interfaces that return raw pointers from their factory functions - to encapsulate allocation details. As an example, consider this interface, - where CreateX might allocate X from its own private - heap, ~X may be inaccessible, or X may be incomplete:

-
X * CreateX();
-void DestroyX(X *);
-
-

The only way to reliably destroy a pointer returned by CreateX is - to call DestroyX.

-

Here is how a shared_ptr-based wrapper may look like:

-
shared_ptr<X> createX()
-{
-    shared_ptr<X> px(CreateX(), DestroyX);
-    return px;
-}
-
-

Client code that calls createX still does not need to know how the - object has been allocated, but now the destruction is automatic.

-

Using a shared_ptr to hold a pointer to a statically - allocated object

-

Sometimes it is desirable to create a shared_ptr to an already - existing object, so that the shared_ptr does not attempt to - destroy the object when there are no more references left. As an example, the - factory function:

-
shared_ptr<X> createX();
-
-

in certain situations may need to return a pointer to a statically allocated X - instance.

-

The solution is to use a custom deleter that does nothing:

-
struct null_deleter
-{
-    void operator()(void const *) const
-    {
-    }
-};
-
-static X x;
-
-shared_ptr<X> createX()
-{
-    shared_ptr<X> px(&x, null_deleter());
-    return px;
-}
-
-

The same technique works for any object known to outlive the pointer.

-

Using a shared_ptr to hold a pointer to a COM Object

-

Background: COM objects have an embedded reference count and two member - functions that manipulate it. AddRef() increments the count. Release() - decrements the count and destroys itself when the count drops to zero.

-

It is possible to hold a pointer to a COM object in a shared_ptr:

-
shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p)
-{
-    p->AddRef();
-    shared_ptr<IWhatever> pw(p, mem_fn(&IWhatever::Release));
-    return pw;
-}
-
-

Note, however, that shared_ptr copies created from pw will - not "register" in the embedded count of the COM object; they will share the - single reference created in make_shared_from_COM. Weak pointers - created from pw will be invalidated when the last shared_ptr - is destroyed, regardless of whether the COM object itself is still alive.

-

As explained in the mem_fn documentation, - you need to #define - BOOST_MEM_FN_ENABLE_STDCALL first.

-

Using a shared_ptr to hold a pointer to an object - with an embedded reference count

-

This is a generalization of the above technique. The example assumes that the - object implements the two functions required by intrusive_ptr, - intrusive_ptr_add_ref and intrusive_ptr_release:

-
template<class T> struct intrusive_deleter
-{
-    void operator()(T * p)
-    {
-        if(p) intrusive_ptr_release(p);
-    }
-};
-
-shared_ptr<X> make_shared_from_intrusive(X * p)
-{
-    if(p) intrusive_ptr_add_ref(p);
-    shared_ptr<X> px(p, intrusive_deleter<X>());
-    return px;
-}
-
-

Using a shared_ptr to hold another shared - ownership smart pointer

-

One of the design goals of shared_ptr is to be used in library - interfaces. It is possible to encounter a situation where a library takes a shared_ptr - argument, but the object at hand is being managed by a different reference - counted or linked smart pointer.

-

It is possible to exploit shared_ptr's custom deleter feature to - wrap this existing smart pointer behind a shared_ptr facade:

-
template<class P> struct smart_pointer_deleter
-{
-private:
-
-    P p_;
-
-public:
-
-    smart_pointer_deleter(P const & p): p_(p)
-    {
-    }
-
-    void operator()(void const *)
-    {
-        p_.reset();
-    }
-    
-    P const & get() const
-    {
-        return p_;
-    }
-};
-
-shared_ptr<X> make_shared_from_another(another_ptr<X> qx)
-{
-    shared_ptr<X> px(qx.get(), smart_pointer_deleter< another_ptr<X> >(qx));
-    return px;
-}
-
-

One subtle point is that deleters are not allowed to throw exceptions, and the - above example as written assumes that p_.reset() doesn't throw. If - this is not the case, p_.reset() should be wrapped in a try {} - catch(...) {} block that ignores exceptions. In the (usually - unlikely) event when an exception is thrown and ignored, p_ will - be released when the lifetime of the deleter ends. This happens when all - references, including weak pointers, are destroyed or reset.

-

Another twist is that it is possible, given the above shared_ptr instance, - to recover the original smart pointer, using - get_deleter:

-
void extract_another_from_shared(shared_ptr<X> px)
-{
-    typedef smart_pointer_deleter< another_ptr<X> > deleter;
-
-    if(deleter const * pd = get_deleter<deleter>(px))
-    {
-        another_ptr<X> qx = pd->get();
-    }
-    else
-    {
-        // not one of ours
-    }
-}
-
-

Obtaining a shared_ptr from a raw pointer

-

Sometimes it is necessary to obtain a shared_ptr given a raw - pointer to an object that is already managed by another shared_ptr - instance. Example:

-
void f(X * p)
-{
-    shared_ptr<X> px(???);
-}
-
-

Inside f, we'd like to create a shared_ptr to *p.

-

In the general case, this problem has no solution. One approach is to modify f - to take a shared_ptr, if possible:

-
void f(shared_ptr<X> px);
-
-

The same transformation can be used for nonvirtual member functions, to convert - the implicit this:

-
void X::f(int m);
-
-

would become a free function with a shared_ptr first argument:

-
void f(shared_ptr<X> this_, int m);
-
-

If f cannot be changed, but X uses intrusive counting, - use make_shared_from_intrusive described - above. Or, if it's known that the shared_ptr created in f - will never outlive the object, use a null deleter.

-

Obtaining a shared_ptr (weak_ptr) - to this in a constructor

-

Some designs require objects to register themselves on construction with a - central authority. When the registration routines take a shared_ptr, this leads - to the question how could a constructor obtain a shared_ptr to this:

-
class X
-{
-public:
-
-    X()
-    {
-        shared_ptr<X> this_(???);
-    }
-};
-
-

In the general case, the problem cannot be solved. The X instance - being constructed can be an automatic variable or a static variable; it can be - created on the heap:

-
shared_ptr<X> px(new X);
-

but at construction time, px does not exist yet, and it is - impossible to create another shared_ptr instance that shares - ownership with it.

-

Depending on context, if the inner shared_ptr this_ doesn't - need to keep the object alive, use a null_deleter as explained - here and here. If X is - supposed to always live on the heap, and be managed by a shared_ptr, - use a static factory function:

-
class X
-{
-private:
-
-    X() { ... }
-
-public:
-
-    static shared_ptr<X> create()
-    {
-        shared_ptr<X> px(new X);
-        // use px as 'this_'
-        return px;
-    }
-};
-
-

Obtaining a shared_ptr to this

-

Sometimes it is needed to obtain a shared_ptr from this - in a virtual member function under the assumption that this is - already managed by a shared_ptr. The transformations - described in the previous technique cannot be applied.

-

A typical example:

-
class X
-{
-public:
-
-    virtual void f() = 0;
-
-protected:
-
-    ~X() {}
-};
-
-class Y
-{
-public:
-
-    virtual shared_ptr<X> getX() = 0;
-
-protected:
-
-    ~Y() {}
-};
-
-// --
-
-class impl: public X, public Y
-{
-public:
-
-    impl() { ... }
-
-    virtual void f() { ... }
-
-    virtual shared_ptr<X> getX()
-    {
-        shared_ptr<X> px(???);
-        return px;
-    }
-};
-
-

The solution is to keep a weak pointer to this as a member in impl:

-
class impl: public X, public Y
-{
-private:
-
-    weak_ptr<impl> weak_this;
-
-    impl(impl const &);
-    impl & operator=(impl const &);
-
-    impl() { ... }
-
-public:
-
-    static shared_ptr<impl> create()
-    {
-        shared_ptr<impl> pi(new impl);
-        pi->weak_this = pi;
-        return pi;
-    }
-
-    virtual void f() { ... }
-
-    virtual shared_ptr<X> getX()
-    {
-        shared_ptr<X> px(weak_this);
-        return px;
-    }
-};
-
-

The library now includes a helper class template - enable_shared_from_this that can be used to encapsulate the - solution:

-
class impl: public X, public Y, public enable_shared_from_this<impl>
-{
-public:
-
-    impl(impl const &);
-    impl & operator=(impl const &);
-
-public:
-
-    virtual void f() { ... }
-
-    virtual shared_ptr<X> getX()
-    {
-        return shared_from_this();
-    }
-}
-
-

Note that you no longer need to manually initialize the weak_ptr member - in enable_shared_from_this. - Constructing a shared_ptr to impl takes care of that.

-

Using shared_ptr as a smart counted handle

-

Some library interfaces use opaque handles, a variation of the - incomplete class technique described above. An example:

-
typedef void * HANDLE;
-HANDLE CreateProcess();
-void CloseHandle(HANDLE);
-
-

Instead of a raw pointer, it is possible to use shared_ptr as the - handle and get reference counting and automatic resource management for free:

-
typedef shared_ptr<void> handle;
-
-handle createProcess()
-{
-    shared_ptr<void> pv(CreateProcess(), CloseHandle);
-    return pv;
-}
-
-

Using shared_ptr to execute code on block exit

-

shared_ptr<void> can automatically execute cleanup code when - control leaves a scope.

-
    -
  • - Executing f(p), where p is a pointer:
-
    shared_ptr<void> guard(p, f);
-
-
    -
  • - Executing arbitrary code: f(x, y):
-
    shared_ptr<void> guard(static_cast<void*>(0), bind(f, x, y));
-
-

For a more thorough treatment, see the article "Simplify Your Exception-Safe - Code" by Andrei Alexandrescu and Petru Marginean, available online at - http://www.cuj.com/experts/1812/alexandr.htm?topic=experts.

-

Using shared_ptr<void> to hold an arbitrary - object

-

shared_ptr<void> can act as a generic object pointer similar - to void*. When a shared_ptr<void> instance - constructed as:

-
    shared_ptr<void> pv(new X);
-
-

is destroyed, it will correctly dispose of the X object by - executing ~X.

-

This propery can be used in much the same manner as a raw void* is - used to temporarily strip type information from an object pointer. A shared_ptr<void> - can later be cast back to the correct type by using - static_pointer_cast.

-

Associating arbitrary data with heterogeneous shared_ptr - instances

-

shared_ptr and weak_ptr support operator< - comparisons required by standard associative containers such as std::map. - This can be used to non-intrusively associate arbitrary data with objects - managed by shared_ptr:

-
typedef int Data;
-
-std::map< shared_ptr<void>, Data > userData;
-// or std::map< weak_ptr<void>, Data > userData; to not affect the lifetime
-
-shared_ptr<X> px(new X);
-shared_ptr<int> pi(new int(3));
-
-userData[px] = 42;
-userData[pi] = 91;
-
-

Using shared_ptr as a CopyConstructible mutex lock

-

Sometimes it's necessary to return a mutex lock from a function, and a - noncopyable lock cannot be returned by value. It is possible to use shared_ptr - as a mutex lock:

-
class mutex
-{
-public:
-
-    void lock();
-    void unlock();
-};
-
-shared_ptr<mutex> lock(mutex & m)
-{
-    m.lock();
-    return shared_ptr<mutex>(&m, mem_fn(&mutex::unlock));
-}
-
-

Better yet, the shared_ptr instance acting as a lock can be - encapsulated in a dedicated shared_lock class:

-
class shared_lock
-{
-private:
-
-    shared_ptr<void> pv;
-
-public:
-
-    template<class Mutex> explicit shared_lock(Mutex & m): pv((m.lock(), &m), mem_fn(&Mutex::unlock)) {}
-};
-
-

shared_lock can now be used as:

-
    shared_lock lock(m);
-
-

Note that shared_lock is not templated on the mutex type, thanks to - shared_ptr<void>'s ability to hide type information.

-

Using shared_ptr to wrap member function calls

-

shared_ptr implements the ownership semantics required from the Wrap/CallProxy - scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function - Calls" (available online at http://www.stroustrup.com/wrapper.pdf). - An implementation is given below:

-
template<class T> class pointer
-{
-private:
-
-    T * p_;
-
-public:
-
-    explicit pointer(T * p): p_(p)
-    {
-    }
-
-    shared_ptr<T> operator->() const
-    {
-        p_->prefix();
-        return shared_ptr<T>(p_, mem_fn(&T::suffix));
-    }
-};
-
-class X
-{
-private:
-
-    void prefix();
-    void suffix();
-    friend class pointer<X>;
-    
-public:
-
-    void f();
-    void g();
-};
-
-int main()
-{
-    X x;
-
-    pointer<X> px(&x);
-
-    px->f();
-    px->g();
-}
-
-

Delayed deallocation

-

In some situations, a single px.reset() can trigger an expensive - deallocation in a performance-critical region:

-
class X; // ~X is expensive
-
-class Y
-{
-    shared_ptr<X> px;
-
-public:
-
-    void f()
-    {
-        px.reset();
-    }
-};
-
-

The solution is to postpone the potential deallocation by moving px - to a dedicated free list that can be periodically emptied when performance and - response times are not an issue:

-
vector< shared_ptr<void> > free_list;
-
-class Y
-{
-    shared_ptr<X> px;
-
-public:
-
-    void f()
-    {
-        free_list.push_back(px);
-        px.reset();
-    }
-};
-
-// periodically invoke free_list.clear() when convenient
-
-

Another variation is to move the free list logic to the construction point by - using a delayed deleter:

-
struct delayed_deleter
-{
-    template<class T> void operator()(T * p)
-    {
-        try
-        {
-            shared_ptr<void> pv(p);
-            free_list.push_back(pv);
-        }
-        catch(...)
-        {
-        }
-    }
-};
-
-

Weak pointers to objects not managed by a shared_ptr

-

Make the object hold a shared_ptr to itself, using a null_deleter:

-
class X
-{
-private:
-
-    shared_ptr<X> this_;
-    int i_;
-
-public:
-
-    explicit X(int i): this_(this, null_deleter()), i_(i)
-    {
-    }
-
-    // repeat in all constructors (including the copy constructor!)
-
-    X(X const & rhs): this_(this, null_deleter()), i_(rhs.i_)
-    {
-    }
-
-    // do not forget to not assign this_ in the copy assignment
-
-    X & operator=(X const & rhs)
-    {
-        i_ = rhs.i_;
-    }
-
-    weak_ptr<X> get_weak_ptr() const { return this_; }
-};
-
-

When the object's lifetime ends, X::this_ will be destroyed, and - all weak pointers will automatically expire.

-
-

$Date$

-

Copyright © 2003 Peter Dimov. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

- - diff --git a/weak_ptr.htm b/weak_ptr.htm deleted file mode 100644 index 4c256b8..0000000 --- a/weak_ptr.htm +++ /dev/null @@ -1,240 +0,0 @@ - - - - weak_ptr - - - -

boost.png (6897 bytes)weak_ptr class template

-

Introduction
- Synopsis
- Members
- Free Functions
- Frequently Asked Questions -

-

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 - the shared_ptr constructor or the member function - 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())
-{
-    // 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.

-

Synopsis

-
namespace boost {
-
-  template<class T> class weak_ptr {
-
-    public:
-      typedef T element_type;
-
-      weak_ptr();
-
-      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);
-
-      ~weak_ptr();
-
-      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);
-
-      long use_count() const;
-      bool expired() const;
-      shared_ptr<T> lock() const;
-
-      void reset();
-      void swap(weak_ptr<T> & b);
-  };
-
-  template<class T, class U>
-    bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);
-
-  template<class T>
-    void swap(weak_ptr<T> & a, weak_ptr<T> & b);
-}
-
-

Members

-

element_type

-
typedef T element_type;
-
-

Provides the type of the template parameter T.

-
-

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.

-
-

destructor

-
~weak_ptr();
-
-

Effects: Destroys this weak_ptr but has no effect on the object - its stored pointer points to.

-

Throws: nothing.

-
-

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.

-
-

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.

-
-

expired

-
bool expired() const;
-
-

Returns: use_count() == 0.

-

Throws: nothing.

-

Notes: expired() may be faster than use_count().

-
-

lock

-
shared_ptr<T> lock() const;
-
-

Returns: expired()? shared_ptr<T>(): shared_ptr<T>(*this).

-

Throws: nothing.

-
-

reset

-
void reset();
-
-

Effects: Equivalent to weak_ptr().swap(*this).

-
-

swap

-
void swap(weak_ptr & b);
-
-

Effects: Exchanges the contents of the two smart pointers.

-

Throws: nothing.

-
-

Free Functions

-

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.

-
-

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.

-
-

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;
-    }
-};
-
-
-

$Date$

-

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 or - copy at http://www.boost.org/LICENSE_1_0.txt.

- -