# Boost.SmartPtr: The Smart Pointer Library

Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes

## 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. 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 six 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;

- `local_shared_ptr`, providing shared ownership within a single thread.

`shared_ptr` and `weak_ptr` are part of the C++ 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.

- `atomic_shared_ptr`, a helper class implementing the interface of `std::atomic` for a value of type `shared_ptr`.

As a general rule, the destructor or `operator delete` for an object managed by pointers in the library are not allowed to throw exceptions.

## scoped_ptr: Scoped Object Ownership

### Description

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.

`scoped_ptr` 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` 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` or `std::unique_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. Destroying `T` must not thow exceptions, and `T` must be complete at the point `scoped_ptr<T>::~scoped_ptr` is instantiated.

### Synopsis

`scoped_ptr` is defined in `<boost/smart_ptr/scoped_ptr.hpp>`.

    namespace boost {

      template<class T> class scoped_ptr {
      private:

        scoped_ptr(scoped_ptr const&);
        scoped_ptr& operator=(scoped_ptr const&);

        void operator==(scoped_ptr const&) const;
        void operator!=(scoped_ptr const&) const;

      public:

        typedef T element_type;

        explicit scoped_ptr(T * p = 0) noexcept;
        ~scoped_ptr() noexcept;

        void reset(T * p = 0) noexcept;

        T & operator*() const noexcept;
        T * operator->() const noexcept;
        T * get() const noexcept;

        explicit operator bool() const noexcept;

        void swap(scoped_ptr & b) noexcept;
      };

      template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;

      template<class T>
        bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
      template<class T>
        bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;

      template<class T>
        bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
      template<class T>
        bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
    }

### Members

#### element_type

    typedef T element_type;

Provides the type of the stored pointer.

#### constructor

    explicit scoped_ptr(T * p = 0) noexcept;

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.

#### destructor

    ~scoped_ptr() noexcept;

Destroys the object pointed to by the stored pointer, if any, as if by using `delete this->get()`. `T` must be a complete type.

#### reset

    void reset(T * p = 0) noexcept;

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.

Since the previous object needs to be deleted, `T` must be a complete type.

#### indirection

    T & operator*() const noexcept;

Returns a reference to the object pointed to by the stored pointer. Behavior is undefined if the stored pointer is 0.

    T * operator->() const noexcept;

Returns the stored pointer. Behavior is undefined if the stored pointer is 0.

#### get

    T * get() const noexcept;

Returns the stored pointer. `T` need not be a complete type.

#### conversions

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

Returns `get() != 0`.

Note | On C++03 compilers, the return value is of an unspecified type.

#### swap

    void swap(scoped_ptr & b) noexcept;

Exchanges the contents of the two smart pointers. `T` need not be a complete type.

### Free Functions

#### swap

    template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;

Equivalent to `a.swap(b)`.

#### comparisons

    template<class T> bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;

    template<class T> bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;

Returns `p.get() == nullptr`.

    template<class T> bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;

    template<class T> bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;

Returns `p.get() != nullptr`.

### 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 `std::auto_ptr` or `std::unique_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

1. Why doesn’t `scoped_ptr` have a `release()` member?

   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)

## scoped_array: Scoped Array Ownership

### Description

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_ptr<T[]>` 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_ptr<T[]>` if `scoped_array` does not meet your needs.

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

`std::vector` is an alternative to `scoped_array` that is a bit heavier duty but far more flexible. `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.

### Synopsis

`scoped_array` is defined in `<boost/smart_ptr/scoped_array.hpp>`.

    namespace boost {

      template<class T> class scoped_array {
      private:

        scoped_array(scoped_array const &);
        scoped_array & operator=(scoped_array const &);

        void operator==( scoped_array const& ) const;
        void operator!=( scoped_array const& ) const;

      public:

        typedef T element_type;

        explicit scoped_array(T * p = 0) noexcept;
        ~scoped_array() noexcept;

        void reset(T * p = 0) noexcept;

        T & operator[](std::ptrdiff_t i) const noexcept;
        T * get() const noexcept;

        explicit operator bool () const noexcept;

        void swap(scoped_array & b) noexcept;
      };

      template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;

      template<class T>
        bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;
      template<class T>
        bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;

      template<class T>
        bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;
      template<class T>
        bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;
    }

### Members

#### element_type

    typedef T element_type;

Provides the type of the stored pointer.

#### constructors

    explicit scoped_array(T * p = 0) noexcept;

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.

#### destructor

    ~scoped_array() noexcept;

Deletes the array pointed to by the stored pointer. Note that `delete[]` on a pointer with a value of 0 is harmless. `T` must be complete, and `delete[]` on the stored pointer must not throw exceptions.

#### reset

    void reset(T * p = 0) noexcept;

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. `T` must be complete, and `delete[]` on the stored pointer must not throw exceptions.

#### subscripting

    T & operator[](std::ptrdiff_t i) const noexcept;

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

Returns the stored pointer. `T` need not be a complete type.

#### conversions

    explicit operator bool () const noexcept;

Returns `get() != 0`.

Note | On C++03 compilers, the return value is of an unspecified type.

#### swap

    void swap(scoped_array & b) noexcept;

Exchanges the contents of the two smart pointers. `T` need not be a complete type.

### Free Functions

#### swap

    template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;

Equivalent to `a.swap(b)`.

#### comparisons

    template<class T>
      bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;

    template<class T>
      bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;

Returns `p.get() == nullptr`.

    template<class T>
      bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;

    template<class T>
      bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;

Returns `p.get() != nullptr`.

## shared_ptr: Shared Ownership

### Description

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.

Code Example 1. Using shared_ptr

    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.

Code Example 2. Using shared_ptr with arrays

    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 the constructor of `Y` 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:

Code Example 3. Exception-safe and -unsafe use of shared_ptr

    void f(shared_ptr<int>, int);
    int g();

    void ok()
    {
        shared_ptr<int> p( new int(2) );
        f( p, g() );
    }

    void bad()
    {
        f( shared_ptr<int>( new int(2) ), g() );
    }

The function `ok` follows the guideline to the letter, whereas `bad` constructs the temporary `shared_ptr` in place, admitting the possibility of a memory leak. Since function arguments are evaluated in unspecified order, it is possible for `new int(2)` to be evaluated first, `g()` second, and we may never get to the `shared_ptr` constructor if `g` throws an exception. See Herb Sutter’s treatment 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/smart_ptr/make_shared.hpp>`. These factory functions also provide an efficiency benefit by consolidating allocations.

### Synopsis

`shared_ptr` is defined in `<boost/smart_ptr/shared_ptr.hpp>`.

    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;

        constexpr shared_ptr() noexcept;
        constexpr shared_ptr(std::nullptr_t) noexcept;

        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() noexcept;

        shared_ptr(shared_ptr const & r) noexcept;
        template<class Y> shared_ptr(shared_ptr<Y> const & r) noexcept;

        shared_ptr(shared_ptr && r) noexcept;
        template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept;

        template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;

        template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept;

        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) noexcept;
        template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r) noexcept;

        shared_ptr & operator=(shared_ptr const && r) noexcept;
        template<class Y> shared_ptr & operator=(shared_ptr<Y> const && r) noexcept;

        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) noexcept;

        void reset() noexcept;

        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) noexcept;
        template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;

        T & operator*() const noexcept; // only valid when T is not an array type
        T * operator->() const noexcept; // only valid when T is not an array type

        // only valid when T is an array type
        element_type & operator[](std::ptrdiff_t i) const noexcept;

        element_type * get() const noexcept;

        bool unique() const noexcept;
        long use_count() const noexcept;

        explicit operator bool() const noexcept;

        void swap(shared_ptr & b) noexcept;

        template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
        template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
      };

      template<class T, class U>
        bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

      template<class T> bool operator==(shared_ptr<T> const & p, std::nullptr_t) noexcept;
      template<class T> bool operator==(std::nullptr_t, shared_ptr<T> const & p) noexcept;

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

      template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;

      template<class T>
        typename shared_ptr<T>::element_type *
          get_pointer(shared_ptr<T> const & p) noexcept;

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

      template<class T, class U>
        shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) noexcept;

      template<class T, class U>
        shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept;

      template<class T, class U>
        shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r) noexcept;

      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) noexcept;

      template<class T> bool atomic_is_lock_free( shared_ptr<T> const * p ) noexcept;

      template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) noexcept;
      template<class T>
        shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, int ) noexcept;

      template<class T>
        void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;
      template<class T>
        void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;

      template<class T>
        shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;
      template<class T>
        shared_ptr<T> atomic_exchange_explicit(
          shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;

      template<class T>
        bool atomic_compare_exchange(
          shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) noexcept;
      template<class T>
        bool atomic_compare_exchange_explicit(
          shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, int, int ) noexcept;
    }

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

    constexpr shared_ptr() noexcept;

    constexpr shared_ptr(std::nullptr_t) noexcept;

