00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Refcounted_Auto_Ptr.h 00006 * 00007 * $Id: Refcounted_Auto_Ptr.h 81179 2008-03-31 19:00:29Z iliyan $ 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 explicit 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 /// Check rep easily. 00091 bool operator !() const; 00092 00093 /// Check rep easily. 00094 operator bool () const; 00095 00096 /// Releases the reference to the underlying representation object. 00097 /// @retval The pointer value prior to releasing it. 00098 X *release (void); 00099 00100 /// Releases the current pointer value and then sets a new 00101 /// pointer value specified by @a p. 00102 void reset (X *p = 0); 00103 00104 /// Get the pointer value. 00105 X *get (void) const; 00106 00107 /// Get the reference count value. 00108 long count (void) const; 00109 00110 /// Returns @c true if this object does not contain a valid pointer. 00111 bool null (void) const; 00112 00113 /// Declare the dynamic allocation hooks. 00114 ACE_ALLOC_HOOK_DECLARE; 00115 00116 protected: 00117 /// the ACE_Refcounted_Auto_Ptr_Rep 00118 typedef ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> AUTO_REFCOUNTED_PTR_REP; 00119 00120 /// Protect operations on the ACE_Refcounted_Auto_Ptr. 00121 AUTO_REFCOUNTED_PTR_REP *rep_; 00122 }; 00123 00124 /** 00125 * @class ACE_Refcounted_Auto_Ptr_Rep 00126 * 00127 * @brief An ACE_Refcounted_Auto_Ptr_Rep object encapsulates a pointer 00128 * to an object of type X. It uses a lock object of type ACE_LOCK to protect 00129 * access to the reference count. 00130 * 00131 * @internal ACE_Refcounted_Auto_Ptr_Rep is used internally by the 00132 * ACE_Refcounted_Auto_Ptr class and is only accessible through it. 00133 */ 00134 template <class X, class ACE_LOCK> 00135 class ACE_Refcounted_Auto_Ptr_Rep 00136 { 00137 private: 00138 friend class ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>; 00139 00140 /// Get the pointer value. 00141 X *get (void) const; 00142 00143 /// Get the reference count value. 00144 long count (void) const; 00145 00146 /// Declare the dynamic allocation hooks. 00147 ACE_ALLOC_HOOK_DECLARE; 00148 00149 // = Encapsulate reference count and object lifetime of instances. 00150 // These methods must go after the others to work around a bug with 00151 // Borland's C++ Builder... 00152 00153 /// Allocate a new ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> instance, 00154 /// returning NULL if it cannot be created. 00155 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *internal_create (X *p); 00156 00157 /// Create a ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> and initialize 00158 /// the reference count. 00159 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *create (X *p); 00160 00161 /// Increase the reference count on @a rep. 00162 /// 00163 /// @retval @a rep if success, 0 if there's an error obtaining the lock 00164 /// on @a rep. 00165 static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *attach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); 00166 00167 /// Decreases the reference count and and deletes rep if there are no 00168 /// more references to rep. 00169 /// 00170 /// Precondition (rep != 0) 00171 static void detach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); 00172 00173 /// Pointer to the result. 00174 ACE_Auto_Basic_Ptr<X> ptr_; 00175 00176 /// Reference count. 00177 mutable ACE_Atomic_Op<ACE_LOCK, long> ref_count_; 00178 00179 private: 00180 // = Constructor and destructor private. 00181 ACE_Refcounted_Auto_Ptr_Rep (X *p = 0); 00182 ~ACE_Refcounted_Auto_Ptr_Rep (void); 00183 }; 00184 00185 ACE_END_VERSIONED_NAMESPACE_DECL 00186 00187 #include "ace/Refcounted_Auto_Ptr.inl" 00188 00189 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00190 #include "ace/Refcounted_Auto_Ptr.cpp" 00191 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00192 00193 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00194 #pragma implementation ("Refcounted_Auto_Ptr.cpp") 00195 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00196 00197 #include /**/ "ace/post.h" 00198 00199 #endif /* ACE_REFCOUNTED_AUTO_PTR_H */