Document return values
[ACE_TAO.git] / ACE / ace / Bound_Ptr.inl
blob5dd1c8b06aae1fb9d2cf35bd25960bf312406b30
1 /* -*- C++ -*- */
2 #include "ace/Guard_T.h"
4 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
6 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
7 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
9   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
10   ACE_NEW_RETURN (temp,
11                   ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
12                   0);
13   return temp;
16 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
17 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong ()
19   // Set initial object reference count to 1.
20   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
21   if (!temp)
22     throw std::bad_alloc ();
23   return temp;
26 template <class ACE_LOCK> inline long
27 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
29   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
31   // Can't attach a strong pointer to an object that has already been deleted.
32   if (counter->obj_ref_count_ == -1)
33     return -1;
35   long const new_obj_ref_count = ++counter->obj_ref_count_;
36   ++counter->self_ref_count_;
38   return new_obj_ref_count;
41 template <class ACE_LOCK> inline long
42 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
44   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
45   long new_obj_ref_count;
47   {
48     ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
50     if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
51       // Change the object reference count to -1 to indicate that the
52       // object has been deleted, as opposed to a weak pointer that
53       // simply hasn't had any strong pointers created from it yet.
54       counter->obj_ref_count_ = -1;
56     if (--counter->self_ref_count_ == 0)
57       // Since counter contains the lock held by the guard, the
58       // guard needs to be released before freeing the memory holding
59       // the lock. So save the pointer to free, then release, then
60       // free.
61       counter_del = counter;
63   }  // Release the lock
65   delete counter_del;
67   return new_obj_ref_count;
70 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
71 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak ()
73   // Set initial object reference count to 0.
75   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
76   if (!temp)
77     throw std::bad_alloc ();
78   return temp;
81 template <class ACE_LOCK> inline void
82 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
84   ACE_GUARD (ACE_LOCK, guard, counter->lock_);
86   ++counter->self_ref_count_;
89 template <class ACE_LOCK> inline void
90 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
92   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
94   {
95     ACE_GUARD (ACE_LOCK, guard, counter->lock_);
97     if (--counter->self_ref_count_ == 0)
98       // Since counter contains the lock held by the guard, the
99       // guard needs to be released before freeing the memory holding
100       // the lock. So save the pointer to free, then release, then
101       // free.
102       counter_del = counter;
104   }  // Release the lock
106   delete counter_del;
109 template <class ACE_LOCK> inline bool
110 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
112   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
114   return counter->obj_ref_count_ == -1;
117 template <class ACE_LOCK> inline
118 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
119   : obj_ref_count_ (init_obj_ref_count),
120     self_ref_count_ (1)
124 template <class X, class ACE_LOCK> inline
125 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
126   : counter_ (COUNTER::create_strong ()),
127     ptr_ (p)
131 template <class X, class ACE_LOCK> inline
132 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
133   : counter_ (r.counter_),
134     ptr_ (r.ptr_)
136   COUNTER::attach_strong (this->counter_);
139 template <class X, class ACE_LOCK> inline
140 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
141   : counter_ (r.counter_),
142     ptr_ (r.ptr_)
144   // When creating a strong pointer from a weak one we can't assume that the
145   // underlying object still exists. Therefore we must check for a return value
146   // of -1, which indicates that the object has been destroyed.
147   if (COUNTER::attach_strong (this->counter_) == -1)
148     {
149       // Underlying object has already been deleted, so set this pointer to null.
150       this->counter_ = COUNTER::create_strong ();
151       this->ptr_ = 0;
152     }
155 template <class X, class ACE_LOCK> inline
156 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr ()
158   if (COUNTER::detach_strong (this->counter_) == 0)
159     delete this->ptr_;
162 template <class X, class ACE_LOCK> inline void
163 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
165   // This will work if &r == this, by first increasing the ref count, but
166   // why go through all that?
167   if (&rhs == this)
168     return;
170   COUNTER *new_counter = rhs.counter_;
171   X *new_ptr = rhs.ptr_;
172   COUNTER::attach_strong (new_counter);
173   if (COUNTER::detach_strong (this->counter_) == 0)
174     delete this->ptr_;
175   this->counter_ = new_counter;
176   this->ptr_ = new_ptr;
179 template <class X, class ACE_LOCK> inline void
180 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
182   // This will work if &r == this, by first increasing the ref count, but
183   // why go through all that?
184   if (&rhs == this)
185     return;
187   COUNTER *new_counter = rhs.counter_;
188   X *new_ptr = rhs.ptr_;
190   // When creating a strong pointer from a weak one we can't assume that the
191   // underlying object still exists. Therefore we must check for a return value
192   // of -1, which indicates that the object has been destroyed.
193   if (COUNTER::attach_strong (new_counter) == -1)
194     {
195       // Underlying object has already been deleted, so set this pointer to null.
196       new_counter = COUNTER::create_strong ();
197       new_ptr = 0;
198     }
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 bool
207 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
209   return this->ptr_ == r.ptr_;
212 template <class X, class ACE_LOCK> inline bool
213 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
215   // Use the weak pointer's operator== since it will check for null.
216   return r == *this;
219 template <class X, class ACE_LOCK> inline bool
220 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
222   return this->ptr_ == p;
225 template <class X, class ACE_LOCK> inline bool
226 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
228   return this->ptr_ != r.ptr_;
231 template <class X, class ACE_LOCK> inline bool
232 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
234   // Use the weak pointer's operator!= since it will check for null.
235   return r != *this;
238 template <class X, class ACE_LOCK> inline bool
239 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
241   return this->ptr_ != p;
244 template <class X, class ACE_LOCK> inline X *
245 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> () const
247   return this->ptr_;
250 template<class X, class ACE_LOCK> inline X &
251 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
253   return *this->ptr_;
256 template <class X, class ACE_LOCK> inline X*
257 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get () const
259   return this->ptr_;
262 template <class X, class ACE_LOCK> inline bool
263 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null () const
265   return this->ptr_ == 0;
268 template<class X, class ACE_LOCK> inline void
269 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
271   COUNTER *old_counter = this->counter_;
272   X *old_ptr = this->ptr_;
273   this->counter_ = COUNTER::create_strong ();
274   this->ptr_ = p;
275   if (COUNTER::detach_strong (old_counter) == 0)
276     delete old_ptr;
279 template <class X, class ACE_LOCK> inline
280 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
281   : counter_ (COUNTER::create_weak ()),
282     ptr_ (p)
286 template <class X, class ACE_LOCK> inline
287 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
288   : counter_ (r.counter_),
289     ptr_ (r.ptr_)
291   COUNTER::attach_weak (this->counter_);
294 template <class X, class ACE_LOCK> inline
295 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
296   : counter_ (r.counter_),
297     ptr_ (r.ptr_)
299   COUNTER::attach_weak (this->counter_);
302 template <class X, class ACE_LOCK> inline
303 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr ()
305   COUNTER::detach_weak (this->counter_);
308 template <class X, class ACE_LOCK> inline void
309 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
311   // This will work if &rhs == this, by first increasing the ref count
312   COUNTER *new_counter = rhs.counter_;
313   COUNTER::attach_weak (new_counter);
314   COUNTER::detach_weak (this->counter_);
315   this->counter_ = new_counter;
316   this->ptr_ = rhs.ptr_;
319 template <class X, class ACE_LOCK> inline void
320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
322   // This will work if &rhs == this, by first increasing the ref count
323   COUNTER *new_counter = rhs.counter_;
324   COUNTER::attach_weak (new_counter);
325   COUNTER::detach_weak (this->counter_);
326   this->counter_ = new_counter;
327   this->ptr_ = rhs.ptr_;
330 template <class X, class ACE_LOCK> inline bool
331 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
333   // A weak pointer must behave as though it is automatically set to null
334   // if the underlying object has been deleted.
335   if (COUNTER::object_was_deleted (this->counter_))
336     return r.ptr_ == 0;
338   return this->ptr_ == r.ptr_;
341 template <class X, class ACE_LOCK> inline bool
342 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
344   // A weak pointer must behave as though it is automatically set to null
345   // if the underlying object has been deleted.
346   if (COUNTER::object_was_deleted (this->counter_))
347     return r.ptr_ == 0;
349   return this->ptr_ == r.ptr_;
352 template <class X, class ACE_LOCK> inline bool
353 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
355   // A weak pointer must behave as though it is automatically set to null
356   // if the underlying object has been deleted.
357   if (COUNTER::object_was_deleted (this->counter_))
358     return p == 0;
360   return this->ptr_ == p;
363 template <class X, class ACE_LOCK> inline bool
364 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
366   // A weak pointer must behave as though it is automatically set to null
367   // if the underlying object has been deleted.
368   if (COUNTER::object_was_deleted (this->counter_))
369     return r.ptr_ != 0;
371   return this->ptr_ != r.ptr_;
374 template <class X, class ACE_LOCK> inline bool
375 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
377   // A weak pointer must behave as though it is automatically set to null
378   // if the underlying object has been deleted.
379   if (COUNTER::object_was_deleted (this->counter_))
380     return r.ptr_ != 0;
382   return this->ptr_ != r.ptr_;
385 template <class X, class ACE_LOCK> inline bool
386 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
388   // A weak pointer must behave as though it is automatically set to null
389   // if the underlying object has been deleted.
390   if (COUNTER::object_was_deleted (this->counter_))
391     return p != 0;
393   return this->ptr_ != p;
396 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
397 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> () const
399   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
402 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
403 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong () const
405   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
408 template <class X, class ACE_LOCK> inline X*
409 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get () const
411   // We do not check if the object has been deleted, since this operation
412   // is defined to be unsafe!
413   return this->ptr_;
416 template <class X, class ACE_LOCK> inline bool
417 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null () const
419   // A weak pointer must behave as though it is automatically set to null
420   // if the underlying object has been deleted.
421   if (COUNTER::object_was_deleted (this->counter_))
422     return true;
424   return this->ptr_ == 0;
427 template<class X, class ACE_LOCK> inline void
428 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
430   COUNTER *old_counter = this->counter_;
431   this->counter_ = COUNTER::create_weak ();
432   this->ptr_ = p;
433   COUNTER::detach_weak (old_counter);
436 template<class X, class ACE_LOCK> inline long
437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
439   return COUNTER::attach_strong (counter_);
442 template<class X, class ACE_LOCK> inline long
443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
445   long new_obj_ref_count = COUNTER::detach_strong (counter_);
446   if (new_obj_ref_count == 0)
447     {
448       delete this->ptr_;
449       this->ptr_ = 0;
450     }
451   return new_obj_ref_count;
454 ACE_END_VERSIONED_NAMESPACE_DECL