- Effects

    Constructs an empty `shared_ptr`.

  Postconditions

    `use_count() == 0 && get() == 0`.

#### pointer constructor

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

- Requires

    `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, well-defined, and 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.

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

Note | 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);

- Requires

    `D` must be `CopyConstructible`. The copy constructor and destructor of `D` must not throw. The expression `d(p)` must be well-formed, well-defined, and not throw exceptions. `A` must be an `Allocator`, as described in section Allocator Requirements [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.

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

Note

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.

Note | 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) noexcept;

    template<class Y> shared_ptr(shared_ptr<Y> const & r) noexcept;

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

#### move constructors

    shared_ptr(shared_ptr && r) noexcept;

    template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept;

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

#### aliasing constructor

    template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;

- Effects

    constructs a `shared_ptr` that shares ownership with `r` and stores `p`.

  Postconditions

    `get() == p && use_count() == r.use_count()`.

#### aliasing move constructor

    template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept;

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

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

    - When `r.get() == 0`, equivalent to `shared_ptr()`;

    - When `D` is not a reference type, equivalent to `shared_ptr(r.release(), r.get_deleter())`;

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

  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() noexcept;

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

#### assignment

    shared_ptr & operator=(shared_ptr const & r) noexcept;

    template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r) noexcept;

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

- Effects

    Equivalent to `shared_ptr(r).swap(*this)`.

  Returns

    `*this`.

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

Note

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) noexcept;

    template<class Y> shared_ptr & operator=(shared_ptr<Y> && r) noexcept;

    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) noexcept;

- Effects

    Equivalent to `shared_ptr().swap(*this)`.

  Returns

    `*this`.

#### reset

    void reset() noexcept;

- 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) noexcept;

- Effects

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

    template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;

- Effects

    Equivalent to `shared_ptr(std::move(r), p).swap(*this)`.

#### indirection

    T & operator*() const noexcept;

- Requires

    `T` should not be an array type. The stored pointer must not be 0.

  Returns

    `*get()`.

    T * operator->() const noexcept;

- Requires

    `T` should not be an array type. The stored pointer must not be 0.

  Returns

    `get()`.

    element_type & operator[](std::ptrdiff_t i) const noexcept;

- Requires

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

#### get

    element_type * get() const noexcept;

- Returns

    The stored pointer.

#### unique

    bool unique() const noexcept;

- Returns

    `use_count() == 1`.

#### use_count

    long use_count() const noexcept;

- Returns

    The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.

#### conversions

    explicit operator bool() const noexcept;

- Returns

    `get() != 0`.

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

Note | The conversion to `bool` is not merely syntactic sugar. It allows `shared_ptr` variables to be declared in conditions when using `dynamic_pointer_cast` or `weak_ptr::lock`.

Note | On C++03 compilers, the return value is of an unspecified type.

#### swap

    void swap(shared_ptr & b) noexcept;

- Effects

    Exchanges the contents of the two smart pointers.

#### owner_before

    template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;

    template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;

- Effects

    See the description of `operator<`.

### Free Functions

#### comparison

    template<class T, class U>
      bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

- Returns

    `a.get() == b.get()`.

    template<class T, class U>
      bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

- Returns

    `a.get() != b.get()`.

    template<class T> bool operator==(shared_ptr<T> const & p, std::nullptr_t) noexcept;

    template<class T> bool operator==(std::nullptr_t, shared_ptr<T> const & p) noexcept;

- Returns

    `p.get() == 0`.

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

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

- Returns

    `p.get() != 0`.

    template<class T, class U>
      bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

- Returns

    An unspecified value such that

    - `operator<` is a strict weak ordering as described in section [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.

Note | Allows `shared_ptr` objects to be used as keys in associative containers.

Note | The rest of the comparison operators are omitted by design.

#### swap

    template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;

- Effects

    Equivalent to `a.swap(b)`.

#### get_pointer

    template<class T>
      typename shared_ptr<T>::element_type *
        get_pointer(shared_ptr<T> const & p) noexcept;

- Returns

    `p.get()`.

Note | 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) noexcept;

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

Caution | 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) noexcept;

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

#### dynamic_pointer_cast

    template<class T, class U>
        shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept;

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

#### reinterpret_pointer_cast

    template<class T, class U>
      shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r) noexcept;

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

#### 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) noexcept;

- Returns

    If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0.

#### Atomic Access

Note | The function in this section are atomic with respect to the first `shared_ptr` argument, identified by `*p`. Concurrent access to the same `shared_ptr` instance is not a data race, if done exclusively by the functions in this section.

    template<class T> bool atomic_is_lock_free( shared_ptr<T> const * p ) noexcept;

- Returns

    `false`.

Note | This implementation is not lock-free.

    template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) noexcept;

    template<class T> shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, int ) noexcept;

- Returns

    `*p`.

Note | The `int` argument is the `memory_order`, but this implementation does not use it, as it’s lock-based and therefore always sequentially consistent.

    template<class T>
      void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;

    template<class T>
      void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;

- Effects

    `p->swap(r)`.

    template<class T>
      shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;

    template<class T>
      shared_ptr<T> atomic_exchange_explicit(
        shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;

- Effects

    `p->swap(r)`.

  Returns

    The old value of `*p`.

    template<class T>
      bool atomic_compare_exchange(
        shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) noexcept;

    template<class T>
      bool atomic_compare_exchange_explicit(
        shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, int, int ) noexcept;

- Effects

    If `*p` is equivalent to `*v`, assigns `w` to `*p`, otherwise assigns `*p` to `*v`.

  Returns

    `true` if `*p` was equivalent to `*v`, `false` otherwise.

  Remarks

    Two `shared_ptr` instances are equivalent if they store the same pointer value and share ownership.

### 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));

Code Example 4. Reading a `shared_ptr` from two threads

    // thread A
    shared_ptr<int> p2(p); // reads p

    // thread B
    shared_ptr<int> p3(p); // OK, multiple reads are safe

Code Example 5. Writing different `shared_ptr` instances from two threads

    // thread A
    p.reset(new int(1912)); // writes p

    // thread B
    p2.reset(); // OK, writes p2

Code Example 6. Reading and writing a `shared_ptr` from two threads

    // thread A
    p = p3; // reads p3, writes p

    // thread B
    p3.reset(); // writes p3; undefined, simultaneous read/write

Code Example 7. Reading and destroying a `shared_ptr` from two threads

    // thread A
    p3 = p2; // reads p2, writes p3

    // thread B
    // p2 goes out of scope: undefined, the destructor is considered a "write access"

Code Example 8. Writing a `shared_ptr` from two threads

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

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

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

2. Why doesn’t shared_ptr have template parameters supplying traits or policies to allow extensive user customization?

   Parameterization discourages users. The `shared_ptr` template is carefully crafted to meet common needs without extensive parameterization.

3. I am not convinced. Default parameters can be used where appropriate to hide the complexity. Again, why not policies?

   Template parameters affect the type. See the answer to the first question above.

4. Why doesn’t `shared_ptr` use a linked list implementation?

   A linked list implementation does not offer enough advantages to offset the added cost of an extra pointer. In addition, it is expensive to make a linked list implementation thread safe.

5. Why doesn’t `shared_ptr` (or any of the other Boost smart pointers) supply an automatic conversion to T*?

   Automatic conversion is believed to be too error prone.

6. Why does `shared_ptr` supply `use_count()`?

   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.

7. Why doesn’t `shared_ptr` specify complexity requirements?

   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.

8. Why doesn’t `shared_ptr` provide a `release()` function?

   `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, or may have pointed to an object of a different type.

9. Why is `operator->()` const, but its return value is a non-const pointer to the element type?

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

## weak_ptr: Non-owning Observer

