Fix search in wxSortedArrayString with custom compare function
This commit is contained in:
@@ -398,6 +398,9 @@ private:
|
|||||||
// (if the old buffer is big enough, just return NULL).
|
// (if the old buffer is big enough, just return NULL).
|
||||||
wxString *Grow(size_t nIncrement);
|
wxString *Grow(size_t nIncrement);
|
||||||
|
|
||||||
|
// Binary search in the sorted array
|
||||||
|
size_t BinarySearch(const wxString& str, bool equal = false) const;
|
||||||
|
|
||||||
size_t m_nSize, // current size of the array
|
size_t m_nSize, // current size of the array
|
||||||
m_nCount; // current number of elements
|
m_nCount; // current number of elements
|
||||||
|
|
||||||
|
@@ -377,14 +377,9 @@ void wxArrayString::Shrink()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// searches the array for an item (forward or backwards)
|
// Binary search in the sorted array
|
||||||
int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const
|
size_t wxArrayString::BinarySearch(const wxString& str, bool equal) const
|
||||||
{
|
{
|
||||||
if ( m_autoSort ) {
|
|
||||||
// use binary search in the sorted array
|
|
||||||
wxASSERT_MSG( bCase && !bFromEnd,
|
|
||||||
wxT("search parameters ignored for auto sorted array") );
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
lo = 0,
|
lo = 0,
|
||||||
hi = m_nCount;
|
hi = m_nCount;
|
||||||
@@ -393,7 +388,7 @@ int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const
|
|||||||
i = (lo + hi) / 2;
|
i = (lo + hi) / 2;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
res = str.compare(m_pItems[i]);
|
res = m_compareFunction ? m_compareFunction(str, m_pItems[i]) : str.Cmp(m_pItems[i]);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
hi = i;
|
hi = i;
|
||||||
else if (res > 0)
|
else if (res > 0)
|
||||||
@@ -401,8 +396,18 @@ int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const
|
|||||||
else
|
else
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
wxASSERT_MSG(lo == hi, wxT("binary search broken"));
|
||||||
|
return equal ? wxNOT_FOUND : lo;
|
||||||
|
}
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
// searches the array for an item (forward or backwards)
|
||||||
|
int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const
|
||||||
|
{
|
||||||
|
if ( m_autoSort ) {
|
||||||
|
// use binary search in the sorted array
|
||||||
|
wxASSERT_MSG( bCase && !bFromEnd,
|
||||||
|
wxT("search parameters ignored for auto sorted array") );
|
||||||
|
return BinarySearch(str, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// use linear search in unsorted array
|
// use linear search in unsorted array
|
||||||
@@ -432,30 +437,9 @@ size_t wxArrayString::Add(const wxString& str, size_t nInsert)
|
|||||||
{
|
{
|
||||||
if ( m_autoSort ) {
|
if ( m_autoSort ) {
|
||||||
// insert the string at the correct position to keep the array sorted
|
// insert the string at the correct position to keep the array sorted
|
||||||
size_t
|
size_t nIndex = BinarySearch(str);
|
||||||
lo = 0,
|
Insert(str, nIndex, nInsert);
|
||||||
hi = m_nCount;
|
return nIndex;
|
||||||
while ( lo < hi ) {
|
|
||||||
size_t i;
|
|
||||||
i = (lo + hi)/2;
|
|
||||||
|
|
||||||
int res;
|
|
||||||
res = m_compareFunction ? m_compareFunction(str, m_pItems[i]) : str.Cmp(m_pItems[i]);
|
|
||||||
if ( res < 0 )
|
|
||||||
hi = i;
|
|
||||||
else if ( res > 0 )
|
|
||||||
lo = i + 1;
|
|
||||||
else {
|
|
||||||
lo = hi = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT_MSG( lo == hi, wxT("binary search broken") );
|
|
||||||
|
|
||||||
Insert(str, lo, nInsert);
|
|
||||||
|
|
||||||
return (size_t)lo;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Now that we must postpone freeing the old memory until we don't need it
|
// Now that we must postpone freeing the old memory until we don't need it
|
||||||
|
@@ -399,6 +399,11 @@ void ArraysTestCase::SortedArray()
|
|||||||
ad.Add("Aa");
|
ad.Add("Aa");
|
||||||
CPPUNIT_ASSERT_EQUAL( "a", ad[0] );
|
CPPUNIT_ASSERT_EQUAL( "a", ad[0] );
|
||||||
CPPUNIT_ASSERT_EQUAL( "Aa", ad[1] );
|
CPPUNIT_ASSERT_EQUAL( "Aa", ad[1] );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 0, ad.Index("a") );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 1, ad.Index("Aa") );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 2, ad.Index("AB") );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("A") );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("z") );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArraysTestCase::wxStringArraySplitTest()
|
void ArraysTestCase::wxStringArraySplitTest()
|
||||||
|
Reference in New Issue
Block a user