summaryrefslogtreecommitdiff
path: root/ace/Memory/Bound_Ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Memory/Bound_Ptr.h')
-rw-r--r--ace/Memory/Bound_Ptr.h300
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 */