### Description

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 taking `weak_ptr`, or the `weak_ptr` 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` had a get member function that returned 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

`weak_ptr` is defined in `<boost/smart_ptr/weak_ptr.hpp>`.

    namespace boost {

      template<class T> class weak_ptr {
      public:

        typedef /*see below*/ element_type;

        weak_ptr() noexcept;

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

        weak_ptr(weak_ptr && r) noexcept;

        ~weak_ptr() noexcept;

        weak_ptr & operator=(weak_ptr const & r) noexcept;
        weak_ptr & operator=(weak_ptr && r) noexcept;
        template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;
        template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;

        long use_count() const noexcept;
        bool expired() const noexcept;

        shared_ptr<T> lock() const noexcept;

        void reset() noexcept;

        void swap(weak_ptr<T> & b) noexcept;

        template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
        template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
      };

      template<class T, class U>
        bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;

      template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
    }

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

#### constructors

    weak_ptr() noexcept;

- Effects

    Constructs an empty `weak_ptr`.

  Postconditions

    `use_count() == 0`.

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

    weak_ptr(weak_ptr const & r) noexcept;

    template<class Y> weak_ptr(weak_ptr<Y> const & r) noexcept;

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

    weak_ptr(weak_ptr && r) noexcept;

- Effects

    Constructs a `weak_ptr` that has the value `r` held.

  Postconditions

    `r` is empty.

#### destructor

    ~weak_ptr() noexcept;

- Effects

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

#### assignment

    weak_ptr & operator=(weak_ptr const & r) noexcept;

    weak_ptr & operator=(weak_ptr && r) noexcept;

    template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;

    template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;

- Effects

    Equivalent to `weak_ptr(r).swap(*this)`.

Note | 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 noexcept;

- Returns

    0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`.

#### expired

    bool expired() const noexcept;

- Returns

    `use_count() == 0`.

#### lock

    shared_ptr<T> lock() const noexcept;

- Returns

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

#### reset

    void reset() noexcept;

- Effects

    Equivalent to `weak_ptr().swap(*this)`.

#### swap

    void swap(weak_ptr & b) noexcept;

- Effects

    Exchanges the contents of the two smart pointers.

    template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;

    template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;

- Returns

    See the description of `operator<`.

### Free Functions

#### comparison

    template<class T, class U>
      bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;

- Returns

    An unspecified value such that

    - `operator<` is a strict weak ordering as described in section [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.

Note | 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) noexcept;

- Effects

    Equivalent to `a.swap(b)`.

### Frequently Asked Questions

1. Can an object create a weak_ptr to itself in its constructor?

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

## make_shared: Creating shared_ptr

### Description

The function templates `make_shared` and `allocate_shared` provide convenient, safe and efficient ways to create `shared_ptr` objects.

### Rationale

Consistent use of `shared_ptr` can eliminate the need to use an explicit `delete`, but alone it provides no support in avoiding explicit `new`. There were repeated requests from users for a factory function that creates an object of a given type and returns a `shared_ptr` to it. Besides convenience and style, such a function is also exception safe and considerably faster because it can use a single allocation for both the object and its corresponding control block, eliminating a significant portion of `shared_ptr` construction overhead. This eliminates one of the major efficiency complaints about `shared_ptr`.

The family of overloaded function templates, `make_shared` and `allocate_shared`, were provided to address this need. `make_shared` uses the global `operator new` to allocate memory, whereas `allocate_shared` uses an user-supplied allocator, allowing finer control.

The rationale for choosing the name `make_shared` is that the expression `make_shared<Widget>()` can be read aloud and conveys the intended meaning.

Originally the Boost function templates `allocate_shared` and `make_shared` were provided for scalar objects only. There was a need to have efficient allocation of array objects. One criticism of class template `shared_array` was always the lack of a utility like `make_shared` that uses only a single allocation. When `shared_ptr` was enhanced to support array types, additional overloads of `allocate_shared` and `make_shared` were provided for array types.

### Synopsis

`make_shared` and `allocate_shared` are defined in `<boost/smart_ptr/make_shared.hpp>`.

    namespace boost {
      // only if T is not an array type
      template<class T, class... Args>
        shared_ptr<T> make_shared(Args&&... args);
      template<class T, class A, class... Args>
        shared_ptr<T> allocate_shared(const A& a, Args&&... args);

      // only if T is an array type of the form U[]
      template<class T>
        shared_ptr<T> make_shared(std::size_t n);
      template<class T, class A>
        shared_ptr<T> allocate_shared(const A& a, std::size_t n);

      // only if T is an array type of the form U[N]
      template<class T>
        shared_ptr<T> make_shared();
      template<class T, class A>
        shared_ptr<T> allocate_shared(const A& a);

      // only if T is an array type of the form U[]
      template<class T> shared_ptr<T>
        make_shared(std::size_t n, const remove_extent_t<T>& v);
      template<class T, class A> shared_ptr<T>
        allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);

      // only if T is an array type of the form U[N]
      template<class T>
        shared_ptr<T> make_shared(const remove_extent_t<T>& v);
      template<class T, class A>
        shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);

      // only if T is not an array type of the form U[]
      template<class T>
        shared_ptr<T> make_shared_noinit();
      template<class T, class A>
        shared_ptr<T> allocate_shared_noinit(const A& a);

      // only if T is an array type of the form U[N]
      template<class T>
        shared_ptr<T> make_shared_noinit(std::size_t n);
      template<class T, class A>
        shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
    }

### Common Requirements

The common requirements that apply to all `make_shared` and `allocate_shared` overloads, unless specified otherwise, are described below.

Requires

  `A` shall be an allocator. The copy constructor and destructor of `A` shall not throw exceptions.

Effects

  Allocates memory for an object of type `T` or `n` objects of `U` (if `T` is an array type of the form `U[]` and `n` is determined by arguments, as specified by the concrete overload). The object is initialized from arguments as specified by the concrete overload. Uses a rebound copy of `a` (for an unspecified `value_type`) to allocate memory. If an exception is thrown, the functions have no effect.

Returns

  A `shared_ptr` instance that stores and owns the address of the newly constructed object.

Postconditions

  `r.get() != 0` and `r.use_count() == 1`, where `r` is the return value.

Throws

  `std::bad_alloc`, an exception thrown from `A::allocate`, or from the initialization of the object.

Remarks

  - Performs no more than one memory allocation. This provides efficiency equivalent to an intrusive smart pointer.

  - When an object of an array type is specified to be initialized to a value of the same type `v`, this shall be interpreted to mean that each array element of the object is initialized to the corresponding element from `v`.

  - When an object of an array type is specified to be value-initialized, this shall be interpreted to mean that each array element of the object is value-initialized.

  - When a (sub)object of non-array type `U` is specified to be initialized to a value `v`, or constructed from `args...`, `make_shared` shall perform this initialization via the expression `::new(p) U(expr)` (where `expr` is `v` or `std::forward<Args>(args)...)` respectively) and `p` has type `void*` and points to storage suitable to hold an object of type `U`.

  - When a (sub)object of non-array type `U` is specified to be initialized to a value `v`, or constructed from `args...`, `allocate_shared` shall perform this initialization via the expression `std::allocator_traits<A2>::construct(a2, p, expr)` (where `expr` is `v` or `std::forward<Args>(args)...)` respectively), `p` points to storage suitable to hold an object of type `U`, and `a2` of type `A2` is a rebound copy `a` such that its `value_type` is `U`.

  - When a (sub)object of non-array type `U` is specified to be default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall perform this initialization via the expression `::new(p) U`, where `p` has type `void*` and points to storage suitable to hold an object of type `U`.

  - When a (sub)object of non-array type `U` is specified to be value-initialized, `make_shared` shall perform this initialization via the expression `::new(p) U()`, where `p` has type `void*` and points to storage suitable to hold an object of type `U`.

  - When a (sub)object of non-array type `U` is specified to be value-initialized, `allocate_shared` shall perform this initialization via the expression `std::allocator_traits<A2>::construct(a2, p)`, where `p` points to storage suitable to hold an object of type `U` and `a2` of type `A2` is a rebound copy of `a` such that its value_type is `U`.

  - Array elements are initialized in ascending order of their addresses.

  - When the lifetime of the object managed by the return value ends, or when the initialization of an array element throws an exception, the initialized elements should be destroyed in the reverse order of their construction.

