1 #ifndef ACE_UNBOUNDED_QUEUE_CPP
2 #define ACE_UNBOUNDED_QUEUE_CPP
4 #include "ace/Unbounded_Queue.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #if !defined (__ACE_INLINE__)
11 #include "ace/Unbounded_Queue.inl"
12 #endif /* __ACE_INLINE__ */
14 #include "ace/Malloc_Base.h"
15 #include "ace/Log_Category.h"
16 #include "ace/os_include/os_errno.h"
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE_Tc(ACE_Unbounded_Queue
)
23 ACE_Unbounded_Queue
<T
>::ACE_Unbounded_Queue (ACE_Allocator
*alloc
)
28 // ACE_TRACE ("ACE_Unbounded_Queue<T>::ACE_Unbounded_Queue ()");
30 if (this->allocator_
== 0)
31 this->allocator_
= ACE_Allocator::instance ();
33 ACE_NEW_MALLOC (this->head_
,
34 (ACE_Node
<T
> *) this->allocator_
->malloc (sizeof (ACE_Node
<T
>)),
36 // Make the list circular by pointing it back to itself.
37 this->head_
->next_
= this->head_
;
41 ACE_Unbounded_Queue
<T
>::ACE_Unbounded_Queue (const ACE_Unbounded_Queue
<T
> &us
)
44 allocator_ (us
.allocator_
)
46 // ACE_TRACE ("ACE_Unbounded_Queue<T>::ACE_Unbounded_Queue");
48 if (this->allocator_
== 0)
49 this->allocator_
= ACE_Allocator::instance ();
51 ACE_NEW_MALLOC (this->head_
,
52 (ACE_Node
<T
> *) this->allocator_
->malloc (sizeof (ACE_Node
<T
>)),
54 this->head_
->next_
= this->head_
;
55 this->copy_nodes (us
);
58 template <class T
> void
59 ACE_Unbounded_Queue
<T
>::operator= (const ACE_Unbounded_Queue
<T
> &us
)
61 // ACE_TRACE ("ACE_Unbounded_Queue<T>::operator=");
65 this->delete_nodes ();
66 this->copy_nodes (us
);
70 template <class T
> ACE_Unbounded_Queue_Iterator
<T
>
71 ACE_Unbounded_Queue
<T
>::begin ()
73 // ACE_TRACE ("ACE_Unbounded_Queue<T>::begin");
74 return ACE_Unbounded_Queue_Iterator
<T
> (*this);
77 template <class T
> ACE_Unbounded_Queue_Iterator
<T
>
78 ACE_Unbounded_Queue
<T
>::end ()
80 // ACE_TRACE ("ACE_Unbounded_Queue<T>::end");
81 return ACE_Unbounded_Queue_Iterator
<T
> (*this, 1);
84 template <class T
> void
85 ACE_Unbounded_Queue
<T
>::dump () const
87 #if defined (ACE_HAS_DUMP)
88 // ACE_TRACE ("ACE_Unbounded_Queue<T>::dump");
90 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
91 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhead_ = %u"), this->head_
));
92 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhead_->next_ = %u"), this->head_
->next_
));
93 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ncur_size_ = %d\n"), this->cur_size_
));
96 #if !defined (ACE_NLOGGING)
98 #endif /* ! ACE_NLOGGING */
100 for (ACE_Unbounded_Queue_Iterator
<T
> iter (*(ACE_Unbounded_Queue
<T
> *) this);
101 iter
.next (item
) != 0;
103 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("count = %d\n"), count
++));
105 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
106 #endif /* ACE_HAS_DUMP */
109 template <class T
> void
110 ACE_Unbounded_Queue
<T
>::copy_nodes (const ACE_Unbounded_Queue
<T
> &us
)
112 for (ACE_Node
<T
> *curr
= us
.head_
->next_
;
115 if (this->enqueue_tail (curr
->item_
) == -1)
116 // @@ What's the right thing to do here?
117 this->delete_nodes ();
120 template <class T
> void
121 ACE_Unbounded_Queue
<T
>::delete_nodes ()
123 for (ACE_Node
<T
> *curr
= this->head_
->next_
;
124 // Keep looking until we've hit the dummy node.
128 ACE_Node
<T
> *temp
= curr
;
131 ACE_DES_FREE_TEMPLATE (temp
,
132 this->allocator_
->free
,
136 // @@ Doesnt make sense to have this check since
137 // this will always be true.
138 // ACE_ASSERT (this->cur_size_ >= 0);
141 // Reset the list to be a circular list with just a dummy node.
142 this->head_
->next_
= this->head_
;
146 ACE_Unbounded_Queue
<T
>::~ACE_Unbounded_Queue ()
148 // ACE_TRACE ("ACE_Unbounded_Queue<T>::~ACE_Unbounded_Queue ()");
150 this->delete_nodes ();
151 ACE_DES_FREE_TEMPLATE (head_
,
152 this->allocator_
->free
,
157 template <class T
> int
158 ACE_Unbounded_Queue
<T
>::enqueue_head (const T
&new_item
)
160 // ACE_TRACE ("ACE_Unbounded_Queue<T>::enqueue_head");
162 ACE_Node
<T
> *temp
= 0;
164 // Create a new node that points to the original head.
165 ACE_NEW_MALLOC_RETURN (temp
,
166 static_cast<ACE_Node
<T
> *> (this->allocator_
->malloc (sizeof (ACE_Node
<T
>))),
167 ACE_Node
<T
> (new_item
, this->head_
->next_
),
169 // Link this pointer into the front of the list. Note that the
170 // "real" head of the queue is <head_->next_>, whereas <head_> is
171 // just a pointer to the dummy node.
172 this->head_
->next_
= temp
;
178 template <class T
> int
179 ACE_Unbounded_Queue
<T
>::enqueue_tail (const T
&new_item
)
181 // ACE_TRACE ("ACE_Unbounded_Queue<T>::enqueue_tail");
183 // Insert <item> into the old dummy node location. Note that this
184 // isn't actually the "head" item in the queue, it's a dummy node at
185 // the "tail" of the queue...
186 this->head_
->item_
= new_item
;
188 ACE_Node
<T
> *temp
= 0;
190 // Create a new dummy node.
191 ACE_NEW_MALLOC_RETURN (temp
,
192 static_cast<ACE_Node
<T
> *> (this->allocator_
->malloc (sizeof (ACE_Node
<T
>))),
193 ACE_Node
<T
> (this->head_
->next_
),
195 // Link this dummy pointer into the list.
196 this->head_
->next_
= temp
;
198 // Point the head to the new dummy node.
205 template <class T
> int
206 ACE_Unbounded_Queue
<T
>::dequeue_head (T
&item
)
208 // ACE_TRACE ("ACE_Unbounded_Queue<T>::dequeue_head");
210 // Check for empty queue.
211 if (this->is_empty ())
214 ACE_Node
<T
> *temp
= this->head_
->next_
;
217 this->head_
->next_
= temp
->next_
;
218 ACE_DES_FREE_TEMPLATE (temp
,
219 this->allocator_
->free
,
226 template <class T
> void
227 ACE_Unbounded_Queue
<T
>::reset ()
231 this->delete_nodes ();
234 template <class T
> int
235 ACE_Unbounded_Queue
<T
>::get (T
*&item
, size_t slot
) const
237 // ACE_TRACE ("ACE_Unbounded_Queue<T>::get");
239 ACE_Node
<T
> *curr
= this->head_
->next_
;
243 for (i
= 0; i
< this->cur_size_
; i
++)
251 if (i
< this->cur_size_
)
260 template <class T
> int
261 ACE_Unbounded_Queue
<T
>::set (const T
&item
,
264 // ACE_TRACE ("ACE_Unbounded_Queue<T>::set");
266 ACE_Node
<T
> *curr
= this->head_
->next_
;
271 i
< slot
&& i
< this->cur_size_
;
275 if (i
< this->cur_size_
)
277 // We're in range, so everything's cool.
283 // We need to expand the list.
285 // A common case will be increasing the set size by 1.
286 // Therefore, we'll optimize for this case.
289 // Try to expand the size of the set by 1.
290 if (this->enqueue_tail (item
) == -1)
297 T
const dummy
= T ();
299 // We need to expand the list by multiple (dummy) items.
300 for (; i
< slot
; ++i
)
302 // This head points to the existing dummy node, which is
303 // about to be overwritten when we add the new dummy
307 // Try to expand the size of the set by 1, but don't
308 // store anything in the dummy node (yet).
309 if (this->enqueue_tail (dummy
) == -1)
319 // ****************************************************************
321 template <class T
> void
322 ACE_Unbounded_Queue_Const_Iterator
<T
>::dump () const
324 #if defined (ACE_HAS_DUMP)
325 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::dump");
326 #endif /* ACE_HAS_DUMP */
330 ACE_Unbounded_Queue_Const_Iterator
<T
>::ACE_Unbounded_Queue_Const_Iterator (const ACE_Unbounded_Queue
<T
> &q
, int end
)
331 : current_ (end
== 0 ? q
.head_
->next_
: q
.head_
),
334 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::ACE_Unbounded_Queue_Const_Iterator");
337 template <class T
> int
338 ACE_Unbounded_Queue_Const_Iterator
<T
>::advance ()
340 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::advance");
341 this->current_
= this->current_
->next_
;
342 return this->current_
!= this->queue_
.head_
;
345 template <class T
> int
346 ACE_Unbounded_Queue_Const_Iterator
<T
>::first ()
348 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::first");
349 this->current_
= this->queue_
.head_
->next_
;
350 return this->current_
!= this->queue_
.head_
;
353 template <class T
> int
354 ACE_Unbounded_Queue_Const_Iterator
<T
>::done () const
356 ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::done");
358 return this->current_
== this->queue_
.head_
;
361 template <class T
> int
362 ACE_Unbounded_Queue_Const_Iterator
<T
>::next (T
*&item
)
364 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::next");
365 if (this->current_
== this->queue_
.head_
)
369 item
= &this->current_
->item_
;
374 // ****************************************************************
376 template <class T
> void
377 ACE_Unbounded_Queue_Iterator
<T
>::dump () const
379 #if defined (ACE_HAS_DUMP)
380 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::dump");
381 #endif /* ACE_HAS_DUMP */
385 ACE_Unbounded_Queue_Iterator
<T
>::ACE_Unbounded_Queue_Iterator (ACE_Unbounded_Queue
<T
> &q
, int end
)
386 : current_ (end
== 0 ? q
.head_
->next_
: q
.head_
),
389 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::ACE_Unbounded_Queue_Iterator");
392 template <class T
> int
393 ACE_Unbounded_Queue_Iterator
<T
>::advance ()
395 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::advance");
396 this->current_
= this->current_
->next_
;
397 return this->current_
!= this->queue_
.head_
;
400 template <class T
> int
401 ACE_Unbounded_Queue_Iterator
<T
>::first ()
403 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::first");
404 this->current_
= this->queue_
.head_
->next_
;
405 return this->current_
!= this->queue_
.head_
;
408 template <class T
> int
409 ACE_Unbounded_Queue_Iterator
<T
>::done () const
411 ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::done");
413 return this->current_
== this->queue_
.head_
;
416 template <class T
> int
417 ACE_Unbounded_Queue_Iterator
<T
>::next (T
*&item
)
419 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::next");
420 if (this->current_
== this->queue_
.head_
)
424 item
= &this->current_
->item_
;
429 ACE_END_VERSIONED_NAMESPACE_DECL
431 #endif /* ACE_UNBOUNDED_QUEUE_CPP */