diff options
Diffstat (limited to 'ace/Memory/Bound_Ptr.h')
-rw-r--r-- | ace/Memory/Bound_Ptr.h | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/ace/Memory/Bound_Ptr.h b/ace/Memory/Bound_Ptr.h new file mode 100644 index 00000000000..094bdb6b8d2 --- /dev/null +++ b/ace/Memory/Bound_Ptr.h @@ -0,0 +1,300 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Bound_Ptr.h + * + * $Id$ + * + * @author Christopher Kohlhoff <chris@kohlhoff.com> + */ +//============================================================================= + +#ifndef ACE_BOUND_PTR_H +#define ACE_BOUND_PTR_H +#include "ace/pre.h" + +#include "ace/OS.h" +#include "ace/Auto_Ptr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Bound_Ptr_Counter + * + * @brief An ACE_Bound_Ptr_Counter<ACE_LOCK> object encapsulates an object + * reference count. Do not use this class directly, use ACE_Strong_Bound_Ptr + * or ACE_Weak_Bound_Ptr instead. + */ +template <class ACE_LOCK> +class ACE_Bound_Ptr_Counter +{ +public: + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + ACE_Bound_Ptr_Counter (int init_obj_ref_count = 0); + ~ACE_Bound_Ptr_Counter (void); + + /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the reference + /// count to indicate ownership by a strong pointer. + static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_strong (void); + + /// Increase both the object and counter reference counts and return the new + /// object reference count. A return value of -1 indicates that the object + /// has already been destroyed. + static int attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); + + /// Decreases both the object and counter reference counts and deletes + /// whichever has no more references. Returns the new object reference count. + static int detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); + + /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the reference + /// count to indicate no ownership. + static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_weak (void); + + /// Increase the counter reference count and return argument. + static void attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); + + /// Decreases the counter reference count and deletes the counter if it has + /// no more references. + static void detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); + + /// Determine whether the object has been deleted. + static int object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); + +private: + /// Allocate a new ACE_Bound_Ptr_Counter<ACE_LOCK> instance, returning NULL + /// if it cannot be created. + static ACE_Bound_Ptr_Counter<ACE_LOCK> *internal_create (int init_obj_ref_count); + + /// Reference count of underlying object. Is set to -1 once the object has + /// been destroyed to indicate to all weak pointers that it is no longer valid. + int obj_ref_count_; + + /// Reference count of this counter. + int self_ref_count_; + + /// Mutex variable to synchronize access to the reference counts. + ACE_LOCK lock_; +}; + +// Forward decl. +template <class X, class ACE_LOCK> class ACE_Weak_Bound_Ptr; + +/** + * @class ACE_Strong_Bound_Ptr + * + * @brief This class implements support for a reference counted pointer. + * Assigning or copying instances of an ACE_Strong_Bound_Ptr will + * automatically increment the reference count of the underlying object. + * When the last instance of an ACE_Strong_Bound_Ptr that references a + * particular object is destroyed or overwritten, it will invoke delete + * on its underlying pointer. + */ +template <class X, class ACE_LOCK> +class ACE_Strong_Bound_Ptr +{ +public: + /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the + /// object <p> immediately. + ACE_EXPLICIT ACE_Strong_Bound_Ptr (X *p = 0); + + /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing + /// ownership of an object from an auto_ptr. + ACE_EXPLICIT ACE_Strong_Bound_Ptr (auto_ptr<X> p); + + /// Copy constructor binds <this> and <r> to the same object. + ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); + + /// Constructor binds <this> and <r> to the same object. + ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); + + /// Destructor. + ~ACE_Strong_Bound_Ptr (void); + + /// Assignment operator that binds <this> and <r> to the same object. + void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); + + /// Assignment operator that binds <this> and <r> to the same object. + void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); + + /// Equality operator that returns 1 if both ACE_Strong_Bound_Ptr instances + /// point to the same underlying object. Attention: It also returns 1 if + /// both objects have just been instantiated and not used yet. + int operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Equality operator that returns 1 if the ACE_Strong_Bound_Ptr and + /// ACE_Weak_Bound_Ptr objects point to the same underlying object. + /// Attention: It also returns 1 if both objects have just been + /// instantiated and not used yet. + int operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Equality operator that returns 1 if the ACE_Strong_Bound_Ptr and the raw + /// pointer point to the same underlying object. + int operator == (X *p) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (X *p) const; + + /// Redirection operator + X *operator-> (void) const; + + /// Dereference operator + X &operator * (void) const; + + /// Get the pointer value. + X *get (void); + + /// Resets the ACE_Strong_Bound_Ptr to refer to a different underlying + /// object. + void reset (X *p = 0); + + /// Resets the ACE_Strong_Bound_Ptr to refer to a different underlying + /// object, ownership of which is stolen from the auto_ptr. + void reset (auto_ptr<X> p); + + /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr objects. + int null (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + friend class ACE_Weak_Bound_Ptr<X, ACE_LOCK>; + + /// The ACE_Bound_Ptr_Counter type. + typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER; + + /// The reference counter. + COUNTER *counter_; + + /// The underlying object. + X *ptr_; +}; + +/** + * @class ACE_Weak_Bound_Ptr + * + * @brief This class implements support for a weak pointer that complements + * ACE_Strong_Bound_Ptr. Unlike ACE_Strong_Bound_Ptr, assigning or copying + * instances of an ACE_Weak_Bound_Ptr will not automatically increment the + * reference count of the underlying object. What ACE_Weak_Bound_Ptr does is + * preserve the knowledge that the object is in fact reference counted, and + * thus provides an alternative to raw pointers where non-ownership + * associations must be maintained. When the last instance of an + * ACE_Strong_Bound_Ptr that references a particular object is destroyed or + * overwritten, the corresponding ACE_Weak_Bound_Ptr instances are set to + * null. + */ +template <class X, class ACE_LOCK> +class ACE_Weak_Bound_Ptr +{ +public: + /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to the + /// object <p> immediately. + ACE_EXPLICIT ACE_Weak_Bound_Ptr (X *p = 0); + + /// Copy constructor binds <this> and <r> to the same object. + ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); + + /// Constructor binds <this> and <r> to the same object. + ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); + + /// Destructor. + ~ACE_Weak_Bound_Ptr (void); + + /// Assignment operator that binds <this> and <r> to the same object. + void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); + + /// Assignment operator that binds <this> and <r> to the same object. + void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); + + /// Equality operator that returns 1 if both ACE_Weak_Bound_Ptr objects + /// point to the same underlying object. Attention: It also returns 1 if + /// both objects have just been instantiated and not used yet. + int operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Equality operator that returns 1 if the ACE_Weak_Bound_Ptr and + /// ACE_Strong_Bound_Ptr objects point to the same underlying object. + /// Attention: It also returns 1 if both objects have just been instantiated + /// and not used yet. + int operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Equality operator that returns 1 if the ACE_Weak_Bound_Ptr and the raw + /// pointer point to the same underlying object. + int operator == (X *p) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; + + /// Inequality operator, which is the opposite of equality. + int operator != (X *p) const; + + /// Redirection operator. It returns a temporary strong pointer and makes + /// use of the chaining properties of operator-> to ensure that the + /// underlying object does not disappear while you are using it. If + /// you are certain of the lifetimes of the object, and do not want to incur + /// the locking overhead, then use the unsafe_get method instead. + ACE_Strong_Bound_Ptr<X, ACE_LOCK> operator-> (void) const; + + /// Obtain a strong pointer corresponding to this weak pointer. This function + /// is useful to create a temporary strong pointer for conversion to a + /// reference. + ACE_Strong_Bound_Ptr<X, ACE_LOCK> strong (void) const; + + /// Get the pointer value. Warning: this does not affect the reference count + /// of the underlying object, so it may disappear on you while you are using + /// it if you are not careful. + X *unsafe_get (void) const; + + /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying object. + void reset (X *p = 0); + + /// Increment the reference count on the underlying object. Returns the new + /// reference count on the object. This function may be used to integrate the + /// bound pointers into an external reference counting mechanism such as + /// those used by COM or CORBA servants. + int add_ref (void); + + /// Decrement the reference count on the underlying object, which is deleted + /// if the count has reached zero. Returns the new reference count on the + /// object. This function may be used to integrate the bound pointers into an + /// external reference counting mechanism such as those used by COM or CORBA + /// servants. + int remove_ref (void); + + /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects. + int null (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + friend class ACE_Strong_Bound_Ptr<X, ACE_LOCK>; + + /// The ACE_Bound_Ptr_Counter type. + typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER; + + /// The reference counter. + COUNTER *counter_; + + /// The underlying object. + X *ptr_; +}; + +#include "ace/Bound_Ptr.i" + +#include "ace/post.h" +#endif /* ACE_BOUND_PTR_H */ |