Note | These functions will typically allocate more memory than the total size of the element objects to allow for internal bookkeeping structures such as the reference counts.

### Free Functions

    template<class T, class... Args>
      shared_ptr<T> make_shared(Args&&... args);

    template<class T, class A, class... Args>
      shared_ptr<T> allocate_shared(const A& a, Args&&... args);

  Remarks

    These overloads shall only participate in overload resolution when `T` is not an array type.

  Returns

    A `shared_ptr` to an object of type `T`, constructed from `args...`.

  Examples

    - `auto p = make_shared<int>();`

    - `auto p = make_shared<std::vector<int> >(16, 1);`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[]`.

  Returns

    A `shared_ptr` to a sequence of `n` value-initialized objects of type `U`.

  Examples

    - `auto p = make_shared<double[]>(1024);`

    - `auto p = make_shared<double[][2][2]>(6);`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[N]`.

  Returns

    A `shared_ptr` to a sequence of `N` value-initialized objects of type `U`.

  Examples

    - `auto p = make_shared<double[1024]>();`

    - `auto p = make_shared<double[6][2][2]>();`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[]`.

  Returns

    A `shared_ptr` to a sequence of `n` objects of type `U`, each initialized to `v`.

  Examples

    - `auto p = make_shared<double[]>(1024, 1.0);`

    - `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`

    - `auto p = make_shared<std::vector<int>[]>(4, {1, 2});`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[N]`.

  Returns

    A `shared_ptr` to a sequence of `N` objects of type `U`, each initialized to `v`.

  Examples

    - `auto p = make_shared<double[1024]>(1.0);`

    - `auto p = make_shared<double[6][2]>({1.0, 0.0});`

    - `auto p = make_shared<std::vector<int>[4]>({1, 2});`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is not an array type, or an array type of the `U[N]`.

  Returns

    A `shared_ptr` to a default-initialized object of type `T`, or a sequence of `N` default-initialized objects of type `U`, respectively.

  Example

    `auto p = make_shared_noinit<double[1024]>();`

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

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[]`.

  Returns

    A `shared_ptr` to a sequence of `n` default-initialized objects of type `U`.

  Example

    `auto p = make_shared_noinit<double[]>(1024);`

## enable_shared_from_this

### Description

The class template `enable_shared_from_this` 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

`enable_shared_from_this` is defined in `<boost/smart_ptr/enable_shared_from_this.hpp>`.

    namespace boost {

      template<class T> class enable_shared_from_this {
      private:

        // exposition only
        weak_ptr<T> weak_this_;

      protected:

        enable_shared_from_this() = default;
        ~enable_shared_from_this() = default;

        enable_shared_from_this(const enable_shared_from_this&) noexcept;
        enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;

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

### Members

    enable_shared_from_this(enable_shared_from_this const &) noexcept;

- Effects

    Default-constructs `weak_this_`.

Note | `weak_this_` is not copied from the argument.

    enable_shared_from_this& operator=(enable_shared_from_this const &) noexcept;

- Returns

    `*this`.

Note | `weak_this_` is unchanged.

    template<class T> shared_ptr<T> shared_from_this();

    template<class T> shared_ptr<T const> shared_from_this() const;

- Returns

    `shared_ptr<T>(weak_this_)`.

Note | These members throw `bad_weak_ptr` when `*this` is not owned by a `shared_ptr`.

Note

`weak_this_` is initialized by `shared_ptr` to a copy of itself when it’s constructed by a pointer to `*this`. For example, in the following code:

    class Y: public boost::enable_shared_from_this<Y> {};

    int main()
    {
        boost::shared_ptr<Y> p(new Y);
    }

the construction of `p` will automatically initialize `p->weak_this_` to `p`.

    template<class T> weak_ptr<T> weak_from_this() noexcept;

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

- Returns

    `weak_this_`.

## make_unique: Creating unique_ptr

### Description

The `make_unique` function templates provide convenient and safe ways to create `std::unique_ptr` objects.

### Rationale

The C++11 standard introduced `std::unique_ptr` but did not provide any `make_unique` utility like `std::make_shared` that provided the same exception safety and facility to avoid writing `new` expressions. Before it was implemented by some standard library vendors (and prior to the C++14 standard introducing `std::make_unique`), this library provided it due to requests from users.

This library also provides additional overloads of `make_unique` for default-initialization, when users do not need or want to incur the expense of value-initialization. The C++ standard does not yet provide this feature with `std::make_unique`.

### Synopsis

`make_unique` is defined in `<boost/smart_ptr/make_unique.hpp>`.

    namespace boost {
      // only if T is not an array type
      template<class T, class... Args>
        std::unique_ptr<T> make_unique(Args&&... args);

      // only if T is not an array type
      template<class T>
        std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);

      // only if T is an array type of the form U[]
      template<class T>
        std::unique_ptr<T> make_unique(std::size_t n);

      // only if T is not an array type
      template<class T>
        std::unique_ptr<T> make_unique_noinit();

      // only if T is an array type of the form U[]
      template<class T>
        std::unique_ptr<T> make_unique_noinit(std::size_t n);
    }

### Free Functions

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is not an array type.

  Returns

    `std::unique_ptr<T>(new T(std::forward<Args>(args)...)`.

  Example

    `auto p = make_unique<int>();`

    template<class T>
      std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);

  Remarks

    These overloads shall only participate in overload resolution when `T` is not an array type.

  Returns

    `std::unique_ptr<T>(new T(std::move(v))`.

  Example

    `auto p = make_unique<std::vector<int> >({1, 2});`

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[]`.

  Returns

    `std::unique_ptr<U[]>(new U[n]())`.

  Example

    `auto p = make_unique<double[]>(1024);`

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is not an array type.

  Returns

    `std::unique_ptr<T>(new T)`.

  Example

    `auto p = make_unique_noinit<double[1024]>();`

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

  Remarks

    These overloads shall only participate in overload resolution when `T` is an array type of the form `U[]`.

  Returns

    `std::unique_ptr<U[]>(new U[n])`.

  Example

    `auto p = make_unique_noinit<double[]>(1024);`

## intrusive_ptr: Managing Objects with Embedded Counts

### Description

The `intrusive_ptr` class template stores a pointer to an object with an embedded reference count. Every new `intrusive_ptr` instance increments the reference count by using an unqualified call to the function `intrusive_ptr_add_ref`, passing it the pointer as an argument. Similarly, when an `intrusive_ptr` is destroyed, it calls `intrusive_ptr_release`; this function is responsible for destroying the object when its reference count drops to zero. The user is expected to provide suitable definitions of these two functions. On compilers that support argument-dependent lookup, `intrusive_ptr_add_ref` and `intrusive_ptr_release` should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace `boost`. The library provides a helper base class template `intrusive_ref_counter` which may help adding support for `intrusive_ptr` to user types.

The class template is parameterized on `T`, the type of the object pointed to. `intrusive_ptr<T>` can be implicitly converted to `intrusive_ptr<U>` whenever `T*` can be implicitly converted to `U*`.

The main reasons to use `intrusive_ptr` are:

- Some existing frameworks or OSes provide objects with embedded reference counts;

- The memory footprint of `intrusive_ptr` is the same as the corresponding raw pointer;

- `intrusive_ptr<T>` can be constructed from an arbitrary raw pointer of type `T*`.

As a general rule, if it isn’t obvious whether `intrusive_ptr` better fits your needs than `shared_ptr`, try a `shared_ptr`-based design first.

### Synopsis

`intrusive_ptr` is defined in `<boost/smart_ptr/intrusive_ptr.hpp>`.

    namespace boost {

      template<class T> class intrusive_ptr {
      public:

        typedef T element_type;

        intrusive_ptr() noexcept;
        intrusive_ptr(T * p, bool add_ref = true);

        intrusive_ptr(intrusive_ptr const & r);
        template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);

        ~intrusive_ptr();

        intrusive_ptr & operator=(intrusive_ptr const & r);
        template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
        intrusive_ptr & operator=(T * r);

        void reset();
        void reset(T * r);
        void reset(T * r, bool add_ref);

        T & operator*() const noexcept;
        T * operator->() const noexcept;
        T * get() const noexcept;
        T * detach() noexcept;

        explicit operator bool () const noexcept;

        void swap(intrusive_ptr & b) noexept;
      };

      template<class T, class U>
        bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;

      template<class T, class U>
        bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;

      template<class T, class U>
        bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

      template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;

      template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;

      template<class T, class U>
        intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;

      template<class T, class U>
        intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;

      template<class T, class U>
        intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;

      template<class E, class T, class Y>
        std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
          intrusive_ptr<Y> const & p);
    }

