From bd39e2ededbe9b0d90e451ca07451d20a9623612 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 21 Jan 2003 17:21:24 +0000 Subject: [PATCH] intrusive_ptr.html added. [SVN r16981] --- include/boost/intrusive_ptr.hpp | 108 ++++++++----- intrusive_ptr.html | 276 ++++++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+), 41 deletions(-) create mode 100644 intrusive_ptr.html diff --git a/include/boost/intrusive_ptr.hpp b/include/boost/intrusive_ptr.hpp index 5d03548..074720f 100644 --- a/include/boost/intrusive_ptr.hpp +++ b/include/boost/intrusive_ptr.hpp @@ -19,7 +19,12 @@ # pragma warning(disable:4284) // odd return type for operator-> #endif -#include // std::less +#include +#include + +#include // for std::less +#include // for std::basic_ostream + namespace boost { @@ -53,14 +58,9 @@ public: { } - intrusive_ptr(T * p): p_(p) + intrusive_ptr(T * p, bool add_ref = true): p_(p) { - if(p_ != 0) intrusive_ptr_add_ref(p_); - } - - ~intrusive_ptr() - { - if(p_ != 0) intrusive_ptr_release(p_); + if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_); } #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) @@ -77,6 +77,11 @@ public: if(p_ != 0) intrusive_ptr_add_ref(p_); } + ~intrusive_ptr() + { + if(p_ != 0) intrusive_ptr_release(p_); + } + #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) template intrusive_ptr & operator=(intrusive_ptr const & rhs) @@ -99,13 +104,6 @@ public: return *this; } - void swap(intrusive_ptr & rhs) - { - T * tmp = p_; - p_ = rhs.p_; - rhs.p_ = tmp; - } - T * get() const { return p_; @@ -121,16 +119,18 @@ public: return p_; } - bool empty() const + typedef T * (intrusive_ptr::*unspecified_bool_type) () const; + + operator unspecified_bool_type () const { - return p_ == 0; + return p_ == 0? 0: &intrusive_ptr::get; } - typedef bool (intrusive_ptr::*bool_type) () const; - - operator bool_type () const + void swap(intrusive_ptr & rhs) { - return p_ == 0? 0: &intrusive_ptr::empty; + T * tmp = p_; + p_ = rhs.p_; + rhs.p_ = tmp; } private: @@ -138,21 +138,6 @@ private: T * p_; }; -template void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) -{ - lhs.swap(rhs); -} - -template intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) -{ - return dynamic_cast(p.get()); -} - -template intrusive_ptr static_pointer_cast(intrusive_ptr const & p) -{ - return static_cast(p.get()); -} - template inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) { return a.get() == b.get(); @@ -163,11 +148,6 @@ template inline bool operator!=(intrusive_ptr const & a, in return a.get() != b.get(); } -template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) -{ - return std::less(a.get(), b.get()); -} - template inline bool operator==(intrusive_ptr const & a, T * b) { return a.get() == b; @@ -188,6 +168,16 @@ template inline bool operator!=(T * a, intrusive_ptr const & b) return a != b.get(); } +template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) +{ + lhs.swap(rhs); +} + // mem_fn support template T * get_pointer(intrusive_ptr const & p) @@ -195,6 +185,42 @@ template T * get_pointer(intrusive_ptr const & p) return p.get(); } +template intrusive_ptr static_pointer_cast(intrusive_ptr const & p) +{ + return static_cast(p.get()); +} + +template intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) +{ + return dynamic_cast(p.get()); +} + +// operator<< + +#if defined(__GNUC__) && (__GNUC__ < 3) + +template std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) +# else +template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) +# endif +{ + os << p.get(); + return os; +} + +#endif + } // namespace boost #ifdef BOOST_MSVC diff --git a/intrusive_ptr.html b/intrusive_ptr.html new file mode 100644 index 0000000..fca484d --- /dev/null +++ b/intrusive_ptr.html @@ -0,0 +1,276 @@ + + + + intrusive_ptr + + + +

c++boost.gif (8819 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:

+
    +
  • + 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$

+

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

+ +