00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Refcounted_Auto_Ptr.h 00006 * 00007 * $Id: Refcounted_Auto_Ptr.h 79219 2007-08-06 08:57:18Z johnnyw $ 00008 * 00009 * @author John Tucker <JTucker@infoglide.com> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_REFCOUNTED_AUTO_PTR_H 00014 #define ACE_REFCOUNTED_AUTO_PTR_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/Auto_Ptr.h" 00019 #include "ace/Atomic_Op.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00026 00027 // Forward decl. 00028 template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr_Rep; 00029 template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr; 00030 00031 /** 00032 * @class ACE_Refcounted_Auto_Ptr 00033 * 00034 * @brief This class implements support for a reference counted auto_ptr. 00035 * Assigning or copying instances of an ACE_Refcounted_Auto_Ptr 00036 * will automatically increment the reference count. When the last 00037 * instance that references a ACE_Refcounted_Auto_Ptr instance is 00038 * destroyed or overwritten, it will invoke delete on its underlying 00039 * pointer. 00040 * 00041 * The ACE_Refcounted_Auto_Ptr works by maintaining a reference to a 00042 * separate representation object, ACE_Refcounted_Auto_Ptr_Rep. That 00043 * separate representation object contains the reference count and 00044 * the actual pointer value. 00045 */ 00046 template <class X, class ACE_LOCK> 00047 class ACE_Refcounted_Auto_Ptr 00048 { 00049 public: 00050 00051 // = Initialization and termination methods. 00052 00053 /// Constructor that initializes an ACE_Refcounted_Auto_Ptr to 00054 /// the specified pointer value. 00055 ACE_Refcounted_Auto_Ptr (X *p = 0); 00056 00057 /// Copy constructor binds the new ACE_Refcounted_Auto_Ptr to the 00058 /// representation object referenced by @a r. 00059 /// An ACE_Refcounted_Auto_Ptr_Rep is created if necessary. 00060 ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r); 00061 00062 /// Destructor. Releases the reference to the underlying representation. 00063 /// If the release of that reference causes its reference count to reach 0, 00064 /// the representation object will also be destroyed. 00065 virtual ~ACE_Refcounted_Auto_Ptr (void); 00066 00067 /// Assignment operator that binds the current object and @a r to the same 00068 /// ACE_Refcounted_Auto_Ptr_Rep. An ACE_Refcounted_Auto_Ptr_Rep 00069 /// is created if necessary. 00070 void operator = (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r); 00071 00072 /// Equality operator that returns @c true if both 00073 /// ACE_Refcounted_Auto_Ptr objects point to the same underlying 00074 /// representation. It does not compare the actual pointers. 00075 /** 00076 * @note It also returns @c true if both objects have just been 00077 * instantiated and not used yet. 00078 */ 00079 bool operator == (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r) const; 00080 00081 /// Inequality operator, which is the opposite of equality. 00082 bool operator != (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r) const; 00083 00084 /// Redirection operator 00085 X *operator-> (void) const; 00086 00087 /// Accessor method. 00088 X &operator *() const; 00089 00090 /// Releases the reference to the underlying representation object. 00091 /// @retval The pointer value prior to releasing it. 00092 X *release (void); 00093 00094 /// Releases the current pointer value and then sets a new 00095 /// pointer value specified by @a p. 00096 void reset (X *p = 0); 00097 00098 /// Get the pointer value. 00099 X *get (void) const; 00100 00101 /// Get the reference count value. 00102 long count (void) const; 00103 00104 /// Returns @c true if this object does not contain a valid pointer. 00105 bool null (void) const; 00106 00107 /// Declare the dynamic allocation hooks. 00108 ACE_ALLOC_HOOK_DECLARE; 00109 00110 protected: 00111 /// the ACE_Refcounted_Auto_Ptr_Rep 00112 typedef ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> AUTO_REFCOUNTED_PTR_REP; 00113 00114 /// Protect operations on the ACE_Refcounted_Auto_Ptr. 00115 AUTO_REFCOUNTED_PTR_REP *rep_; 00116 }; 00117 00118 /** 00119 * @class ACE_Refcounted_Auto_Ptr_Rep 00120 * 00121 * @brief An ACE_Refcounted_Auto_Ptr_Rep object encapsulates a pointer 00122 * to an object of type X. It uses a lock object of type ACE_LOCK to protect 00123 * access to the reference count. 00124 * 00125 * @internal ACE_Refcounted_Auto_Ptr_Rep is used internally by the 00126 * ACE_Refcounted_Auto_Ptr class and is only accessible through it. 00127 */ 00128 template <class X, class ACE_LOCK> 00129 class ACE_Refcounted_Auto_Ptr_Rep 00130 { 00131 private: 00132 friend class ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>; 00133 00134 /// Get the pointer value. 00135 X *get (void) const; 00136 00137 /// Get the reference count value. 00138 long count (void) const; 00139 00140 /// Declare the dynamic allocation hooks. 00141 ACE_ALLOC_HOOK_DECLARE; 00142 00143 // = Encapsulate reference count and object lifetime of instances. 00144 // These methods must go after the others to work around a bug with 00145 // Borland's C++ Builder... 00146 00147 /// Allocate a new ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> instance, 00148 /// returning NULL if it cannot be created. 00149 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *internal_create (X *p); 00150 00151 /// Create a ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> and initialize 00152 /// the reference count. 00153 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *create (X *p); 00154 00155 /// Increase the reference count on @a rep. 00156 /// 00157 /// @retval @a rep if success, 0 if there's an error obtaining the lock 00158 /// on @a rep. 00159 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *attach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); 00160 00161 /// Decreases the reference count and and deletes rep if there are no 00162 /// more references to rep. 00163 /// 00164 /// Precondition (rep != 0) 00165 static void detach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); 00166 00167 /// Pointer to the result. 00168 ACE_Auto_Basic_Ptr<X> ptr_; 00169 00170 /// Reference count. 00171 mutable ACE_Atomic_Op<ACE_LOCK, long> ref_count_; 00172 00173 private: 00174 // = Constructor and destructor private. 00175 ACE_Refcounted_Auto_Ptr_Rep (X *p = 0); 00176 ~ACE_Refcounted_Auto_Ptr_Rep (void); 00177 }; 00178 00179 ACE_END_VERSIONED_NAMESPACE_DECL 00180 00181 #include "ace/Refcounted_Auto_Ptr.inl" 00182 00183 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00184 #include "ace/Refcounted_Auto_Ptr.cpp" 00185 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00186 00187 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00188 #pragma implementation ("Refcounted_Auto_Ptr.cpp") 00189 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00190 00191 #include /**/ "ace/post.h" 00192 00193 #endif /* ACE_REFCOUNTED_AUTO_PTR_H */