### Members

#### element_type

    typedef T element_type;

Provides the type of the template parameter T.

#### constructors

    intrusive_ptr() noexcept;

- Postconditions

    `get() == 0`.

    intrusive_ptr(T * p, bool add_ref = true);

- Effects

    `if(p != 0 && add_ref) intrusive_ptr_add_ref(p);`.

  Postconditions

    `get() == p`.

    intrusive_ptr(intrusive_ptr const & r);

    template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);

- Effects

    `T * p = r.get(); if(p != 0) intrusive_ptr_add_ref(p);`.

  Postconditions

    `get() == r.get()`.

#### destructor

    ~intrusive_ptr();

- Effects

    `if(get() != 0) intrusive_ptr_release(get());`.

#### assignment

    intrusive_ptr & operator=(intrusive_ptr const & r);

    template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);

    intrusive_ptr & operator=(T * r);

- Effects

    Equivalent to `intrusive_ptr(r).swap(*this)`.

  Returns

    `*this`.

#### reset

    void reset();

- Effects

    Equivalent to `intrusive_ptr().swap(*this)`.

    void reset(T * r);

- Effects

    Equivalent to `intrusive_ptr(r).swap(*this)`.

    void reset(T * r, bool add_ref);

- Effects

    Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.

#### indirection

    T & operator*() const noexcept;

- Requirements

    `get() != 0`.

  Returns

    `*get()`.

    T * operator->() const noexcept;

- Requirements

    `get() != 0`.

  Returns

    `get()`.

#### get

    T * get() const noexcept;

- Returns

    the stored pointer.

#### detach

    T * detach() noexcept;

- Returns

    the stored pointer.

  Postconditions

    `get() == 0`.

Note | The returned pointer has an elevated reference count. This allows conversion of an `intrusive_ptr` back to a raw pointer, without the performance overhead of acquiring and dropping an extra reference. It can be viewed as the complement of the non-reference-incrementing constructor.

Caution | Using `detach` escapes the safety of automatic reference counting provided by `intrusive_ptr`. It should by used only where strictly necessary (such as when interfacing to an existing API), and when the implications are thoroughly understood.

#### conversions

    explicit operator bool () const noexcept;

- Returns

    `get() != 0`.

Note | This conversion operator allows `intrusive_ptr` objects to be used in boolean contexts, like `if (p && p->valid()) {}`.

Note | On C++03 compilers, the return value is of an unspecified type.

#### swap

    void swap(intrusive_ptr & b) noexcept;

- Effects

    Exchanges the contents of the two smart pointers.

### Free Functions

#### comparison

    template<class T, class U>
      bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

- Returns

    `a.get() == b.get()`.

    template<class T, class U>
      bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

- Returns

    `a.get() != b.get()`.

    template<class T, class U>
      bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;

- Returns

    `a.get() == b`.

    template<class T, class U>
      bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;

- Returns

    `a.get() != b`.

    template<class T, class U>
      bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;

- Returns

    `a == b.get()`.

    template<class T, class U>
      bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;

- Returns

    `a != b.get()`.

    template<class T, class U>
      bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;

- Returns

    `std::less<T *>()(a.get(), b.get())`.

Note | Allows `intrusive_ptr` objects to be used as keys in associative containers.

#### swap

    template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;

- Effects

    Equivalent to `a.swap(b)`.

#### get_pointer

    template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;

- Returns

    `p.get()`.

Note | Provided as an aid to generic programming. Used by `mem_fn`.

#### static_pointer_cast

    template<class T, class U>
      intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;

- Returns

    `intrusive_ptr<T>(static_cast<T*>(r.get()))`.

#### const_pointer_cast

    template<class T, class U>
      intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;

- Returns

    `intrusive_ptr<T>(const_cast<T*>(r.get()))`.

#### dynamic_pointer_cast

    template<class T, class U>
      intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;

