Removed ACE_HAS_BSTRING, not used
[ACE_TAO.git] / ACE / ace / Bound_Ptr.inl
blob826c9aa9898c77057036fdb26d5d2583438fd2e7
1 /* -*- C++ -*- */
2 #include "ace/Guard_T.h"
3 #if !defined (ACE_NEW_THROWS_EXCEPTIONS)
4 #  include "ace/Log_Category.h"
5 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
7 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
9 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
10 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
12   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
13   ACE_NEW_RETURN (temp,
14                   ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
15                   0);
16   return temp;
19 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
20 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong (void)
22   // Set initial object reference count to 1.
23   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
24 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
25   if (temp == 0)
26     ACE_throw_bad_alloc;
27 #else
28   ACE_ASSERT (temp != 0);
29 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
30   return temp;
35 template <class ACE_LOCK> inline long
36 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
38   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
40   // Can't attach a strong pointer to an object that has already been deleted.
41   if (counter->obj_ref_count_ == -1)
42     return -1;
44   long new_obj_ref_count = ++counter->obj_ref_count_;
45   ++counter->self_ref_count_;
47   return new_obj_ref_count;
50 template <class ACE_LOCK> inline long
51 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
53   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
54   long new_obj_ref_count;
56   {
57     ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
59     if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
60       // Change the object reference count to -1 to indicate that the
61       // object has been deleted, as opposed to a weak pointer that
62       // simply hasn't had any strong pointers created from it yet.
63       counter->obj_ref_count_ = -1;
65     if (--counter->self_ref_count_ == 0)
66       // Since counter contains the lock held by the guard, the
67       // guard needs to be released before freeing the memory holding
68       // the lock. So save the pointer to free, then release, then
69       // free.
70       counter_del = counter;
72   }  // Release the lock
74   delete counter_del;
76   return new_obj_ref_count;
79 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
80 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak (void)
82   // Set initial object reference count to 0.
84   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
85 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
86   if (temp == 0)
87     ACE_throw_bad_alloc;
88 #else
89   ACE_ASSERT (temp != 0);
90 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
91   return temp;
94 template <class ACE_LOCK> inline void
95 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
97   ACE_GUARD (ACE_LOCK, guard, counter->lock_);
99   ++counter->self_ref_count_;
102 template <class ACE_LOCK> inline void
103 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
105   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
107   {
108     ACE_GUARD (ACE_LOCK, guard, counter->lock_);
110     if (--counter->self_ref_count_ == 0)
111       // Since counter contains the lock held by the guard, the
112       // guard needs to be released before freeing the memory holding
113       // the lock. So save the pointer to free, then release, then
114       // free.
115       counter_del = counter;
117   }  // Release the lock
119   delete counter_del;
122 template <class ACE_LOCK> inline bool
123 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
125   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
127   return counter->obj_ref_count_ == -1;
130 template <class ACE_LOCK> inline
131 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
132   : obj_ref_count_ (init_obj_ref_count),
133     self_ref_count_ (1)
137 template <class ACE_LOCK> inline
138 ACE_Bound_Ptr_Counter<ACE_LOCK>::~ACE_Bound_Ptr_Counter (void)
142 template <class X, class ACE_LOCK> inline
143 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
144   : counter_ (COUNTER::create_strong ()),
145     ptr_ (p)
149 #if !defined (ACE_HAS_CPP11)
150 template <class X, class ACE_LOCK> inline
151 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (auto_ptr<X> p)
152   : counter_ (COUNTER::create_strong ()),
153     ptr_ (p.release())
156 #endif /* !ACE_HAS_CPP11 */
158 template <class X, class ACE_LOCK> inline
159 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
160   : counter_ (r.counter_),
161     ptr_ (r.ptr_)
163   COUNTER::attach_strong (this->counter_);
166 template <class X, class ACE_LOCK> inline
167 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
168   : counter_ (r.counter_),
169     ptr_ (r.ptr_)
171   // When creating a strong pointer from a weak one we can't assume that the
172   // underlying object still exists. Therefore we must check for a return value
173   // of -1, which indicates that the object has been destroyed.
174   if (COUNTER::attach_strong (this->counter_) == -1)
175     {
176       // Underlying object has already been deleted, so set this pointer to null.
177       this->counter_ = COUNTER::create_strong ();
178       this->ptr_ = 0;
179     }
182 template <class X, class ACE_LOCK> inline
183 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr (void)
185   if (COUNTER::detach_strong (this->counter_) == 0)
186     delete this->ptr_;
189 template <class X, class ACE_LOCK> inline void
190 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
192   // This will work if &r == this, by first increasing the ref count, but
193   // why go through all that?
194   if (&rhs == this)
195     return;
197   COUNTER *new_counter = rhs.counter_;
198   X_t *new_ptr = rhs.ptr_;
199   COUNTER::attach_strong (new_counter);
200   if (COUNTER::detach_strong (this->counter_) == 0)
201     delete this->ptr_;
202   this->counter_ = new_counter;
203   this->ptr_ = new_ptr;
206 template <class X, class ACE_LOCK> inline void
207 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
209   // This will work if &r == this, by first increasing the ref count, but
210   // why go through all that?
211   if (&rhs == this)
212     return;
214   COUNTER *new_counter = rhs.counter_;
215   X_t *new_ptr = rhs.ptr_;
217   // When creating a strong pointer from a weak one we can't assume that the
218   // underlying object still exists. Therefore we must check for a return value
219   // of -1, which indicates that the object has been destroyed.
220   if (COUNTER::attach_strong (new_counter) == -1)
221     {
222       // Underlying object has already been deleted, so set this pointer to null.
223       new_counter = COUNTER::create_strong ();
224       new_ptr = 0;
225     }
227   if (COUNTER::detach_strong (this->counter_) == 0)
228     delete this->ptr_;
229   this->counter_ = new_counter;
230   this->ptr_ = new_ptr;
233 template <class X, class ACE_LOCK> inline bool
234 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
236   return this->ptr_ == r.ptr_;
239 template <class X, class ACE_LOCK> inline bool
240 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
242   // Use the weak pointer's operator== since it will check for null.
243   return r == *this;
246 template <class X, class ACE_LOCK> inline bool
247 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
249   return this->ptr_ == p;
252 template <class X, class ACE_LOCK> inline bool
253 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
255   return this->ptr_ != r.ptr_;
258 template <class X, class ACE_LOCK> inline bool
259 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
261   // Use the weak pointer's operator!= since it will check for null.
262   return r != *this;
265 template <class X, class ACE_LOCK> inline bool
266 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
268   return this->ptr_ != p;
271 template <class X, class ACE_LOCK> inline X *
272 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
274   return this->ptr_;
277 template<class X, class ACE_LOCK> inline X &
278 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
280   return *this->ptr_;
283 template <class X, class ACE_LOCK> inline X*
284 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get (void) const
286   return this->ptr_;
289 template <class X, class ACE_LOCK> inline bool
290 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
292   return this->ptr_ == 0;
295 template<class X, class ACE_LOCK> inline void
296 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
298   COUNTER *old_counter = this->counter_;
299   X_t *old_ptr = this->ptr_;
300   this->counter_ = COUNTER::create_strong ();
301   this->ptr_ = p;
302   if (COUNTER::detach_strong (old_counter) == 0)
303     delete old_ptr;
306 #if !defined (ACE_HAS_CPP11)
307 template<class X, class ACE_LOCK> inline void
308 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
310   COUNTER *old_counter = this->counter_;
311   X_t *old_ptr = this->ptr_;
312   this->counter_ = COUNTER::create_strong ();
313   this->ptr_ = p.release ();
314   if (COUNTER::detach_strong (old_counter) == 0)
315     delete old_ptr;
317 #endif /* !ACE_HAS_CPP11 */
319 template <class X, class ACE_LOCK> inline
320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
321   : counter_ (COUNTER::create_weak ()),
322     ptr_ (p)
326 template <class X, class ACE_LOCK> inline
327 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
328   : counter_ (r.counter_),
329     ptr_ (r.ptr_)
331   COUNTER::attach_weak (this->counter_);
334 template <class X, class ACE_LOCK> inline
335 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
336   : counter_ (r.counter_),
337     ptr_ (r.ptr_)
339   COUNTER::attach_weak (this->counter_);
342 template <class X, class ACE_LOCK> inline
343 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
345   COUNTER::detach_weak (this->counter_);
348 template <class X, class ACE_LOCK> inline void
349 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
351   // This will work if &rhs == this, by first increasing the ref count
352   COUNTER *new_counter = rhs.counter_;
353   COUNTER::attach_weak (new_counter);
354   COUNTER::detach_weak (this->counter_);
355   this->counter_ = new_counter;
356   this->ptr_ = rhs.ptr_;
359 template <class X, class ACE_LOCK> inline void
360 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
362   // This will work if &rhs == this, by first increasing the ref count
363   COUNTER *new_counter = rhs.counter_;
364   COUNTER::attach_weak (new_counter);
365   COUNTER::detach_weak (this->counter_);
366   this->counter_ = new_counter;
367   this->ptr_ = rhs.ptr_;
370 template <class X, class ACE_LOCK> inline bool
371 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
373   // A weak pointer must behave as though it is automatically set to null
374   // if the underlying object has been deleted.
375   if (COUNTER::object_was_deleted (this->counter_))
376     return r.ptr_ == 0;
378   return this->ptr_ == r.ptr_;
381 template <class X, class ACE_LOCK> inline bool
382 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
384   // A weak pointer must behave as though it is automatically set to null
385   // if the underlying object has been deleted.
386   if (COUNTER::object_was_deleted (this->counter_))
387     return r.ptr_ == 0;
389   return this->ptr_ == r.ptr_;
392 template <class X, class ACE_LOCK> inline bool
393 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
395   // A weak pointer must behave as though it is automatically set to null
396   // if the underlying object has been deleted.
397   if (COUNTER::object_was_deleted (this->counter_))
398     return p == 0;
400   return this->ptr_ == p;
403 template <class X, class ACE_LOCK> inline bool
404 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
406   // A weak pointer must behave as though it is automatically set to null
407   // if the underlying object has been deleted.
408   if (COUNTER::object_was_deleted (this->counter_))
409     return r.ptr_ != 0;
411   return this->ptr_ != r.ptr_;
414 template <class X, class ACE_LOCK> inline bool
415 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
417   // A weak pointer must behave as though it is automatically set to null
418   // if the underlying object has been deleted.
419   if (COUNTER::object_was_deleted (this->counter_))
420     return r.ptr_ != 0;
422   return this->ptr_ != r.ptr_;
425 template <class X, class ACE_LOCK> inline bool
426 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
428   // A weak pointer must behave as though it is automatically set to null
429   // if the underlying object has been deleted.
430   if (COUNTER::object_was_deleted (this->counter_))
431     return p != 0;
433   return this->ptr_ != p;
436 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
439   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
442 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong (void) const
445   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
448 template <class X, class ACE_LOCK> inline X*
449 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
451   // We do not check if the object has been deleted, since this operation
452   // is defined to be unsafe!
453   return this->ptr_;
456 template <class X, class ACE_LOCK> inline bool
457 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
459   // A weak pointer must behave as though it is automatically set to null
460   // if the underlying object has been deleted.
461   if (COUNTER::object_was_deleted (this->counter_))
462     return true;
464   return this->ptr_ == 0;
467 template<class X, class ACE_LOCK> inline void
468 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
470   COUNTER *old_counter = this->counter_;
471   this->counter_ = COUNTER::create_weak ();
472   this->ptr_ = p;
473   COUNTER::detach_weak (old_counter);
476 template<class X, class ACE_LOCK> inline long
477 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
479   return COUNTER::attach_strong (counter_);
482 template<class X, class ACE_LOCK> inline long
483 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
485   long new_obj_ref_count = COUNTER::detach_strong (counter_);
486   if (new_obj_ref_count == 0)
487     {
488       delete this->ptr_;
489       this->ptr_ = 0;
490     }
491   return new_obj_ref_count;
494 ACE_END_VERSIONED_NAMESPACE_DECL