GitHub Actions: Try MSVC builds with /std:c++17 and 20
[ACE_TAO.git] / ACE / ace / Hash_Multi_Map_Manager_T.cpp
blob51da4e4e519349919e8d05391f5ff1bc9bd567a4
2 //=============================================================================
3 /**
4 * @file Hash_Multi_Map_Manager_T.cpp
6 * @author Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
7 */
8 //=============================================================================
10 #ifndef ACE_Hash_Multi_Map_Manager_T_CPP
11 #define ACE_Hash_Multi_Map_Manager_T_CPP
13 #include "ace/Hash_Multi_Map_Manager_T.h"
15 #if !defined (ACE_LACKS_PRAGMA_ONCE)
16 # pragma once
17 #endif /* ACE_LACKS_PRAGMA_ONCE */
19 #if !defined (__ACE_INLINE__)
20 # include "ace/Hash_Multi_Map_Manager_T.inl"
21 #endif /* __ACE_INLINE__ */
23 #include "ace/Malloc_Base.h"
25 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
27 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Manager)
28 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Iterator_Base)
29 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Const_Iterator_Base)
30 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Iterator)
31 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Const_Iterator)
32 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Reverse_Iterator)
34 template <class EXT_ID, class INT_ID>
35 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Multi_Map_Entry (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *next,
36 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *prev)
37 : next_ (next),
38 prev_ (prev)
42 template <class EXT_ID, class INT_ID>
43 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Multi_Map_Entry (const EXT_ID &ext_id,
44 const ACE_Unbounded_Set<INT_ID> &int_id_set,
45 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *next,
46 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *prev)
47 : ext_id_ (ext_id),
48 int_id_set_ (int_id_set),
49 next_ (next),
50 prev_ (prev)
54 template <class EXT_ID, class INT_ID>
55 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Multi_Map_Entry (void)
59 template <class EXT_ID, class INT_ID> EXT_ID &
60 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::key ()
62 return ext_id_;
65 template <class EXT_ID, class INT_ID> ACE_Unbounded_Set<INT_ID> &
66 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::item ()
68 return int_id_set_;
71 template <class EXT_ID, class INT_ID> void
72 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::dump (void) const
74 #if defined (ACE_HAS_DUMP)
75 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
76 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
77 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("prev_ = %d"), this->prev_));
78 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
79 #endif /* ACE_HAS_DUMP */
82 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
83 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump (void) const
85 #if defined (ACE_HAS_DUMP)
86 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
87 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("total_size_ = %d"), this->total_size_));
88 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d"), this->cur_size_));
89 this->table_allocator_->dump ();
90 this->entry_allocator_->dump ();
91 this->lock_.dump ();
92 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
93 #endif /* ACE_HAS_DUMP */
96 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
97 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::create_buckets (size_t size)
99 size_t bytes = size * sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>);
100 void *ptr;
102 ACE_ALLOCATOR_RETURN (ptr,
103 this->table_allocator_->malloc (bytes),
104 -1);
106 this->table_ = (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *) ptr;
108 this->total_size_ = size;
110 // Initialize each entry in the hash table to be a circular linked
111 // list with the dummy node in the front serving as the anchor of
112 // the list.
113 for (size_t i = 0; i < size; i++)
114 new (&this->table_[i]) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (&this->table_[i],
115 &this->table_[i]);
116 return 0;
119 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
120 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open (size_t size,
121 ACE_Allocator *table_alloc,
122 ACE_Allocator *entry_alloc)
124 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
126 // Calling this->close_i () to ensure we release previous allocated
127 // memory before allocating new one.
128 this->close_i ();
130 if (table_alloc == 0)
131 table_alloc = ACE_Allocator::instance ();
133 this->table_allocator_ = table_alloc;
135 if (entry_alloc == 0)
136 entry_alloc = table_alloc;
138 this->entry_allocator_ = entry_alloc;
140 // This assertion is here to help track a situation that shouldn't
141 // happen, but did with Sun C++ 4.1 (before a change to this class
142 // was made: it used to have an enum that was supposed to be defined
143 // to be ACE_DEFAULT_MAP_SIZE, but instead was defined to be 0).
144 if (size == 0)
145 return -1;
147 return this->create_buckets (size);
150 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
151 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::close_i (void)
153 // Protect against "double-deletion" in case the destructor also
154 // gets called.
155 if (this->table_ != 0)
157 // Remove all the entries.
158 this->unbind_all_i ();
160 // Iterate through the buckets cleaning up the sentinels.
161 for (size_t i = 0; i < this->total_size_; i++)
163 // Destroy the dummy entry.
164 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *entry = &this->table_[i];
166 // The second argument results in a no-op instead of
167 // deallocation.
168 ACE_DES_FREE_TEMPLATE2 (entry, ACE_NOOP,
169 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
172 // Reset size.
173 this->total_size_ = 0;
175 // Free table memory.
176 this->table_allocator_->free (this->table_);
178 // Should be done last...
179 this->table_ = 0;
182 return 0;
185 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
186 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_all_i (void)
188 // Iterate through the entire map calling the destuctor of each
189 // <ACE_Hash_Multi_Map_Entry>.
190 for (size_t i = 0; i < this->total_size_; i++)
192 for (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp_ptr = this->table_[i].next_;
193 temp_ptr != &this->table_[i];
196 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *hold_ptr = temp_ptr;
197 temp_ptr = temp_ptr->next_;
199 // Explicitly call the destructor.
200 ACE_DES_FREE_TEMPLATE2 (hold_ptr, this->entry_allocator_->free,
201 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
204 // Restore the sentinel.
205 this->table_[i].next_ = &this->table_[i];
206 this->table_[i].prev_ = &this->table_[i];
209 this->cur_size_ = 0;
211 return 0;
214 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
215 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
216 const INT_ID &int_id,
217 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
219 size_t loc;
220 int result = this->shared_find (ext_id, entry, loc);
222 ACE_Unbounded_Set<INT_ID> int_id_set;
223 if (result == -1)
225 void *ptr;
226 // Not found.
227 ACE_ALLOCATOR_RETURN (ptr,
228 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
229 -1);
231 int_id_set.insert (int_id);
233 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
234 int_id_set,
235 this->table_[loc].next_,
236 &this->table_[loc]);
237 this->table_[loc].next_ = entry;
238 entry->next_->prev_ = entry;
239 this->cur_size_++;
240 return 0;
242 else
244 int_id_set = (*entry).int_id_set_;
246 if (0 == int_id_set.insert (int_id))
248 this->unbind_i (entry);
249 return this->bind_i (ext_id, int_id_set);
251 else
252 return 1;
256 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
257 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
258 const ACE_Unbounded_Set<INT_ID> &int_id_set,
259 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
261 size_t loc;
262 int result = this->shared_find (ext_id, entry, loc);
264 if (result == -1)
266 void *ptr;
267 // Not found.
268 ACE_ALLOCATOR_RETURN (ptr,
269 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
270 -1);
272 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
273 int_id_set,
274 this->table_[loc].next_,
275 &this->table_[loc]);
276 this->table_[loc].next_ = entry;
277 entry->next_->prev_ = entry;
278 this->cur_size_++;
279 return 0;
281 else
282 return 1;
285 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
286 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
287 ACE_Unbounded_Set<INT_ID> &int_id_set,
288 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
290 size_t loc;
291 int result = this->shared_find (ext_id, entry, loc);
293 if (result == -1)
295 // Not found.
296 void *ptr;
297 ACE_ALLOCATOR_RETURN (ptr,
298 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
299 -1);
301 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
302 int_id_set,
303 this->table_[loc].next_,
304 &this->table_[loc]);
305 this->table_[loc].next_ = entry;
306 entry->next_->prev_ = entry;
307 this->cur_size_++;
308 return 0;
310 else
311 return 1;
314 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
315 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
316 ACE_Unbounded_Set<INT_ID> &int_id_set)
318 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp;
320 size_t loc;
321 int result = this->shared_find (ext_id, temp, loc);
323 if (result == -1)
325 errno = ENOENT;
326 return -1;
329 int_id_set = temp->int_id_set_;
331 return this->unbind_i (temp);
334 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
335 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *entry)
337 entry->next_->prev_ = entry->prev_;
338 entry->prev_->next_ = entry->next_;
340 // Explicitly call the destructor.
341 ACE_DES_FREE_TEMPLATE2 (entry, this->entry_allocator_->free,
342 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
344 this->cur_size_--;
345 return 0;
348 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
349 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
350 const INT_ID &int_id)
352 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp;
354 size_t loc;
355 int result = this->shared_find (ext_id, temp, loc);
357 if (result == -1)
359 errno = ENOENT;
360 return -1;
363 ACE_Unbounded_Set<INT_ID> int_id_set = (*temp).int_id_set_;
364 if (0 == int_id_set.remove (int_id))
366 this->unbind_i (temp);
368 if (0 != int_id_set.size ())
369 return this->bind_i (ext_id, int_id_set);
370 else
371 return 0;
373 else
374 return -1;
378 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
379 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
380 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry,
381 size_t &loc)
383 loc = this->hash (ext_id) % this->total_size_;
385 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc].next_;
387 while (temp != &this->table_[loc] && this->equal (temp->ext_id_, ext_id) == 0)
388 temp = temp->next_;
390 if (temp == &this->table_[loc])
392 errno = ENOENT;
393 return -1;
395 else
397 entry = temp;
398 return 0;
402 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
403 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
404 const ACE_Unbounded_Set<INT_ID> &int_id_set,
405 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
407 size_t dummy;
408 if (this->shared_find (ext_id, entry, dummy) == -1)
409 return this->bind_i (ext_id, int_id_set);
410 else
412 entry->ext_id_ = ext_id;
413 entry->int_id_set_ = int_id_set;
414 return 1;
418 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
419 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
420 const ACE_Unbounded_Set<INT_ID> &int_id_set,
421 ACE_Unbounded_Set<INT_ID> &old_int_id_set,
422 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
424 size_t dummy;
425 if (this->shared_find (ext_id, entry, dummy) == -1)
426 return this->bind_i (ext_id, int_id_set);
427 else
429 old_int_id_set = entry->int_id_set_;
430 entry->ext_id_ = ext_id;
431 entry->int_id_set_ = int_id_set;
432 return 1;
436 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
437 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
438 const ACE_Unbounded_Set<INT_ID> &int_id_set,
439 EXT_ID &old_ext_id,
440 ACE_Unbounded_Set<INT_ID> &old_int_id_set,
441 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
443 size_t dummy;
444 if (this->shared_find (ext_id, entry, dummy) == -1)
445 return this->bind_i (ext_id, int_id_set);
446 else
448 old_ext_id = entry->ext_id_;
449 old_int_id_set = entry->int_id_set_;
450 entry->ext_id_ = ext_id;
451 entry->int_id_set_ = int_id_set;
452 return 1;
456 // ------------------------------------------------------------
458 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
459 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i (void) const
461 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
463 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
464 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
465 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
466 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
469 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
470 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i (void)
472 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
474 if (this->map_man_->table_ == 0)
475 return -1;
476 // Handle initial case specially.
477 else if (this->index_ == -1)
479 this->index_++;
480 return this->forward_i ();
482 else if (this->index_ >= static_cast<ssize_t> (this->map_man_->total_size_))
483 return 0;
485 this->next_ = this->next_->next_;
486 if (this->next_ == &this->map_man_->table_[this->index_])
488 while (++this->index_ < static_cast<ssize_t> (this->map_man_->total_size_))
490 this->next_ = this->map_man_->table_[this->index_].next_;
491 if (this->next_ != &this->map_man_->table_[this->index_])
492 break;
496 return this->index_ < static_cast<ssize_t> (this->map_man_->total_size_);
499 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
500 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i (void)
502 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
504 if (this->map_man_->table_ == 0)
505 return -1;
506 else if (this->index_ == static_cast<ssize_t> (this->map_man_->total_size_))
508 this->index_--;
509 return this->reverse_i ();
511 else if (this->index_ < 0)
512 return 0;
514 this->next_ = this->next_->prev_;
515 if (this->next_ == &this->map_man_->table_[this->index_])
517 while (--this->index_ >= 0)
519 this->next_ = this->map_man_->table_[this->index_].prev_;
520 if (this->next_ != &this->map_man_->table_[this->index_])
521 break;
525 return this->index_ >= 0;
528 // ------------------------------------------------------------
530 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
531 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i (void) const
533 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
535 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
536 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
537 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
538 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
541 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
542 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i (void)
544 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
546 if (this->map_man_->table_ == 0)
547 return -1;
548 // Handle initial case specially.
549 else if (this->index_ == -1)
551 this->index_++;
552 return this->forward_i ();
554 else if (this->index_ >= (ssize_t) this->map_man_->total_size_)
555 return 0;
557 this->next_ = this->next_->next_;
558 if (this->next_ == &this->map_man_->table_[this->index_])
560 while (++this->index_ < (ssize_t) this->map_man_->total_size_)
562 this->next_ = this->map_man_->table_[this->index_].next_;
563 if (this->next_ != &this->map_man_->table_[this->index_])
564 break;
568 return this->index_ < (ssize_t) this->map_man_->total_size_;
571 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
572 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i (void)
574 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
576 if (this->map_man_->table_ == 0)
577 return -1;
578 else if (this->index_ == (ssize_t) this->map_man_->total_size_)
580 this->index_--;
581 return this->reverse_i ();
583 else if (this->index_ < 0)
584 return 0;
586 this->next_ = this->next_->prev_;
587 if (this->next_ == &this->map_man_->table_[this->index_])
589 while (--this->index_ >= 0)
591 this->next_ = this->map_man_->table_[this->index_].prev_;
592 if (this->next_ != &this->map_man_->table_[this->index_])
593 break;
597 return this->index_ >= 0;
600 ACE_END_VERSIONED_NAMESPACE_DECL
602 #endif /* ACE_Hash_Multi_Map_Manager_T_CPP */