- Returns

    `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.

#### operator<<

    template<class E, class T, class Y>
      std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
        intrusive_ptr<Y> const & p);

- Effects

    `os << p.get();`.

  Returns

    `os`.

## intrusive_ref_counter

### Description

The `intrusive_ref_counter` class template implements a reference counter for a derived user’s class that is intended to be used with `intrusive_ptr`. The base class has associated `intrusive_ptr_add_ref` and `intrusive_ptr_release` functions which modify the reference counter as needed and destroy the user’s object when the counter drops to zero.

The class template is parameterized on `Derived` and `CounterPolicy` parameters. The first parameter is the user’s class that derives from `intrusive_ref_counter`. This type is needed in order to destroy the object correctly when there are no references to it left.

The second parameter is a policy that defines the nature of the reference counter. The library provides two such policies: `thread_unsafe_counter` and `thread_safe_counter`. The former instructs the `intrusive_ref_counter` base class to use a counter only suitable for a single-threaded use. Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy makes the reference counter thread-safe, unless the target platform doesn’t support threading. Since in modern systems support for threading is common, the default counter policy is `thread_safe_counter`.

### Synopsis

`intrusive_ref_counter` is defined in `<boost/smart_ptr/intrusive_ref_counter.hpp>`.

    namespace boost {
      struct thread_unsafe_counter;
      struct thread_safe_counter;

      template<class Derived, class CounterPolicy = thread_safe_counter>
      class intrusive_ref_counter {
      public:
        intrusive_ref_counter() noexcept;
        intrusive_ref_counter(const intrusive_ref_counter& v) noexcept;

        intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;

        unsigned int use_count() const noexcept;

      protected:
        ~intrusive_ref_counter() = default;
      };

      template<class Derived, class CounterPolicy>
        void intrusive_ptr_add_ref(
          const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;

      template<class Derived, class CounterPolicy>
        void intrusive_ptr_release(
          const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
    }

### Members

#### Constructors

    intrusive_ref_counter() noexcept;

    intrusive_ref_counter(const intrusive_ref_counter&) noexcept;

  Postconditions

    `use_count() == 0`.

Note | The pointer to the constructed object is expected to be passed to `intrusive_ptr` constructor, assignment operator or `reset` method, which would increment the reference counter.

#### Destructor

    ~intrusive_ref_counter();

  Effects

    Destroys the counter object.

Note | The destructor is protected so that the object can only be destroyed through the `Derived` class.

#### Assignment

    intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;

  Effects

    Does nothing, reference counter is not modified.

#### use_count

    unsigned int use_count() const noexcept;

  Returns

    The current value of the reference counter.

Note | The returned value may not be actual in multi-threaded applications.

### Free Functions

#### intrusive_ptr_add_ref

    template<class Derived, class CounterPolicy>
      void intrusive_ptr_add_ref(
        const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;

  Effects

    Increments the reference counter.

#### intrusive_ptr_release

    template<class Derived, class CounterPolicy>
      void intrusive_ptr_release(
        const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;

  Effects

    Decrements the reference counter. If the reference counter reaches 0, calls `delete static_cast<const Derived*>(p)`.

## local_shared_ptr: Shared Ownership within a Single Thread

### Description

`local_shared_ptr` is nearly identical to `shared_ptr`, with the only difference of note being that its reference count is updated with non-atomic operations. As such, a `local_shared_ptr` and all its copies must reside in (be local to) a single thread (hence the name.)

`local_shared_ptr` can be converted to `shared_ptr` and vice versa. Creating a `local_shared_ptr` from a `shared_ptr` creates a new local reference count; this means that two `local_shared_ptr` instances, both created from the same `shared_ptr`, refer to the same object but don’t share the same count, and as such, can safely be used by two different threads.

Code Example 9. Two local_shared_ptr instances created from a shared_ptr

    shared_ptr<X> p1( new X );

    local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
    local_shared_ptr<X> p3( p1 ); // p3.local_use_count() also 1

Creating the second `local_shared_ptr` from the first one, however, does lead to the two sharing the same count:

Code Example 10. A local_shared_ptr created from another local_shared_ptr

    shared_ptr<X> p1( new X );

    local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
    local_shared_ptr<X> p3( p2 ); // p3.local_use_count() == 2

Two `shared_ptr` instances created from the same `local_shared_ptr` do share ownership:

Code Example 11. Two shared_ptr instances created from a local_shared_ptr

    local_shared_ptr<X> p1( new X );

    shared_ptr<X> p2( p1 ); // p2.use_count() == 2
    shared_ptr<X> p3( p1 ); // p3.use_count() == 3

Here `p2.use_count()` is 2, because `p1` holds a reference, too.

One can think of `local_shared_ptr<T>` as `shared_ptr<shared_ptr<T>>`, with the outer `shared_ptr` using non-atomic operations for its count. Converting from `local_shared_ptr` to `shared_ptr` gives you a copy of the inner `shared_ptr`; converting from `shared_ptr` wraps it into an outer `shared_ptr` with a non-atomic use count (conceptually speaking) and returns the result.

### Synopsis

`local_shared_ptr` is defined in `<boost/smart_ptr/local_shared_ptr.hpp>`.

    namespace boost {

      template<class T> class local_shared_ptr {
      public:

        typedef /*see below*/ element_type;

        // constructors

        constexpr local_shared_ptr() noexcept;
        constexpr local_shared_ptr(std::nullptr_t) noexcept;

        template<class Y> explicit local_shared_ptr(Y * p);

        template<class Y, class D> local_shared_ptr(Y * p, D d);
        template<class D> local_shared_ptr(std::nullptr_t p, D d);

        template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
        template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);

        local_shared_ptr(local_shared_ptr const & r) noexcept;
        template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;

        local_shared_ptr(local_shared_ptr && r) noexcept;
        template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;

        template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
        template<class Y> local_shared_ptr( shared_ptr<Y> && r );

        template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
        template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;

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

        // destructor

        ~local_shared_ptr() noexcept;

        // assignment

        local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
        template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;

        local_shared_ptr & operator=(local_shared_ptr const && r) noexcept;
        template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const && r) noexcept;

        template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);

        local_shared_ptr & operator=(std::nullptr_t) noexcept;

        // reset

        void reset() noexcept;

        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(local_shared_ptr<Y> const & r, element_type * p) noexcept;
        template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;

        // accessors

        T & operator*() const noexcept; // only valid when T is not an array type
        T * operator->() const noexcept; // only valid when T is not an array type

        // only valid when T is an array type
        element_type & operator[](std::ptrdiff_t i) const noexcept;

        element_type * get() const noexcept;

        long local_use_count() const noexcept;

        // conversions

        explicit operator bool() const noexcept;

        template<class Y> operator shared_ptr<Y>() const noexcept;
        template<class Y> operator weak_ptr<Y>() const noexcept;

        // swap

        void swap(local_shared_ptr & b) noexcept;

        // owner_before

        template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
      };

      // comparisons

      template<class T, class U>
        bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
      template<class T, class U>
        bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
      template<class T, class U>
        bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

      template<class T, class U>
        bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
      template<class T, class U>
        bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
      template<class T, class U>
        bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

      template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
      template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;

      template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
      template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;

      template<class T, class U>
        bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

      // swap

      template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;

      // get_pointer

      template<class T>
        typename local_shared_ptr<T>::element_type *
          get_pointer(local_shared_ptr<T> const & p) noexcept;

      // casts

      template<class T, class U>
        local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;

      template<class T, class U>
        local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;

      template<class T, class U>
        local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;

      template<class T, class U>
        local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;

      // stream I/O

      template<class E, class T, class Y>
        std::basic_ostream<E, T> &
          operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);

      // get_deleter

      template<class D, class T> D * get_deleter(local_shared_ptr<T> const & p) noexcept;
    }

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

    constexpr local_shared_ptr() noexcept;

    constexpr local_shared_ptr(std::nullptr_t) noexcept;

- Effects

    Constructs an empty `local_shared_ptr`.

  Postconditions

    `local_use_count() == 0 && get() == 0`.

#### pointer constructor

    template<class Y> explicit local_shared_ptr(Y * p);

- Effects

    Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p )`.

  Postconditions

    `local_use_count() == 1 && get() == p`.

  Throws

    `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.

#### constructors taking a deleter

    template<class Y, class D> local_shared_ptr(Y * p, D d);

    template<class D> local_shared_ptr(std::nullptr_t p, D d);

- Effects

    Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d )`.

  Postconditions

    `local_use_count() == 1 && get() == p`.

  Throws

    `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.

    template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);

    template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);

- Effects

    Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d, a )`.

  Postconditions

    `local_use_count() == 1 && get() == p`.

  Throws

    `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.

#### copy and converting constructors

    local_shared_ptr(local_shared_ptr const & r) noexcept;

    template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;

- Requires

    `Y*` should be convertible to `T*`.

  Effects

    If `r` is empty, constructs an empty `local_shared_ptr`; otherwise, constructs a `local_shared_ptr` that shares ownership with `r`.

  Postconditions

    `get() == r.get() && local_use_count() == r.local_use_count()`.

#### move constructors

    local_shared_ptr(local_shared_ptr && r) noexcept;

    template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;

- Requires

    `Y*` should be convertible to `T*`.

  Effects

    Move-constructs a `local_shared_ptr` from `r`.

  Postconditions

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

#### shared_ptr constructor

    template<class Y> local_shared_ptr( shared_ptr<Y> const & r );

    template<class Y> local_shared_ptr( shared_ptr<Y> && r );

- Effects

    Constructs a `local_shared_ptr` that owns `r`.

  Postconditions

    `local_use_count() == 1`. `get()` returns the old value of `r.get()`.

  Throws

    `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.

#### aliasing constructor

    template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;

- Effects

    constructs a `local_shared_ptr` that shares ownership with `r` and stores `p`.

  Postconditions

    `get() == p && local_use_count() == r.local_use_count()`.

#### aliasing move constructor

    template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;

- Effects

    Move-constructs a `local_shared_ptr` from `r`, while storing `p` instead.

  Postconditions

    `get() == p` and `local_use_count()` equals the old count of `r`. `r` is empty and `r.get() == 0`.

#### unique_ptr constructor

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

- Requires

    `Y*` should be convertible to `T*`.

  Effects

    - When `r.get() == 0`, equivalent to `local_shared_ptr()`;

    - Otherwise, constructs a `local_shared_ptr` that owns `shared_ptr<T>( std::move(r) )`.

  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

    ~local_shared_ptr() noexcept;

- Effects

    - If `*this` is empty, or shares ownership with another `local_shared_ptr` instance (`local_use_count() > 1`), there are no side effects.

    - Otherwise, destroys the owned `shared_ptr`.

#### assignment

    local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;

    template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;

- Effects

    Equivalent to `local_shared_ptr(r).swap(*this)`.

  Returns

    `*this`.

    local_shared_ptr & operator=(local_shared_ptr && r) noexcept;

    template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> && r) noexcept;

    template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);

- Effects

    Equivalent to `local_shared_ptr(std::move(r)).swap(*this)`.

  Returns

    `*this`.

    local_shared_ptr & operator=(std::nullptr_t) noexcept;

- Effects

    Equivalent to `local_shared_ptr().swap(*this)`.

  Returns

    `*this`.

#### reset

    void reset() noexcept;

- Effects

    Equivalent to `local_shared_ptr().swap(*this)`.

    template<class Y> void reset(Y * p);

- Effects

    Equivalent to `local_shared_ptr(p).swap(*this)`.

    template<class Y, class D> void reset(Y * p, D d);

- Effects

    Equivalent to `local_shared_ptr(p, d).swap(*this)`.

    template<class Y, class D, class A> void reset(Y * p, D d, A a);

- Effects

    Equivalent to `local_shared_ptr(p, d, a).swap(*this)`.

    template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;

- Effects

    Equivalent to `local_shared_ptr(r, p).swap(*this)`.

    template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;

- Effects

    Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.

#### indirection

    T & operator*() const noexcept;

- Requires

    `T` should not be an array type.

  Returns

    `*get()`.

    T * operator->() const noexcept;

- Requires

    `T` should not be an array type.

  Returns

    `get()`.

    element_type & operator[](std::ptrdiff_t i) const noexcept;

- Requires

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

#### get

    element_type * get() const noexcept;

- Returns

    The stored pointer.

#### local_use_count

    long local_use_count() const noexcept;

- Returns

    The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.

#### conversions

    explicit operator bool() const noexcept;

- Returns

    `get() != 0`.

