00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Bound_Ptr.h 00006 * 00007 * $Id: Bound_Ptr.h 80826 2008-03-04 14:51:23Z wotte $ 00008 * 00009 * @author Christopher Kohlhoff <chris@kohlhoff.com> 00010 * @author Boris Kolpackov <boris@codesynthesis.com> 00011 */ 00012 //============================================================================= 00013 00014 #ifndef ACE_BOUND_PTR_H 00015 #define ACE_BOUND_PTR_H 00016 00017 #include /**/ "ace/pre.h" 00018 00019 #include /**/ "ace/config-all.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Auto_Ptr.h" 00026 00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 /** 00030 * @class ACE_Bound_Ptr_Counter 00031 * 00032 * @brief An ACE_Bound_Ptr_Counter<ACE_LOCK> object encapsulates an 00033 * object reference count. 00034 * 00035 * Do not use this class directly, use ACE_Strong_Bound_Ptr or 00036 * ACE_Weak_Bound_Ptr instead. 00037 */ 00038 template <class ACE_LOCK> 00039 class ACE_Bound_Ptr_Counter 00040 { 00041 public: 00042 /// Declare the dynamic allocation hooks. 00043 ACE_ALLOC_HOOK_DECLARE; 00044 00045 ACE_Bound_Ptr_Counter (long init_obj_ref_count = 0); 00046 ~ACE_Bound_Ptr_Counter (void); 00047 00048 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the 00049 /// reference count to indicate ownership by a strong pointer. 00050 static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_strong (void); 00051 00052 /// Increase both the object and counter reference counts and return 00053 /// the new object reference count. A return value of -1 indicates 00054 /// that the object has already been destroyed. 00055 static long attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); 00056 00057 /// Decreases both the object and counter reference counts and 00058 /// deletes whichever has no more references. Returns the new object 00059 /// reference count. 00060 static long detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); 00061 00062 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the 00063 /// reference count to indicate no ownership. 00064 static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_weak (void); 00065 00066 /// Increase the counter reference count and return argument. 00067 static void attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); 00068 00069 /// Decreases the counter reference count and deletes the counter if 00070 /// it has no more references. 00071 static void detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); 00072 00073 /// Determine whether the object has been deleted. 00074 static bool object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter); 00075 00076 private: 00077 00078 /// Allocate a new ACE_Bound_Ptr_Counter<ACE_LOCK> instance, 00079 /// returning NULL if it cannot be created. 00080 static ACE_Bound_Ptr_Counter<ACE_LOCK> *internal_create (long init_obj_ref_count); 00081 00082 private: 00083 00084 /// Reference count of underlying object. Is set to -1 once the 00085 /// object has been destroyed to indicate to all weak pointers that 00086 /// it is no longer valid. 00087 long obj_ref_count_; 00088 00089 /// Reference count of this counter. 00090 long self_ref_count_; 00091 00092 /// Mutex variable to synchronize access to the reference counts. 00093 ACE_LOCK lock_; 00094 }; 00095 00096 // Forward decl. 00097 template <class X, class ACE_LOCK> class ACE_Weak_Bound_Ptr; 00098 00099 /** 00100 * @class ACE_Strong_Bound_Ptr 00101 * 00102 * @brief This class implements support for a reference counted 00103 * pointer. 00104 * 00105 * Assigning or copying instances of an ACE_Strong_Bound_Ptr will 00106 * automatically increment the reference count of the underlying object. 00107 * When the last instance of an ACE_Strong_Bound_Ptr that references a 00108 * particular object is destroyed or overwritten, it will invoke delete 00109 * on its underlying pointer. 00110 */ 00111 template <class X, class ACE_LOCK> 00112 class ACE_Strong_Bound_Ptr 00113 { 00114 public: 00115 /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the 00116 /// object <p> immediately. 00117 explicit ACE_Strong_Bound_Ptr (X *p = 0); 00118 00119 /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing 00120 /// ownership of an object from an auto_ptr. 00121 explicit ACE_Strong_Bound_Ptr (auto_ptr<X> p); 00122 00123 /// Copy constructor binds @c this and @a r to the same object. 00124 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); 00125 00126 /// Constructor binds @c this and @a r to the same object. 00127 ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); 00128 00129 /// Copy constructor binds @c this and @a r to the same object if 00130 /// Y* can be implicitly converted to X*. 00131 template <class Y> 00132 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<Y, ACE_LOCK> &r) 00133 : counter_ (r.counter_), 00134 ptr_ (dynamic_cast<X_t*>(r.ptr_)) 00135 { 00136 // This ctor is temporarily defined here to increase our chances 00137 // of being accepted by broken compilers. 00138 // 00139 COUNTER::attach_strong (this->counter_); 00140 } 00141 00142 /// Destructor. 00143 ~ACE_Strong_Bound_Ptr (void); 00144 00145 /// Assignment operator that binds @c this and @a r to the same object. 00146 void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); 00147 00148 /// Assignment operator that binds @c this and @a r to the same object. 00149 void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); 00150 00151 /// Assignment operator that binds @c this and @a r to the same object 00152 /// if Y* can be implicitly converted to X*. 00153 template <class Y> 00154 ACE_Weak_Bound_Ptr<X, ACE_LOCK>& 00155 operator= (const ACE_Strong_Bound_Ptr<Y, ACE_LOCK> &r) 00156 { 00157 // This operator is temporarily defined here to increase our chances 00158 // of being accepted by broken compilers. 00159 // 00160 00161 // This will work if &r == this, by first increasing the ref count 00162 00163 COUNTER *new_counter = r.counter_; 00164 X* new_ptr = dynamic_cast<X_t*> (r.ptr_); 00165 COUNTER::attach_strong (new_counter); 00166 if (COUNTER::detach_strong (this->counter_) == 0) 00167 delete this->ptr_; 00168 this->counter_ = new_counter; 00169 this->ptr_ = new_ptr; 00170 00171 return *this; 00172 } 00173 00174 /// Equality operator that returns @c true if both 00175 /// ACE_Strong_Bound_Ptr instances point to the same underlying 00176 /// object. 00177 /** 00178 * @note It also returns @c true if both objects have just been 00179 * instantiated and not used yet. 00180 */ 00181 bool operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; 00182 00183 /// Equality operator that returns true if the ACE_Strong_Bound_Ptr 00184 /// and ACE_Weak_Bound_Ptr objects point to the same underlying 00185 /// object. 00186 /** 00187 * @note It also returns @c true if both objects have just been 00188 * instantiated and not used yet. 00189 */ 00190 bool operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; 00191 00192 /// Equality operator that returns @c true if the 00193 /// ACE_Strong_Bound_Ptr and the raw pointer point to the same 00194 /// underlying object. 00195 bool operator == (X *p) const; 00196 00197 /// Inequality operator, which is the opposite of equality. 00198 bool operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; 00199 00200 /// Inequality operator, which is the opposite of equality. 00201 bool operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; 00202 00203 /// Inequality operator, which is the opposite of equality. 00204 bool operator != (X *p) const; 00205 00206 /// Redirection operator 00207 X *operator-> (void) const; 00208 00209 /// Dereference operator 00210 X &operator * (void) const; 00211 00212 /// Get the pointer value. 00213 X *get (void) const; 00214 00215 /// Resets the ACE_Strong_Bound_Ptr to refer to a different 00216 /// underlying object. 00217 void reset (X *p = 0); 00218 00219 /// Resets the ACE_Strong_Bound_Ptr to refer to a different 00220 /// underlying object, ownership of which is stolen from the 00221 /// auto_ptr. 00222 void reset (auto_ptr<X> p); 00223 00224 /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr 00225 /// objects. 00226 int null (void) const; 00227 00228 /// Declare the dynamic allocation hooks. 00229 ACE_ALLOC_HOOK_DECLARE; 00230 00231 private: 00232 typedef X X_t; // This indirection is for Borland C++. 00233 00234 friend class ACE_Weak_Bound_Ptr<X, ACE_LOCK>; 00235 00236 template <class Y, class L> 00237 friend class ACE_Strong_Bound_Ptr; 00238 00239 /// The ACE_Bound_Ptr_Counter type. 00240 typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER; 00241 00242 /// The reference counter. 00243 COUNTER *counter_; 00244 00245 /// The underlying object. 00246 X *ptr_; 00247 }; 00248 00249 /** 00250 * @class ACE_Weak_Bound_Ptr 00251 * 00252 * @brief This class implements support for a weak pointer that complements 00253 * ACE_Strong_Bound_Ptr. 00254 * 00255 * Unlike ACE_Strong_Bound_Ptr, assigning or copying instances of an 00256 * ACE_Weak_Bound_Ptr will not automatically increment the reference 00257 * count of the underlying object. What ACE_Weak_Bound_Ptr does is 00258 * preserve the knowledge that the object is in fact reference 00259 * counted, and thus provides an alternative to raw pointers where 00260 * non-ownership associations must be maintained. When the last 00261 * instance of an ACE_Strong_Bound_Ptr that references a particular 00262 * object is destroyed or overwritten, the corresponding 00263 * ACE_Weak_Bound_Ptr instances are set to NULL. 00264 */ 00265 template <class X, class ACE_LOCK> 00266 class ACE_Weak_Bound_Ptr 00267 { 00268 public: 00269 /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to 00270 /// the object <p> immediately. 00271 explicit ACE_Weak_Bound_Ptr (X *p = 0); 00272 00273 /// Copy constructor binds @c this and @a r to the same object. 00274 ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); 00275 00276 /// Constructor binds @c this and @a r to the same object. 00277 ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); 00278 00279 /// Destructor. 00280 ~ACE_Weak_Bound_Ptr (void); 00281 00282 /// Assignment operator that binds @c this and @a r to the same object. 00283 void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r); 00284 00285 /// Assignment operator that binds @c this and @a r to the same object. 00286 void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r); 00287 00288 /// Equality operator that returns @c true if both 00289 /// ACE_Weak_Bound_Ptr objects point to the same underlying object. 00290 /** 00291 * @note It also returns @c true if both objects have just been 00292 * instantiated and not used yet. 00293 */ 00294 bool operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; 00295 00296 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr 00297 /// and ACE_Strong_Bound_Ptr objects point to the same underlying 00298 /// object. 00299 /** 00300 * @note It also returns @c true if both objects have just been 00301 * instantiated and not used yet. 00302 */ 00303 bool operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; 00304 00305 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr 00306 /// and the raw pointer point to the same underlying object. 00307 bool operator == (X *p) const; 00308 00309 /// Inequality operator, which is the opposite of equality. 00310 bool operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const; 00311 00312 /// Inequality operator, which is the opposite of equality. 00313 bool operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const; 00314 00315 /// Inequality operator, which is the opposite of equality. 00316 bool operator != (X *p) const; 00317 00318 /// Redirection operator. 00319 /** 00320 * It returns a temporary strong pointer and makes use of the 00321 * chaining properties of operator-> to ensure that the underlying 00322 * object does not disappear while you are using it. If you are 00323 * certain of the lifetimes of the object, and do not want to incur 00324 * the locking overhead, then use the unsafe_get method instead. 00325 */ 00326 ACE_Strong_Bound_Ptr<X, ACE_LOCK> operator-> (void) const; 00327 00328 /// Obtain a strong pointer corresponding to this weak pointer. This 00329 /// function is useful to create a temporary strong pointer for 00330 /// conversion to a reference. 00331 ACE_Strong_Bound_Ptr<X, ACE_LOCK> strong (void) const; 00332 00333 /// Get the pointer value. Warning: this does not affect the 00334 /// reference count of the underlying object, so it may disappear on 00335 /// you while you are using it if you are not careful. 00336 X *unsafe_get (void) const; 00337 00338 /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying 00339 /// object. 00340 void reset (X *p = 0); 00341 00342 /// Increment the reference count on the underlying object. 00343 /** 00344 * Returns the new reference count on the object. This function may 00345 * be used to integrate the bound pointers into an external 00346 * reference counting mechanism such as those used by COM or CORBA 00347 * servants. 00348 */ 00349 long add_ref (void); 00350 00351 /// Decrement the reference count on the underlying object, which is deleted 00352 /// if the count has reached zero. 00353 /** 00354 * Returns the new reference count on the object. This function may 00355 * be used to integrate the bound pointers into an external 00356 * reference counting mechanism such as those used by COM or CORBA 00357 * servants. 00358 */ 00359 long remove_ref (void); 00360 00361 /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects. 00362 int null (void) const; 00363 00364 /// Declare the dynamic allocation hooks. 00365 ACE_ALLOC_HOOK_DECLARE; 00366 00367 private: 00368 typedef X X_t; // This indirection is for Borland C++. 00369 00370 friend class ACE_Strong_Bound_Ptr<X, ACE_LOCK>; 00371 00372 /// The ACE_Bound_Ptr_Counter type. 00373 typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER; 00374 00375 /// The reference counter. 00376 COUNTER *counter_; 00377 00378 /// The underlying object. 00379 X *ptr_; 00380 }; 00381 00382 ACE_END_VERSIONED_NAMESPACE_DECL 00383 00384 #include "ace/Bound_Ptr.inl" 00385 00386 #include /**/ "ace/post.h" 00387 00388 #endif /* ACE_BOUND_PTR_H */