// -*- C++ -*- //============================================================================= /** * @file Refcounted_Auto_Ptr.h * * @author John Tucker */ //============================================================================= #ifndef ACE_REFCOUNTED_AUTO_PTR_H #define ACE_REFCOUNTED_AUTO_PTR_H #include /**/ "ace/pre.h" #include "ace/Auto_Ptr.h" #include "ace/Atomic_Op.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Forward decl. template class ACE_Refcounted_Auto_Ptr_Rep; template class ACE_Refcounted_Auto_Ptr; /** * @class ACE_Refcounted_Auto_Ptr * * @brief This class implements support for a reference counted auto_ptr. * Assigning or copying instances of an ACE_Refcounted_Auto_Ptr * will automatically increment the reference count. When the last * instance that references a ACE_Refcounted_Auto_Ptr instance is * destroyed or overwritten, it will invoke delete on its underlying * pointer. * * The ACE_Refcounted_Auto_Ptr works by maintaining a reference to a * separate representation object, ACE_Refcounted_Auto_Ptr_Rep. That * separate representation object contains the reference count and * the actual pointer value. */ template class ACE_Refcounted_Auto_Ptr { public: /// Constructor that initializes an ACE_Refcounted_Auto_Ptr to /// the specified pointer value. explicit ACE_Refcounted_Auto_Ptr (X *p = 0); /// Copy constructor binds the new ACE_Refcounted_Auto_Ptr to the /// representation object referenced by @a r. /// An ACE_Refcounted_Auto_Ptr_Rep is created if necessary. ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr &r); /// Destructor. Releases the reference to the underlying representation. /// If the release of that reference causes its reference count to reach 0, /// the representation object will also be destroyed. virtual ~ACE_Refcounted_Auto_Ptr (void); /// Assignment operator that binds the current object and @a r to the same /// ACE_Refcounted_Auto_Ptr_Rep. An ACE_Refcounted_Auto_Ptr_Rep /// is created if necessary. void operator = (const ACE_Refcounted_Auto_Ptr &r); /// Equality operator that returns @c true if both /// ACE_Refcounted_Auto_Ptr objects point to the same underlying /// representation. It does not compare the actual pointers. /** * @note It also returns @c true if both objects have just been * instantiated and not used yet. */ bool operator == (const ACE_Refcounted_Auto_Ptr &r) const; /// Inequality operator, which is the opposite of equality. bool operator != (const ACE_Refcounted_Auto_Ptr &r) const; /// Redirection operator X *operator-> (void) const; /// Accessor method. X &operator *() const; /// Check rep easily. bool operator !() const; /// Check rep easily. operator bool () const; /// Releases the reference to the underlying representation object. /// @retval The pointer value prior to releasing it. X *release (void); /// Releases the current pointer value and then sets a new /// pointer value specified by @a p. void reset (X *p = 0); /// Get the pointer value. X *get (void) const; /// Get the reference count value. long count (void) const; /// Returns @c true if this object does not contain a valid pointer. bool null (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; protected: /// the ACE_Refcounted_Auto_Ptr_Rep typedef ACE_Refcounted_Auto_Ptr_Rep AUTO_REFCOUNTED_PTR_REP; /// Protect operations on the ACE_Refcounted_Auto_Ptr. AUTO_REFCOUNTED_PTR_REP *rep_; }; /** * @class ACE_Refcounted_Auto_Ptr_Rep * * @brief An ACE_Refcounted_Auto_Ptr_Rep object encapsulates a pointer * to an object of type X. It uses a lock object of type ACE_LOCK to protect * access to the reference count. * * @internal ACE_Refcounted_Auto_Ptr_Rep is used internally by the * ACE_Refcounted_Auto_Ptr class and is only accessible through it. */ template class ACE_Refcounted_Auto_Ptr_Rep { private: friend class ACE_Refcounted_Auto_Ptr; /// Get the pointer value. X *get (void) const; /// Get the reference count value. long count (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; // = Encapsulate reference count and object lifetime of instances. // These methods must go after the others to work around a bug with // Borland's C++ Builder... /// Allocate a new ACE_Refcounted_Auto_Ptr_Rep instance, /// returning NULL if it cannot be created. static ACE_Refcounted_Auto_Ptr_Rep *internal_create (X *p); /// Create a ACE_Refcounted_Auto_Ptr_Rep and initialize /// the reference count. static ACE_Refcounted_Auto_Ptr_Rep *create (X *p); /// Increase the reference count on @a rep. /// /// @retval @a rep if success, 0 if there's an error obtaining the lock /// on @a rep. static ACE_Refcounted_Auto_Ptr_Rep *attach (ACE_Refcounted_Auto_Ptr_Rep *&rep); /// Decreases the reference count and and deletes rep if there are no /// more references to rep. /// /// Precondition (rep != 0) static void detach (ACE_Refcounted_Auto_Ptr_Rep *&rep); /// Pointer to the result. ACE_Auto_Basic_Ptr ptr_; /// Reference count. mutable ACE_Atomic_Op ref_count_; private: // = Constructor and destructor private. ACE_Refcounted_Auto_Ptr_Rep (X *p = 0); ~ACE_Refcounted_Auto_Ptr_Rep (void); }; ACE_END_VERSIONED_NAMESPACE_DECL #include "ace/Refcounted_Auto_Ptr.inl" #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) #include "ace/Refcounted_Auto_Ptr.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) #pragma implementation ("Refcounted_Auto_Ptr.cpp") #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #include /**/ "ace/post.h" #endif /* ACE_REFCOUNTED_AUTO_PTR_H */