Bound_Ptr.h

Go to the documentation of this file.
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 */

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7