# intrusive_ptr class template

Introduction
Synopsis
Members
Free Functions

## Introduction

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

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

The main reasons to use intrusive_ptr are:

- Some existing frameworks or OSes provide objects with embedded reference counts;
- The memory footprint of intrusive_ptr is the same as the corresponding raw pointer;
- intrusive_ptr<T> can be constructed from an arbitrary raw pointer of type T *.

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

## Synopsis

    namespace boost {

      template<class T> class intrusive_ptr {

        public:

          typedef T element_type;

          intrusive_ptr(); // never throws
          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);
          template<class Y> intrusive_ptr & operator=(T * r);

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

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

          void swap(intrusive_ptr & b); // never throws
      };

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

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

      template<class T>
        bool operator==(intrusive_ptr<T> const & a, T * b); // never throws

      template<class T>
        bool operator!=(intrusive_ptr<T> const & a, T * b); // never throws

      template<class T>
        bool operator==(T * a, intrusive_ptr<T> const & b); // never throws

      template<class T>
        bool operator!=(T * a, intrusive_ptr<T> const & b); // never throws

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

      template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws

      template<class T> T * get_pointer(intrusive_ptr<T> const & p); // never throws

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

      template<class T, class U>
        intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r); // never throws

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

    }

## Members

### element_type

    typedef T element_type;

> Provides the type of the template parameter T.

### constructors

    intrusive_ptr(); // never throws

> Postconditions: `get() == 0`.

> Throws: nothing.

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

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

> Postconditions: `get() == p`.

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

> Effects: `if(r.get() != 0) intrusive_ptr_add_ref(r.get());`.

> Postconditions: `get() == r.get()`.

### destructor

    ~intrusive_ptr();

> Effects: `if(get() != 0) intrusive_ptr_release(get());`.

### assignment

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

> Effects: Equivalent to `intrusive_ptr(r).swap(*this)`.

> Returns: `*this`.

### indirection

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

> Requirements: `get() != 0`.

> Returns: `*get()`.

> Throws: nothing.

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

> Requirements: `get() != 0`.

> Returns: `get()`.

> Throws: nothing.

### get

    T * get() const; // never throws

> Returns: the stored pointer.

> Throws: nothing.

### conversions

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

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

> Throws: nothing.

> Notes: This conversion operator allows intrusive_ptr objects to be used in boolean contexts, like `if (p && p->valid()) {}`. The actual target type is typically a pointer to a member function, avoiding many of the implicit conversion pitfalls.

### swap

    void swap(intrusive_ptr & b); // never throws

> Effects: Exchanges the contents of the two smart pointers.

> Throws: nothing.

## Free Functions

### comparison

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

> Returns: `a.get() == b.get()`.

> Throws: nothing.

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

> Returns: `a.get() != b.get()`.

> Throws: nothing.

    template<class T>
      bool operator==(intrusive_ptr<T> const & a, T * b); // never throws

> Returns: `a.get() == b`.

> Throws: nothing.

    template<class T>
      bool operator!=(intrusive_ptr<T> const & a, T * b); // never throws

> Returns: `a.get() != b`.

> Throws: nothing.

    template<class T>
      bool operator==(T * a, intrusive_ptr<T> const & b); // never throws

> Returns: `a == b.get()`.

> Throws: nothing.

    template<class T>
      bool operator!=(T * a, intrusive_ptr<T> const & b); // never throws

> Returns: `a != b.get()`.

> Throws: nothing.

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

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

> Throws: nothing.

> Notes: Allows intrusive_ptr objects to be used as keys in associative containers.

### swap

    template<class T>
      void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws

> Effects: Equivalent to `a.swap(b)`.

> Throws: nothing.

> Notes: Matches the interface of std::swap. Provided as an aid to generic programming.

### get_pointer

    template<class T>
      T * get_pointer(intrusive_ptr<T> const & p); // never throws

> Returns: `p.get()`.

> Throws: nothing.

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

### static_pointer_cast

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

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

> Throws: nothing.

### dynamic_pointer_cast

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

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

> Throws: nothing.

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

$Date: 2003/02/05 12:56:48 $

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