diff options
-rw-r--r-- | ChangeLog | 40 | ||||
-rw-r--r-- | ace/Array_Map.cpp | 135 | ||||
-rw-r--r-- | ace/Array_Map.h | 15 | ||||
-rw-r--r-- | ace/Array_Map.inl | 95 | ||||
-rw-r--r-- | ace/Refcountable.cpp | 13 | ||||
-rw-r--r-- | ace/Refcountable.inl | 5 | ||||
-rw-r--r-- | ace/config-lite.h | 4 | ||||
-rw-r--r-- | tests/Array_Map_Test.cpp | 115 |
8 files changed, 296 insertions, 126 deletions
diff --git a/ChangeLog b/ChangeLog index 80a0a2af62d..f2ebb247a35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +Thu Jul 28 00:28:46 2005 Ossama Othman <ossama@dre.vanderbilt.edu> + + * ace/Array_Map.cpp: + * ace/Array_Map.h: + * ace/Array_Map.inl: + + Added third equality functor template parameter. Defaults to + std::equal_to<> if unspecified. Necessary for cases where + operator==() is not suitable or available for a given key type. + + (erase): + + Explicitly destroy the tail element by assigning a default + constructed value_type instance to it. Prevents duplicate + instances of erase()d elements from existing. Some applications + may assume that erased elements no longer exist. This + essentially disables the lazy destruction behavior of + ACE_Array_Map. Note that this change also applies to the case + of a map of size 1. + + * ace/Refcountable.cpp: + * ace/Refcountable.inl: + + Moved ~ACE_Refcountable() virtual destructor out of line. + Addresses RTTI issues when g++ 4.0 hidden visibility of inlined + functions is enabled. + + * ace/config-lite.h: + + Disable use of ACE_RCSIDs by default. Most users never need to + determine the RCS ID of a given object file in an ACE-based + binary so optimize for the common case. Also reduces + footprint. + + * tests/Array_Map_Test.cpp: + + Added reference count test to verify that the number of + references/copies of a given data element drop by the same + amount as was increased during insertion. + Wed Jul 27 16:33:46 2005 Gary Maxey <gary.maxey@hp.com> * ace/config-tandem-nsk-mips-v3.h: diff --git a/ace/Array_Map.cpp b/ace/Array_Map.cpp index 008de606c28..01fbf4cdcae 100644 --- a/ace/Array_Map.cpp +++ b/ace/Array_Map.cpp @@ -10,13 +10,13 @@ #endif /* !__ACE_INLINE__ */ #include <algorithm> -#include <functional> #ifndef ACE_LACKS_MEMBER_TEMPLATES -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> template<typename InputIterator> -ACE_Array_Map<Key, Value>::ACE_Array_Map (InputIterator f, InputIterator l) +ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map (InputIterator f, + InputIterator l) : size_ (l - f) , capacity_ (size_) , nodes_ (size_ == 0 ? 0 : new value_type[size_]) @@ -29,10 +29,10 @@ ACE_Array_Map<Key, Value>::ACE_Array_Map (InputIterator f, InputIterator l) // *n = *i; } #else -template<typename Key, typename Value> -ACE_Array_Map<Key, Value>::ACE_Array_Map ( - typename ACE_Array_Map<Key, Value>::const_iterator f, - typename ACE_Array_Map<Key, Value>::const_iterator l) +template<typename Key, typename Value, class EqualTo> +ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map ( + typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator f, + typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator l) : size_ (l - f) , capacity_ (size_) , nodes_ (size_ == 0 ? 0 : new value_type[size_]) @@ -46,9 +46,9 @@ ACE_Array_Map<Key, Value>::ACE_Array_Map ( } #endif /* !ACE_LACKS_MEMBER_TEMPLATES */ -template<typename Key, typename Value> -ACE_Array_Map<Key, Value>::ACE_Array_Map ( - ACE_Array_Map<Key, Value> const & map) +template<typename Key, typename Value, class EqualTo> +ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map ( + ACE_Array_Map<Key, Value, EqualTo> const & map) : size_ (map.size_) , capacity_ (map.size_) , nodes_ (size_ == 0 ? 0 : new value_type[size_]) @@ -63,30 +63,31 @@ ACE_Array_Map<Key, Value>::ACE_Array_Map ( // *n = *i; } -template<typename Key, typename Value> -ACE_Array_Map<Key, Value>::~ACE_Array_Map (void) +template<typename Key, typename Value, class EqualTo> +ACE_Array_Map<Key, Value, EqualTo>::~ACE_Array_Map (void) { delete[] this->nodes_; } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::swap (ACE_Array_Map<Key, Value> & map) +ACE_Array_Map<Key, Value, EqualTo>::swap ( + ACE_Array_Map<Key, Value, EqualTo> & map) { std::swap (this->size_, map.size_); std::swap (this->capacity_, map.capacity_); std::swap (this->nodes_, map.nodes_); } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> #if defined (_MSC_VER) && (_MSC_VER <= 1200) // MSVC++ 6 doesn't like the typename qualification. -std::pair<ACE_Array_Map<Key, Value>::iterator, bool> +std::pair<ACE_Array_Map<Key, Value, EqualTo>::iterator, bool> #else -std::pair<typename ACE_Array_Map<Key, Value>::iterator, bool> +std::pair<typename ACE_Array_Map<Key, Value, EqualTo>::iterator, bool> #endif /* _MSC_VER <= 1200 */ -ACE_Array_Map<Key, Value>::insert ( - typename ACE_Array_Map<Key, Value>::value_type const & x) +ACE_Array_Map<Key, Value, EqualTo>::insert ( + typename ACE_Array_Map<Key, Value, EqualTo>::value_type const & x) { // Linear insertion due to linear duplicate key search. @@ -112,10 +113,10 @@ ACE_Array_Map<Key, Value>::insert ( } #ifndef ACE_LACKS_MEMBER_TEMPLATES -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> template<typename InputIterator> void -ACE_Array_Map<Key, Value>::insert (InputIterator f, InputIterator l) +ACE_Array_Map<Key, Value, EqualTo>::insert (InputIterator f, InputIterator l) { this->grow (l - f); // Preallocate storage. @@ -125,11 +126,11 @@ ACE_Array_Map<Key, Value>::insert (InputIterator f, InputIterator l) } } #else -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::insert ( - typename ACE_Array_Map<Key, Value>::const_iterator f, - typename ACE_Array_Map<Key, Value>::const_iterator l) +ACE_Array_Map<Key, Value, EqualTo>::insert ( + typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator f, + typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator l) { this->grow (l - f); // Preallocate storage. @@ -140,27 +141,37 @@ ACE_Array_Map<Key, Value>::insert ( } #endif /* ACE_LACKS_MEMBER_TEMPLATES */ -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::erase ( - typename ACE_Array_Map<Key, Value>::iterator pos) +ACE_Array_Map<Key, Value, EqualTo>::erase ( + typename ACE_Array_Map<Key, Value, EqualTo>::iterator pos) { iterator const first = this->begin (); iterator const last = this->end (); if (pos >= first && pos < last) { - if (this->size_ > 1 && pos < last - 1) - *pos = *(last - 1); + if (pos != last - 1) + { + // Relocate the tail element to the location of the erased + // element to prevent introduction of "holes" in the + // underlying array. + *pos = *(last - 1); + } + + // Explicitly destroy the tail element by assigning a default + // constructed instance to it. Note that this also works for + // the case of a map of size 1. + *(last - 1) = value_type (); --this->size_; } } -template<typename Key, typename Value> -typename ACE_Array_Map<Key, Value>::size_type -ACE_Array_Map<Key, Value>::erase ( - typename ACE_Array_Map<Key, Value>::key_type const & k) +template<typename Key, typename Value, class EqualTo> +typename ACE_Array_Map<Key, Value, EqualTo>::size_type +ACE_Array_Map<Key, Value, EqualTo>::erase ( + typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) { iterator pos = this->find (k); @@ -171,56 +182,60 @@ ACE_Array_Map<Key, Value>::erase ( return old_size - this->size_; } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::erase ( - typename ACE_Array_Map<Key, Value>::iterator first, - typename ACE_Array_Map<Key, Value>::iterator last) +ACE_Array_Map<Key, Value, EqualTo>::erase ( + typename ACE_Array_Map<Key, Value, EqualTo>::iterator first, + typename ACE_Array_Map<Key, Value, EqualTo>::iterator last) { if (this->begin () <= first && first < last && last < this->end ()) for (iterator i = first; i != last; ++i) this->erase (i); } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::clear (void) +ACE_Array_Map<Key, Value, EqualTo>::clear (void) { this->size_ = 0; // No need to deallocate array nor destroy elements. } -template<typename Key, typename Value> -typename ACE_Array_Map<Key, Value>::iterator -ACE_Array_Map<Key, Value>::find ( - typename ACE_Array_Map<Key, Value>::key_type const & k) +template<typename Key, typename Value, class EqualTo> +typename ACE_Array_Map<Key, Value, EqualTo>::iterator +ACE_Array_Map<Key, Value, EqualTo>::find ( + typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) { iterator const the_end = this->end (); + EqualTo eq; + for (iterator i = this->begin (); i != the_end; ++i) - if (k == i->first) + if (eq (k, i->first)) return i; return this->end (); } -template<typename Key, typename Value> -typename ACE_Array_Map<Key, Value>::const_iterator -ACE_Array_Map<Key, Value>::find ( - typename ACE_Array_Map<Key, Value>::key_type const & k) const +template<typename Key, typename Value, class EqualTo> +typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator +ACE_Array_Map<Key, Value, EqualTo>::find ( + typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) const { const_iterator const the_end = this->end (); + EqualTo eq; + for (const_iterator i = this->begin (); i != the_end; ++i) - if (k == i->first) + if (eq (k, i->first)) return i; return this->end (); } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> void -ACE_Array_Map<Key, Value>::grow ( - typename ACE_Array_Map<Key, Value>::size_type s) +ACE_Array_Map<Key, Value, EqualTo>::grow ( + typename ACE_Array_Map<Key, Value, EqualTo>::size_type s) { if (this->size () + s > this->capacity_) { @@ -229,7 +244,7 @@ ACE_Array_Map<Key, Value>::grow ( // Strongly exception safe. - ACE_Array_Map<Key, Value> temp (this->size () + s); + ACE_Array_Map<Key, Value, EqualTo> temp (this->size () + s); std::copy (this->begin (), this->end (), temp.begin ()); @@ -245,10 +260,10 @@ ACE_Array_Map<Key, Value>::grow ( // --------------------------------------------------------------- -template <typename Key, typename Value> +template <typename Key, typename Value, class EqualTo> bool -operator== (ACE_Array_Map<Key, Value> const & lhs, - ACE_Array_Map<Key, Value> const & rhs) +operator== (ACE_Array_Map<Key, Value, EqualTo> const & lhs, + ACE_Array_Map<Key, Value, EqualTo> const & rhs) { // Do not include Array_Map capacity in comparison. It isn't useful // in this case. @@ -257,10 +272,10 @@ operator== (ACE_Array_Map<Key, Value> const & lhs, && std::equal (lhs.begin (), lhs.end (), rhs.begin ())); } -template <typename Key, typename Value> +template <typename Key, typename Value, class EqualTo> bool -operator< (ACE_Array_Map<Key, Value> const & lhs, - ACE_Array_Map<Key, Value> const & rhs) +operator< (ACE_Array_Map<Key, Value, EqualTo> const & lhs, + ACE_Array_Map<Key, Value, EqualTo> const & rhs) { return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (), rhs.end ()); diff --git a/ace/Array_Map.h b/ace/Array_Map.h index b5e8d8d927a..1d5b0c1977c 100644 --- a/ace/Array_Map.h +++ b/ace/Array_Map.h @@ -30,6 +30,7 @@ #include <utility> #include <iterator> +#include <functional> /** @@ -82,7 +83,7 @@ * -# Copy constructor * -# operator= */ -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo = std::equal_to<Key> > class ACE_Array_Map { public: @@ -283,14 +284,14 @@ private: // -------------------------------------------------------------- /// @c ACE_Array_Map equality operator. -template <typename Key, typename Value> -bool operator== (ACE_Array_Map<Key, Value> const & lhs, - ACE_Array_Map<Key, Value> const & rhs); +template <typename Key, typename Value, class EqualTo> +bool operator== (ACE_Array_Map<Key, Value, EqualTo> const & lhs, + ACE_Array_Map<Key, Value, EqualTo> const & rhs); /// @c ACE_Array_Map lexicographical comparison operator. -template <typename Key, typename Value> -bool operator< (ACE_Array_Map<Key, Value> const & lhs, - ACE_Array_Map<Key, Value> const & rhs); +template <typename Key, typename Value, class EqualTo> +bool operator< (ACE_Array_Map<Key, Value, EqualTo> const & lhs, + ACE_Array_Map<Key, Value, EqualTo> const & rhs); // -------------------------------------------------------------- diff --git a/ace/Array_Map.inl b/ace/Array_Map.inl index 9a84d945ae2..26ad1da1fca 100644 --- a/ace/Array_Map.inl +++ b/ace/Array_Map.inl @@ -2,117 +2,118 @@ // // $Id$ -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> ACE_INLINE -ACE_Array_Map<Key, Value>::ACE_Array_Map ( - typename ACE_Array_Map<Key, Value>::size_type s) +ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map ( + typename ACE_Array_Map<Key, Value, EqualTo>::size_type s) : size_ (0) , capacity_ (s) , nodes_ (s == 0 ? 0 : new value_type[s]) { } -template<typename Key, typename Value> -ACE_INLINE ACE_Array_Map<Key, Value> & -ACE_Array_Map<Key, Value>::operator= (ACE_Array_Map<Key, Value> const & map) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE ACE_Array_Map<Key, Value, EqualTo> & +ACE_Array_Map<Key, Value, EqualTo>::operator= ( + ACE_Array_Map<Key, Value, EqualTo> const & map) { // Strongly exception-safe assignment. - ACE_Array_Map<Key, Value> temp (map); + ACE_Array_Map<Key, Value, EqualTo> temp (map); this->swap (temp); return *this; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::iterator -ACE_Array_Map<Key, Value>::begin (void) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::iterator +ACE_Array_Map<Key, Value, EqualTo>::begin (void) { return this->nodes_; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::iterator -ACE_Array_Map<Key, Value>::end (void) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::iterator +ACE_Array_Map<Key, Value, EqualTo>::end (void) { return this->nodes_ + this->size_; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::const_iterator -ACE_Array_Map<Key, Value>::begin (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator +ACE_Array_Map<Key, Value, EqualTo>::begin (void) const { return this->nodes_; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::const_iterator -ACE_Array_Map<Key, Value>::end (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator +ACE_Array_Map<Key, Value, EqualTo>::end (void) const { return this->nodes_ + this->size_; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::reverse_iterator -ACE_Array_Map<Key, Value>::rbegin (void) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::reverse_iterator +ACE_Array_Map<Key, Value, EqualTo>::rbegin (void) { return reverse_iterator (this->end ()); } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::reverse_iterator -ACE_Array_Map<Key, Value>::rend (void) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::reverse_iterator +ACE_Array_Map<Key, Value, EqualTo>::rend (void) { return reverse_iterator (this->begin ()); } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::const_reverse_iterator -ACE_Array_Map<Key, Value>::rbegin (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_reverse_iterator +ACE_Array_Map<Key, Value, EqualTo>::rbegin (void) const { return const_reverse_iterator (this->end ()); } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::const_reverse_iterator -ACE_Array_Map<Key, Value>::rend (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_reverse_iterator +ACE_Array_Map<Key, Value, EqualTo>::rend (void) const { return const_reverse_iterator (this->begin ()); } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::size_type -ACE_Array_Map<Key, Value>::size (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type +ACE_Array_Map<Key, Value, EqualTo>::size (void) const { return this->size_; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::size_type -ACE_Array_Map<Key, Value>::max_size (void) const +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type +ACE_Array_Map<Key, Value, EqualTo>::max_size (void) const { return size_type (-1) / sizeof (value_type); } -template<typename Key, typename Value> +template<typename Key, typename Value, class EqualTo> ACE_INLINE bool -ACE_Array_Map<Key, Value>::empty (void) const +ACE_Array_Map<Key, Value, EqualTo>::empty (void) const { return this->size_ == 0; } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::size_type -ACE_Array_Map<Key, Value>::count ( - typename ACE_Array_Map<Key, Value>::key_type const & k) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type +ACE_Array_Map<Key, Value, EqualTo>::count ( + typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) { return (this->find (k) == this->end () ? 0 : 1); // Only one datum per key. } -template<typename Key, typename Value> -ACE_INLINE typename ACE_Array_Map<Key, Value>::data_type & -ACE_Array_Map<Key, Value>::operator[] ( - typename ACE_Array_Map<Key, Value>::key_type const & k) +template<typename Key, typename Value, class EqualTo> +ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::data_type & +ACE_Array_Map<Key, Value, EqualTo>::operator[] ( + typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) { return (*((this->insert (value_type (k, data_type ()))).first)).second; } diff --git a/ace/Refcountable.cpp b/ace/Refcountable.cpp index 19c95cb990a..0c77633f4d1 100644 --- a/ace/Refcountable.cpp +++ b/ace/Refcountable.cpp @@ -1,8 +1,17 @@ -//$Id$ +// $Id$ + #include "ace/Refcountable.h" #if !defined (__ACE_INLINE__) #include "ace/Refcountable.inl" #endif /* __ACE_INLINE __ */ -ACE_RCSID(ace, Refcountable, "$Id$") + +ACE_RCSID (ace, + Refcountable, + "$Id$") + + +ACE_Refcountable::~ACE_Refcountable (void) +{ +} diff --git a/ace/Refcountable.inl b/ace/Refcountable.inl index e36d0992705..1d9a03fb66a 100644 --- a/ace/Refcountable.inl +++ b/ace/Refcountable.inl @@ -6,11 +6,6 @@ ACE_Refcountable::ACE_Refcountable (int refcount) { } -ACE_INLINE -ACE_Refcountable::~ACE_Refcountable (void) -{ -} - ACE_INLINE int ACE_Refcountable::increment (void) { diff --git a/ace/config-lite.h b/ace/config-lite.h index 9ff87619ce7..abe7440b607 100644 --- a/ace/config-lite.h +++ b/ace/config-lite.h @@ -146,9 +146,9 @@ // RCSID Macros // ========================================================================= -// By default, DO include RCS Id strings in object code. +// By default, DO NOT include RCS Id strings in object code. #if ! defined (ACE_USE_RCSID) -# define ACE_USE_RCSID 1 +# define ACE_USE_RCSID 0 #endif /* #if ! defined (ACE_USE_RCSID) */ #if (defined (ACE_USE_RCSID) && (ACE_USE_RCSID != 0)) diff --git a/tests/Array_Map_Test.cpp b/tests/Array_Map_Test.cpp index ac6a850b9ad..2a2e17dcf60 100644 --- a/tests/Array_Map_Test.cpp +++ b/tests/Array_Map_Test.cpp @@ -16,6 +16,7 @@ #include "ace/SString.h" #include "ace/Array_Map.h" +#include <algorithm> //#include <map> /* For STL portability testing. */ @@ -303,10 +304,10 @@ index_operator_test (void) const_reverse_iterator const rlast = const_phonetic.rend (); for (const_reverse_iterator r = const_phonetic.rbegin (); - r != rlast; + !(r == rlast); // Sun C++ Forte doesn't support operator!= ++r, --letter, --word) { - if ((*r).first != *letter || (*r).second != *word) + if ((*r).first != *letter || (*r).second != *word) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Key/Datum mismatch:\n" " key \"%c\" should be \"%c\"\n" @@ -340,6 +341,113 @@ index_operator_test (void) // -------------------------------------------------------------- +class RefCounted +{ +public: + + RefCounted (void) + : refcount_ (0) + { + } + + RefCounted (unsigned int * count) + : refcount_ (count) + { + } + + ~RefCounted (void) + { + if (this->refcount_) + --(*this->refcount_); + } + + RefCounted (RefCounted const & r) + : refcount_ (r.refcount_ptr ()) + { + if (this->refcount_) + ++(*this->refcount_); + } + + RefCounted & + operator= (RefCounted const & r) + { + RefCounted tmp (r); + std::swap (this->refcount_, tmp.refcount_); + + return *this; + } + + unsigned int * + refcount_ptr (void) const + { + return this->refcount_; + } + + unsigned int + refcount (void) const + { + return *this->refcount_; + } + +private: + + unsigned int * refcount_; + +}; + +// -------- + +bool +reference_count_test (void) +{ + typedef ACE_Array_Map<ACE_TString, RefCounted> Map; + + static Map::size_type const CAPACITY = 30; + + unsigned int ref_count = 1; + + RefCounted counted (&ref_count); + + ACE_ASSERT (counted.refcount () == 1); + + { + Map map (CAPACITY); // Preallocate storage for a number of + // elements even if they are not used to test + // some internals. + + map[ACE_TEXT("One")] = counted; + + ACE_ASSERT (counted.refcount () == 2); + + map.insert (std::make_pair (ACE_TString (ACE_TEXT ("Two")), + counted)); + + ACE_ASSERT (counted.refcount () == 3); + + map.insert (std::make_pair (ACE_TString (ACE_TEXT ("Three")), + counted)); + + ACE_ASSERT (counted.refcount () == 4); + + Map::size_type const erased = map.erase (ACE_TEXT ("One")); + + ACE_ASSERT (erased == 1); + ACE_ASSERT (counted.refcount () == 3); + } + + // Map instance no longer contains any references to the "counted" + // object so the reference count should be back to one. + + ACE_ASSERT (counted.refcount () == 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Reference count test passed.\n"))); + + return true; +} + +// -------------------------------------------------------------- + int run_main (int, ACE_TCHAR *[]) { @@ -349,7 +457,8 @@ run_main (int, ACE_TCHAR *[]) bool const success = ::insertion_removal_test () - && ::index_operator_test (); + && ::index_operator_test () + && ::reference_count_test (); ACE_END_TEST; |