3 //=============================================================================
7 * @author Christopher Kohlhoff <chris@kohlhoff.com>
8 * @author Boris Kolpackov <boris@codesynthesis.com>
10 //=============================================================================
12 #ifndef ACE_BOUND_PTR_H
13 #define ACE_BOUND_PTR_H
15 #include /**/ "ace/pre.h"
17 #include /**/ "ace/config-all.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
26 * @class ACE_Bound_Ptr_Counter
28 * @brief An ACE_Bound_Ptr_Counter<ACE_LOCK> object encapsulates an
29 * object reference count.
31 * Do not use this class directly, use ACE_Strong_Bound_Ptr or
32 * ACE_Weak_Bound_Ptr instead.
34 template <class ACE_LOCK
>
35 class ACE_Bound_Ptr_Counter
38 /// Declare the dynamic allocation hooks.
39 ACE_ALLOC_HOOK_DECLARE
;
41 ACE_Bound_Ptr_Counter (long init_obj_ref_count
= 0);
42 ~ACE_Bound_Ptr_Counter () = default;
44 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
45 /// reference count to indicate ownership by a strong pointer.
46 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *create_strong ();
48 /// Increase both the object and counter reference counts and return
49 /// the new object reference count. A return value of -1 indicates
50 /// that the object has already been destroyed.
51 static long attach_strong (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
53 /// Decreases both the object and counter reference counts and
54 /// deletes whichever has no more references. Returns the new object
56 static long detach_strong (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
58 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
59 /// reference count to indicate no ownership.
60 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *create_weak ();
62 /// Increase the counter reference count and return argument.
63 static void attach_weak (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
65 /// Decreases the counter reference count and deletes the counter if
66 /// it has no more references.
67 static void detach_weak (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
69 /// Determine whether the object has been deleted.
70 static bool object_was_deleted (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
73 /// Allocate a new ACE_Bound_Ptr_Counter<ACE_LOCK> instance,
74 /// returning NULL if it cannot be created.
75 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *internal_create (long init_obj_ref_count
);
78 /// Reference count of underlying object. Is set to -1 once the
79 /// object has been destroyed to indicate to all weak pointers that
80 /// it is no longer valid.
83 /// Reference count of this counter.
86 /// Mutex variable to synchronize access to the reference counts.
91 template <class X
, class ACE_LOCK
> class ACE_Weak_Bound_Ptr
;
94 * @class ACE_Strong_Bound_Ptr
96 * @brief This class implements support for a reference counted
99 * Assigning or copying instances of an ACE_Strong_Bound_Ptr will
100 * automatically increment the reference count of the underlying object.
101 * When the last instance of an ACE_Strong_Bound_Ptr that references a
102 * particular object is destroyed or overwritten, it will invoke delete
103 * on its underlying pointer.
105 template <class X
, class ACE_LOCK
>
106 class ACE_Strong_Bound_Ptr
109 /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the
110 /// object \<p\> immediately.
111 explicit ACE_Strong_Bound_Ptr (X
*p
= 0);
113 /// Copy constructor binds @c this and @a r to the same object.
114 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
116 /// Constructor binds @c this and @a r to the same object.
117 ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
119 /// Copy constructor binds @c this and @a r to the same object if
120 /// Y* can be implicitly converted to X*.
122 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr
<Y
, ACE_LOCK
> &r
)
123 : counter_ (r
.counter_
),
124 ptr_ (dynamic_cast<X
*>(r
.ptr_
))
126 // This ctor is temporarily defined here to increase our chances
127 // of being accepted by broken compilers.
129 COUNTER::attach_strong (this->counter_
);
133 ~ACE_Strong_Bound_Ptr ();
135 /// Assignment operator that binds @c this and @a r to the same object.
136 void operator = (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
138 /// Assignment operator that binds @c this and @a r to the same object.
139 void operator = (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
141 /// Assignment operator that binds @c this and @a r to the same object
142 /// if Y* can be implicitly converted to X*.
144 ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
>&
145 operator= (const ACE_Strong_Bound_Ptr
<Y
, ACE_LOCK
> &r
)
147 // This operator is temporarily defined here to increase our chances
148 // of being accepted by broken compilers.
151 // This will work if &r == this, by first increasing the ref count
153 COUNTER
*new_counter
= r
.counter_
;
154 X
* new_ptr
= dynamic_cast<X
*> (r
.ptr_
);
155 COUNTER::attach_strong (new_counter
);
156 if (COUNTER::detach_strong (this->counter_
) == 0)
158 this->counter_
= new_counter
;
159 this->ptr_
= new_ptr
;
164 /// Equality operator that returns @c true if both
165 /// ACE_Strong_Bound_Ptr instances point to the same underlying
168 * @note It also returns @c true if both objects have just been
169 * instantiated and not used yet.
171 bool operator == (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
173 /// Equality operator that returns true if the ACE_Strong_Bound_Ptr
174 /// and ACE_Weak_Bound_Ptr objects point to the same underlying
177 * @note It also returns @c true if both objects have just been
178 * instantiated and not used yet.
180 bool operator == (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
182 /// Equality operator that returns @c true if the
183 /// ACE_Strong_Bound_Ptr and the raw pointer point to the same
184 /// underlying object.
185 bool operator == (X
*p
) const;
187 /// Inequality operator, which is the opposite of equality.
188 bool operator != (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
190 /// Inequality operator, which is the opposite of equality.
191 bool operator != (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
193 /// Inequality operator, which is the opposite of equality.
194 bool operator != (X
*p
) const;
196 /// Redirection operator
197 X
*operator-> () const;
199 /// Dereference operator
200 X
&operator * () const;
202 /// Get the pointer value.
205 /// Resets the ACE_Strong_Bound_Ptr to refer to a different
206 /// underlying object.
207 void reset (X
*p
= 0);
209 /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr
213 /// Declare the dynamic allocation hooks.
214 ACE_ALLOC_HOOK_DECLARE
;
217 friend class ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
>;
219 template <class Y
, class L
>
220 friend class ACE_Strong_Bound_Ptr
;
222 /// The ACE_Bound_Ptr_Counter type.
223 typedef ACE_Bound_Ptr_Counter
<ACE_LOCK
> COUNTER
;
225 /// The reference counter.
228 /// The underlying object.
233 * @class ACE_Weak_Bound_Ptr
235 * @brief This class implements support for a weak pointer that complements
236 * ACE_Strong_Bound_Ptr.
238 * Unlike ACE_Strong_Bound_Ptr, assigning or copying instances of an
239 * ACE_Weak_Bound_Ptr will not automatically increment the reference
240 * count of the underlying object. What ACE_Weak_Bound_Ptr does is
241 * preserve the knowledge that the object is in fact reference
242 * counted, and thus provides an alternative to raw pointers where
243 * non-ownership associations must be maintained. When the last
244 * instance of an ACE_Strong_Bound_Ptr that references a particular
245 * object is destroyed or overwritten, the corresponding
246 * ACE_Weak_Bound_Ptr instances are set to NULL.
248 template <class X
, class ACE_LOCK
>
249 class ACE_Weak_Bound_Ptr
252 /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to
253 /// the object \<p\> immediately.
254 explicit ACE_Weak_Bound_Ptr (X
*p
= 0);
256 /// Copy constructor binds @c this and @a r to the same object.
257 ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
259 /// Constructor binds @c this and @a r to the same object.
260 ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
263 ~ACE_Weak_Bound_Ptr ();
265 /// Assignment operator that binds @c this and @a r to the same object.
266 void operator = (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
268 /// Assignment operator that binds @c this and @a r to the same object.
269 void operator = (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
271 /// Equality operator that returns @c true if both
272 /// ACE_Weak_Bound_Ptr objects point to the same underlying object.
274 * @note It also returns @c true if both objects have just been
275 * instantiated and not used yet.
277 bool operator == (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
279 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
280 /// and ACE_Strong_Bound_Ptr objects point to the same underlying
283 * @note It also returns @c true if both objects have just been
284 * instantiated and not used yet.
286 bool operator == (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
288 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
289 /// and the raw pointer point to the same underlying object.
290 bool operator == (X
*p
) const;
292 /// Inequality operator, which is the opposite of equality.
293 bool operator != (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
295 /// Inequality operator, which is the opposite of equality.
296 bool operator != (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
298 /// Inequality operator, which is the opposite of equality.
299 bool operator != (X
*p
) const;
301 /// Redirection operator.
303 * It returns a temporary strong pointer and makes use of the
304 * chaining properties of operator-> to ensure that the underlying
305 * object does not disappear while you are using it. If you are
306 * certain of the lifetimes of the object, and do not want to incur
307 * the locking overhead, then use the unsafe_get method instead.
309 ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> operator-> () const;
311 /// Obtain a strong pointer corresponding to this weak pointer. This
312 /// function is useful to create a temporary strong pointer for
313 /// conversion to a reference.
314 ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> strong () const;
316 /// Get the pointer value. Warning: this does not affect the
317 /// reference count of the underlying object, so it may disappear on
318 /// you while you are using it if you are not careful.
319 X
*unsafe_get () const;
321 /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying
323 void reset (X
*p
= 0);
325 /// Increment the reference count on the underlying object.
327 * Returns the new reference count on the object. This function may
328 * be used to integrate the bound pointers into an external
329 * reference counting mechanism such as those used by COM or CORBA
334 /// Decrement the reference count on the underlying object, which is deleted
335 /// if the count has reached zero.
337 * Returns the new reference count on the object. This function may
338 * be used to integrate the bound pointers into an external
339 * reference counting mechanism such as those used by COM or CORBA
344 /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects.
347 /// Declare the dynamic allocation hooks.
348 ACE_ALLOC_HOOK_DECLARE
;
351 friend class ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
>;
353 /// The ACE_Bound_Ptr_Counter type.
354 typedef ACE_Bound_Ptr_Counter
<ACE_LOCK
> COUNTER
;
356 /// The reference counter.
359 /// The underlying object.
363 ACE_END_VERSIONED_NAMESPACE_DECL
365 #if defined (__ACE_INLINE__)
366 #include "ace/Bound_Ptr.inl"
367 #endif /* __ACE_INLINE__ */
369 #include "ace/Bound_Ptr.cpp"
371 #include /**/ "ace/post.h"
373 #endif /* ACE_BOUND_PTR_H */