Note | On C++03 compilers, the return value is of an unspecified type.

    template<class Y> operator shared_ptr<Y>() const noexcept;

    template<class Y> operator weak_ptr<Y>() const noexcept;

- Requires

    `T*` should be convertible to `Y*`.

  Returns

    a copy of the owned `shared_ptr`.

#### swap

    void swap(local_shared_ptr & b) noexcept;

- Effects

    Exchanges the contents of the two smart pointers.

#### owner_before

    template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;

- Effects

    See the description of `operator<`.

### Free Functions

#### comparison

    template<class T, class U>
      bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

    template<class T, class U>
      bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

    template<class T, class U>
      bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

- Returns

    `a.get() == b.get()`.

    template<class T, class U>
      bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

    template<class T, class U>
      bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;

    template<class T, class U>
      bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

- Returns

    `a.get() != b.get()`.

    template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;

    template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;

- Returns

    `p.get() == 0`.

    template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;

    template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;

- Returns

    `p.get() != 0`.

    template<class T, class U>
      bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;

- Returns

    An unspecified value such that

    - `operator<` is a strict weak ordering as described in section [lib.alg.sorting] of the C++ standard;

    - under the equivalence relation defined by `operator<`, `!(a < b) && !(b < a)`, two `local_shared_ptr` instances are equivalent if and only if they share ownership or are both empty.

Note | Allows `local_shared_ptr` objects to be used as keys in associative containers.

Note | The rest of the comparison operators are omitted by design.

#### swap

    template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;

- Effects

    Equivalent to `a.swap(b)`.

#### get_pointer

    template<class T>
      typename local_shared_ptr<T>::element_type *
        get_pointer(local_shared_ptr<T> const & p) noexcept;

- Returns

    `p.get()`.

Note | Provided as an aid to generic programming. Used by `mem_fn`.

#### static_pointer_cast

    template<class T, class U>
      local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;

- Requires

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

  Returns

    `local_shared_ptr<T>( r, static_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.

Caution | The seemingly equivalent expression `local_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>
      local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;

- Requires

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

  Returns

    `local_shared_ptr<T>( r, const_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.

#### dynamic_pointer_cast

    template<class T, class U>
        local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;

- Requires

    The expression `dynamic_cast<T*>( (U*)0 )` must be well-formed.

  Returns

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

    - Otherwise, `local_shared_ptr<T>()`.

#### reinterpret_pointer_cast

    template<class T, class U>
      local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;

- Requires

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

  Returns

    `local_shared_ptr<T>( r, reinterpret_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.

#### operator<<

    template<class E, class T, class Y>
      std::basic_ostream<E, T> &
        operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);

- Effects

    `os << p.get();`.

  Returns

    `os`.

#### get_deleter

    template<class D, class T>
      D * get_deleter(local_shared_ptr<T> const & p) noexcept;

- Returns

    If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0.

## make_local_shared: Creating local_shared_ptr

### Description

The function templates `make_local_shared` and `allocate_local_shared` provide convenient, safe and efficient ways to create `local_shared_ptr` objects. They are analogous to `make_shared` and `allocate_shared` for `shared_ptr`.

### Synopsis

`make_local_shared` and `allocate_local_shared` are defined in `<boost/smart_ptr/make_local_shared.hpp>`.

    namespace boost {
      // only if T is not an array type
      template<class T, class... Args>
        local_shared_ptr<T> make_local_shared(Args&&... args);
      template<class T, class A, class... Args>
        local_shared_ptr<T> allocate_local_shared(const A& a, Args&&... args);

      // only if T is an array type of the form U[]
      template<class T>
        local_shared_ptr<T> make_local_shared(std::size_t n);
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n);

      // only if T is an array type of the form U[N]
      template<class T>
        local_shared_ptr<T> make_local_shared();
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared(const A& a);

      // only if T is an array type of the form U[]
      template<class T>
        local_shared_ptr<T> make_local_shared(std::size_t n,
          const remove_extent_t<T>& v);
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n,
          const remove_extent_t<T>& v);

      // only if T is an array type of the form U[N]
      template<class T>
        local_shared_ptr<T> make_local_shared(const remove_extent_t<T>& v);
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared(const A& a,
          const remove_extent_t<T>& v);

      // only if T is not an array type of the form U[]
      template<class T>
        local_shared_ptr<T> make_local_shared_noinit();
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared_noinit(const A& a);

      // only if T is an array type of the form U[N]
      template<class T>
        local_shared_ptr<T> make_local_shared_noinit(std::size_t n);
      template<class T, class A>
        local_shared_ptr<T> allocate_local_shared_noinit(const A& a,
          std::size_t n);
    }

### Description

The requirements and effects of these functions are the same as `make_shared` and `allocate_shared`, except that a `local_shared_ptr` is returned.

## Generic Pointer Casts

### Description

The pointer cast function templates (`static_pointer_cast`, `dynamic_pointer_cast`, `const_pointer_cast`, and `reinterpret_pointer_cast`) provide a way to write generic pointer castings for raw pointers, `std::shared_ptr` and `std::unique_ptr`.

There is test and 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, `shared_ptr<T>` implements a static pointer cast this way:

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

