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 #if !defined (ACE_HAS_CPP11)
24 # include "ace/Auto_Ptr.h"
25 #endif /* !ACE_HAS_CPP11 */
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
30 * @class ACE_Bound_Ptr_Counter
32 * @brief An ACE_Bound_Ptr_Counter<ACE_LOCK> object encapsulates an
33 * object reference count.
35 * Do not use this class directly, use ACE_Strong_Bound_Ptr or
36 * ACE_Weak_Bound_Ptr instead.
38 template <class ACE_LOCK
>
39 class ACE_Bound_Ptr_Counter
42 /// Declare the dynamic allocation hooks.
43 ACE_ALLOC_HOOK_DECLARE
;
45 ACE_Bound_Ptr_Counter (long init_obj_ref_count
= 0);
46 ~ACE_Bound_Ptr_Counter (void);
48 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
49 /// reference count to indicate ownership by a strong pointer.
50 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *create_strong (void);
52 /// Increase both the object and counter reference counts and return
53 /// the new object reference count. A return value of -1 indicates
54 /// that the object has already been destroyed.
55 static long attach_strong (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
57 /// Decreases both the object and counter reference counts and
58 /// deletes whichever has no more references. Returns the new object
60 static long detach_strong (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
62 /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
63 /// reference count to indicate no ownership.
64 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *create_weak (void);
66 /// Increase the counter reference count and return argument.
67 static void attach_weak (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
69 /// Decreases the counter reference count and deletes the counter if
70 /// it has no more references.
71 static void detach_weak (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
73 /// Determine whether the object has been deleted.
74 static bool object_was_deleted (ACE_Bound_Ptr_Counter
<ACE_LOCK
> *counter
);
77 /// Allocate a new ACE_Bound_Ptr_Counter<ACE_LOCK> instance,
78 /// returning NULL if it cannot be created.
79 static ACE_Bound_Ptr_Counter
<ACE_LOCK
> *internal_create (long init_obj_ref_count
);
82 /// Reference count of underlying object. Is set to -1 once the
83 /// object has been destroyed to indicate to all weak pointers that
84 /// it is no longer valid.
87 /// Reference count of this counter.
90 /// Mutex variable to synchronize access to the reference counts.
95 template <class X
, class ACE_LOCK
> class ACE_Weak_Bound_Ptr
;
98 * @class ACE_Strong_Bound_Ptr
100 * @brief This class implements support for a reference counted
103 * Assigning or copying instances of an ACE_Strong_Bound_Ptr will
104 * automatically increment the reference count of the underlying object.
105 * When the last instance of an ACE_Strong_Bound_Ptr that references a
106 * particular object is destroyed or overwritten, it will invoke delete
107 * on its underlying pointer.
109 template <class X
, class ACE_LOCK
>
110 class ACE_Strong_Bound_Ptr
113 /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the
114 /// object \<p\> immediately.
115 explicit ACE_Strong_Bound_Ptr (X
*p
= 0);
117 #if !defined (ACE_HAS_CPP11)
118 /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing
119 /// ownership of an object from an auto_ptr.
120 explicit ACE_Strong_Bound_Ptr (auto_ptr
<X
> p
);
121 #endif /* !ACE_HAS_CPP11 */
123 /// Copy constructor binds @c this and @a r to the same object.
124 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
126 /// Constructor binds @c this and @a r to the same object.
127 ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
129 /// Copy constructor binds @c this and @a r to the same object if
130 /// Y* can be implicitly converted to X*.
132 ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr
<Y
, ACE_LOCK
> &r
)
133 : counter_ (r
.counter_
),
134 ptr_ (dynamic_cast<X_t
*>(r
.ptr_
))
136 // This ctor is temporarily defined here to increase our chances
137 // of being accepted by broken compilers.
139 COUNTER::attach_strong (this->counter_
);
143 ~ACE_Strong_Bound_Ptr (void);
145 /// Assignment operator that binds @c this and @a r to the same object.
146 void operator = (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
148 /// Assignment operator that binds @c this and @a r to the same object.
149 void operator = (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
151 /// Assignment operator that binds @c this and @a r to the same object
152 /// if Y* can be implicitly converted to X*.
154 ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
>&
155 operator= (const ACE_Strong_Bound_Ptr
<Y
, ACE_LOCK
> &r
)
157 // This operator is temporarily defined here to increase our chances
158 // of being accepted by broken compilers.
161 // This will work if &r == this, by first increasing the ref count
163 COUNTER
*new_counter
= r
.counter_
;
164 X
* new_ptr
= dynamic_cast<X_t
*> (r
.ptr_
);
165 COUNTER::attach_strong (new_counter
);
166 if (COUNTER::detach_strong (this->counter_
) == 0)
168 this->counter_
= new_counter
;
169 this->ptr_
= new_ptr
;
174 /// Equality operator that returns @c true if both
175 /// ACE_Strong_Bound_Ptr instances point to the same underlying
178 * @note It also returns @c true if both objects have just been
179 * instantiated and not used yet.
181 bool operator == (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
183 /// Equality operator that returns true if the ACE_Strong_Bound_Ptr
184 /// and ACE_Weak_Bound_Ptr objects point to the same underlying
187 * @note It also returns @c true if both objects have just been
188 * instantiated and not used yet.
190 bool operator == (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
192 /// Equality operator that returns @c true if the
193 /// ACE_Strong_Bound_Ptr and the raw pointer point to the same
194 /// underlying object.
195 bool operator == (X
*p
) const;
197 /// Inequality operator, which is the opposite of equality.
198 bool operator != (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
200 /// Inequality operator, which is the opposite of equality.
201 bool operator != (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
203 /// Inequality operator, which is the opposite of equality.
204 bool operator != (X
*p
) const;
206 /// Redirection operator
207 X
*operator-> (void) const;
209 /// Dereference operator
210 X
&operator * (void) const;
212 /// Get the pointer value.
215 /// Resets the ACE_Strong_Bound_Ptr to refer to a different
216 /// underlying object.
217 void reset (X
*p
= 0);
219 #if !defined (ACE_HAS_CPP11)
220 /// Resets the ACE_Strong_Bound_Ptr to refer to a different
221 /// underlying object, ownership of which is stolen from the
223 void reset (auto_ptr
<X
> p
);
224 #endif /* !ACE_HAS_CPP11 */
226 /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr
228 bool null (void) const;
230 /// Declare the dynamic allocation hooks.
231 ACE_ALLOC_HOOK_DECLARE
;
234 typedef X X_t
; // This indirection is for Borland C++.
236 friend class ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
>;
238 template <class Y
, class L
>
239 friend class ACE_Strong_Bound_Ptr
;
241 /// The ACE_Bound_Ptr_Counter type.
242 typedef ACE_Bound_Ptr_Counter
<ACE_LOCK
> COUNTER
;
244 /// The reference counter.
247 /// The underlying object.
252 * @class ACE_Weak_Bound_Ptr
254 * @brief This class implements support for a weak pointer that complements
255 * ACE_Strong_Bound_Ptr.
257 * Unlike ACE_Strong_Bound_Ptr, assigning or copying instances of an
258 * ACE_Weak_Bound_Ptr will not automatically increment the reference
259 * count of the underlying object. What ACE_Weak_Bound_Ptr does is
260 * preserve the knowledge that the object is in fact reference
261 * counted, and thus provides an alternative to raw pointers where
262 * non-ownership associations must be maintained. When the last
263 * instance of an ACE_Strong_Bound_Ptr that references a particular
264 * object is destroyed or overwritten, the corresponding
265 * ACE_Weak_Bound_Ptr instances are set to NULL.
267 template <class X
, class ACE_LOCK
>
268 class ACE_Weak_Bound_Ptr
271 /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to
272 /// the object \<p\> immediately.
273 explicit ACE_Weak_Bound_Ptr (X
*p
= 0);
275 /// Copy constructor binds @c this and @a r to the same object.
276 ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
278 /// Constructor binds @c this and @a r to the same object.
279 ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
282 ~ACE_Weak_Bound_Ptr (void);
284 /// Assignment operator that binds @c this and @a r to the same object.
285 void operator = (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
);
287 /// Assignment operator that binds @c this and @a r to the same object.
288 void operator = (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
);
290 /// Equality operator that returns @c true if both
291 /// ACE_Weak_Bound_Ptr objects point to the same underlying object.
293 * @note It also returns @c true if both objects have just been
294 * instantiated and not used yet.
296 bool operator == (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
298 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
299 /// and ACE_Strong_Bound_Ptr objects point to the same underlying
302 * @note It also returns @c true if both objects have just been
303 * instantiated and not used yet.
305 bool operator == (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
307 /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
308 /// and the raw pointer point to the same underlying object.
309 bool operator == (X
*p
) const;
311 /// Inequality operator, which is the opposite of equality.
312 bool operator != (const ACE_Weak_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
314 /// Inequality operator, which is the opposite of equality.
315 bool operator != (const ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> &r
) const;
317 /// Inequality operator, which is the opposite of equality.
318 bool operator != (X
*p
) const;
320 /// Redirection operator.
322 * It returns a temporary strong pointer and makes use of the
323 * chaining properties of operator-> to ensure that the underlying
324 * object does not disappear while you are using it. If you are
325 * certain of the lifetimes of the object, and do not want to incur
326 * the locking overhead, then use the unsafe_get method instead.
328 ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> operator-> (void) const;
330 /// Obtain a strong pointer corresponding to this weak pointer. This
331 /// function is useful to create a temporary strong pointer for
332 /// conversion to a reference.
333 ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
> strong (void) const;
335 /// Get the pointer value. Warning: this does not affect the
336 /// reference count of the underlying object, so it may disappear on
337 /// you while you are using it if you are not careful.
338 X
*unsafe_get (void) const;
340 /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying
342 void reset (X
*p
= 0);
344 /// Increment the reference count on the underlying object.
346 * Returns the new reference count on the object. This function may
347 * be used to integrate the bound pointers into an external
348 * reference counting mechanism such as those used by COM or CORBA
353 /// Decrement the reference count on the underlying object, which is deleted
354 /// if the count has reached zero.
356 * Returns the new reference count on the object. This function may
357 * be used to integrate the bound pointers into an external
358 * reference counting mechanism such as those used by COM or CORBA
361 long remove_ref (void);
363 /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects.
364 bool null (void) const;
366 /// Declare the dynamic allocation hooks.
367 ACE_ALLOC_HOOK_DECLARE
;
370 typedef X X_t
; // This indirection is for Borland C++.
372 friend class ACE_Strong_Bound_Ptr
<X
, ACE_LOCK
>;
374 /// The ACE_Bound_Ptr_Counter type.
375 typedef ACE_Bound_Ptr_Counter
<ACE_LOCK
> COUNTER
;
377 /// The reference counter.
380 /// The underlying object.
384 ACE_END_VERSIONED_NAMESPACE_DECL
386 #if defined (__ACE_INLINE__)
387 #include "ace/Bound_Ptr.inl"
388 #endif /* __ACE_INLINE__ */
390 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
391 #include "ace/Bound_Ptr.cpp"
392 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
394 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
395 #pragma implementation ("Bound_Ptr.cpp")
396 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
398 #include /**/ "ace/post.h"
400 #endif /* ACE_BOUND_PTR_H */