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

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: 2004/10/05 15:45:50 $

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.