Pointer cast functions templates are overloads of `static_pointer_cast`, `dynamic_pointer_cast`, `const_pointer_cast`, and `reinterpret_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

The generic pointer casts are defined in `<boost/pointer_cast.hpp>`.

    namespace boost {
      template<class T, class U> T* static_pointer_cast(U* p) noexcept;
      template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
      template<class T, class U> T* const_pointer_cast(U* p) noexcept;
      template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;

      template<class T, class U> std::shared_ptr<T>
        static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
      template<class T, class U> std::shared_ptr<T>
        dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
      template<class T, class U> std::shared_ptr<T>
        const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
      template<class T, class U> std::shared_ptr<T>
        reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;

      template<class T, class U> std::unique_ptr<T>
        static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
      template<class T, class U> std::unique_ptr<T>
        dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
      template<class T, class U> std::unique_ptr<T>
        const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
      template<class T, class U> std::unique_ptr<T>
        reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
    }

### Free Functions

#### static_pointer_cast

    template<class T, class U> T* static_pointer_cast(U* p) noexcept;

  Returns

    `static_cast<T*>(p)`

    template<class T, class U> std::shared_ptr<T>
      static_pointer_cast(const std::shared_ptr<U>& p) noexcept;

  Returns

    `std::static_pointer_cast<T>(p)`

    template<class T, class U> std::unique_ptr<T>
      static_pointer_cast(std::unique_ptr<U>&& p) noexcept;

  Requires

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

  Returns

    `std::unique_ptr<T>(static_cast<typename std::unique_ptr<T>::element_type*>(p.release()))`.

Caution | The seemingly equivalent expression `std::unique_ptr<T>(static_cast<T*>(p.get()))` will eventually result in undefined behavior, attempting to delete the same object twice.

#### dynamic_pointer_cast

    template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;

  Returns

    `dynamic_cast<T*>(p)`

    template<class T, class U> std::shared_ptr<T>
      dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;

  Returns

    `std::dynamic_pointer_cast<T>(p)`

    template<class T, class U> std::unique_ptr<T>
      dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;

  Requires

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

    - `T` must have a virtual destructor.

  Returns

    - When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())` returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.release()));`.

    - Otherwise, `std::unique_ptr<T>()`.

#### const_pointer_cast

    template<class T, class U> T* const_pointer_cast(U* p) noexcept;

  Returns

    `const_cast<T*>(p)`

    template<class T, class U> std::shared_ptr<T>
      const_pointer_cast(const std::shared_ptr<U>& p) noexcept;

  Returns

    `std::const_pointer_cast<T>(p)`

    template<class T, class U> std::unique_ptr<T>
      const_pointer_cast(std::unique_ptr<U>&& p) noexcept;

  Requires

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

  Returns

    `std::unique_ptr<T>(const_cast<typename std::unique_ptr<T>::element_type*>(p.release()))`.

#### reinterpret_pointer_cast

    template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;

  Returns

    `reinterpret_cast<T*>(p)`

    template<class T, class U> std::shared_ptr<T>
      reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;

  Returns

    `std::reinterpret_pointer_cast<T>(p)`

    template<class T, class U> std::unique_ptr<T>
      reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;

  Requires

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

  Returns

    `std::unique_ptr<T>(reinterpret_cast<typename std::unique_ptr<T>::element_type*>(p.release()))`.

### Example

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

    #include <boost/pointer_cast.hpp>
    #include <boost/shared_ptr.hpp>

    class base {
    public:
      virtual ~base() { }
    };

    class derived : public base { };

    template<class Ptr>
    void check_if_it_is_derived(const Ptr& ptr)
    {
      assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
    }

    int main()
    {
      base* ptr = new derived;
      boost::shared_ptr<base> sptr(new derived);

      check_if_it_is_derived(ptr);
      check_if_it_is_derived(sptr);

      delete ptr;
    }

## pointer_to_other

### Description

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.

There is test/example code in pointer_to_other_test.cpp.

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

`pointer_to_other` is defined in `<boost/smart_ptr/pointer_to_other.hpp>`.

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

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.

## atomic_shared_ptr

### Description

The class template `atomic_shared_ptr<T>` implements the interface of `std::atomic` for a contained value of type `shared_ptr<T>`. Concurrent access to `atomic_shared_ptr` is not a data race.

### Synopsis

`atomic_shared_ptr` is defined in `<boost/smart_ptr/atomic_shared_ptr.hpp>`.

    namespace boost {

      template<class T> class atomic_shared_ptr {
      private:

        shared_ptr<T> p_; // exposition only

        atomic_shared_ptr(const atomic_shared_ptr&) = delete;
        atomic_shared_ptr& operator=(const atomic_shared_ptr&) = delete;

      public:

        constexpr atomic_shared_ptr() noexcept;
        atomic_shared_ptr( shared_ptr<T> p ) noexcept;

        atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;

        bool is_lock_free() const noexcept;

        shared_ptr<T> load( int = 0 ) const noexcept;
        operator shared_ptr<T>() const noexcept;

        void store( shared_ptr<T> r, int = 0 ) noexcept;

        shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;

        bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
        bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
        bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
        bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;

        bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
        bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
        bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
        bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
      };
    }

### Members

    constexpr atomic_shared_ptr() noexcept;

- Effects

    Default-initializes `p_`.

    atomic_shared_ptr( shared_ptr<T> p ) noexcept;

- Effects

    Initializes `p_` to `p`.

    atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;

- Effects

    `p_.swap(r)`.

  Returns

    `*this`.

    bool is_lock_free() const noexcept;

- Returns

    `false`.

Note | This implementation is not lock-free.

    shared_ptr<T> load( int = 0 ) const noexcept;

    operator shared_ptr<T>() const noexcept;

- Returns

    `p_`.

Note | The `int` argument is intended to be of type `memory_order`, but is ignored. This implementation is lock-based and therefore always sequentially consistent.

    void store( shared_ptr<T> r, int = 0 ) noexcept;

- Effects

    `p_.swap(r)`.

    shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;

- Effects

    `p_.swap(r)`.

  Returns

    The old value of `p_`.

    bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;

    bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;

    bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;

    bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;

- Effects

    If `p_` is equivalent to `v`, assigns `w` to `p_`, otherwise assigns `p_` to `v`.

  Returns

    `true` if `p_` was equivalent to `v`, `false` otherwise.

  Remarks

    Two `shared_ptr` instances are equivalent if they store the same pointer value and share ownership.

    bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;

    bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;

    bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;

    bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;

- Effects

    If `p_` is equivalent to `v`, assigns `std::move(w)` to `p_`, otherwise assigns `p_` to `v`.

  Returns

    `true` if `p_` was equivalent to `v`, `false` otherwise.

  Remarks

    The old value of `w` is not preserved in either case.

## Appendix A: Smart Pointer Programming Techniques

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

### 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));

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

## Appendix B: History and Acknowledgments

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

### March 2003

Peter Dimov, Beman Dawes and Greg Colvin proposed `shared_ptr` and `weak_ptr` for inclusion in the Standard Library via the first Library Technical Report (known as TR1). The proposal was accepted and eventually went on to become a part of the C++ standard in its 2011 iteration.

### July 2007

Peter Dimov and Beman Dawes proposed a number of enhancements to `shared_ptr` as it was entering the working paper that eventually became the C++11 standard.

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

Peter Dimov aided this development by extending `shared_ptr` to support arrays via the syntax `shared_ptr<T[]>` and `shared_ptr<T[N]>`.

### April 2013

Peter Dimov proposed the extension of `shared_ptr` to support arrays for inclusion into the standard, and it was accepted.

### February 2014

Glen Fernandes updated `make_shared` and `allocate_shared` to conform to the specification in C++ standard paper N3870, 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.

### February 2017

Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more optimal and more maintainable implementation.

### June 2017

Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.

Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`.

## Appendix C: shared_array (deprecated)

Note | This facility is deprecated because a `shared_ptr` to `T[]` or `T[N]` is now available, and is superior in every regard.

### Description

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`, the use count of `A` 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. `shared_array` 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.

### 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(const shared_array& v) noexcept;

        ~shared_array() noexcept;

        shared_array& operator=(const shared_array& v) noexcept;

        void reset(T* p = 0);
        template<class D> void reset(T* p, D d);

        T& operator[](std::ptrdiff_t n) const noexcept;
        T* get() const noexcept;

        bool unique() const noexcept;
        long use_count() const noexcept;

        explicit operator bool() const noexcept;

        void swap(shared_array<T>& v) noexcept;
      };

      template<class T> bool
        operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;
      template<class T> bool
        operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;
      template<class T> bool
        operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;

      template<class T>
        void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
    }

### Members

#### element_type

    typedef T element_type;

Type

  Provides the type of the stored pointer.

#### Constructors

    explicit shared_array(T* p = 0);

  Effects

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

  Requires

    `T` is a complete type.

  Throws

    `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.

    template<class D> shared_array(T* p, D d);

  Effects

    Constructs a `shared_array`, storing a copy of `p` and of `d`. Afterwards, the use count is 1. When the the time comes to delete the array pointed to by `p`, the object `d` is used in the statement `d(p)`.

  Requires

    - `T` is a complete type.

    - The copy constructor and destructor of `D` must not throw.

    - Invoking the object `d` with parameter `p` must not throw.

  Throws

    `std::bad_alloc`. If an exception is thrown, `d(p)` is called.

    shared_array(const shared_array& v) noexcept;

  Effects

    Constructs a `shared_array`, as if by storing a copy of the pointer stored in `v`. Afterwards, the use count for all copies is 1 more than the initial use count.

  Requires

    `T` is a complete type.

#### Destructor

    ~shared_array() noexcept;

  Effects

    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.

#### Assignment

    shared_array& operator=(const shared_array& v) noexcept;

  Effects

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

  Requires

    `T` is a complete type.

  Returns

    `*this`.

#### reset

    void reset(T* p = 0);

  Effects

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

  Requires

    `T` is a complete type.

  Throws

    `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.

    template<class D> void reset(T* p, D d);

  Effects

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

  Requires

    - `T` is a complete type.

    - The copy constructor of `D` must not throw.

  Throws

    `std::bad_alloc`. If an exception is thrown, `d(p)` is called.

#### Indexing

    T& operator[](std::ptrdiff_t n) const noexcept;

Returns

  A reference to element `n` of the array pointed to by the stored pointer. Behavior is undefined and almost certainly undesirable if the stored pointer is 0, or if `n` is less than 0 or is greater than or equal to the number of elements in the array.

Requires

  `T` is a complete type.

#### get

    T* get() const noexcept;

  Returns

    The stored pointer.

#### unique

    bool unique() const noexcept;

  Returns

    `true` if no other `shared_array` is sharing ownership of the stored pointer, `false` otherwise.

#### use_count

    long use_count() const noexcept;

  Returns

    The number of `shared_array` objects sharing ownership of the stored pointer.

#### Conversions

    explicit operator bool() const noexcept;

  Returns

    `get() != 0`.

  Requires

    `T` is a complete type.

#### swap

    void swap(shared_array<T>& b) noexcept;

  Effects

    Exchanges the contents of the two smart pointers.

### Free Functions

#### Comparison

    template<class T> bool
      operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;

    template<class T> bool
      operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;

    template<class T> bool
      operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;

  Returns

    The result of comparing the stored pointers of the two smart pointers.

Note

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) noexcept;

  Returns

    `a.swap(b)`.

  Requires

    `T` is a complete type.

## Appendix D: 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 Boost Software License, Version 1.0.