boost.png (6897 bytes)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 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:

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);
      intrusive_ptr & operator=(T * r);

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

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

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

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

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

detach

T * detach(); // never throws

Returns: the stored pointer.

Throws: nothing.

Postconditions: get() == 0.

Notes: 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

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, class U>
  bool operator==(intrusive_ptr<T> const & a, U * b); // never throws

Returns: a.get() == b.

Throws: nothing.

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

Returns: a.get() != b.

Throws: nothing.

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

Returns: a == b.get().

Throws: nothing.

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

Returns: a != b.get().

Throws: nothing.

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

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

Throws: nothing.

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

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.

const_pointer_cast

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

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

Throws: nothing.

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$

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