use std::sort() instead of qsort() to implement wxArrayString::Sort(), this makes it thread-safe without any extra hacks and also makes the code simpler
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55317 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -15,9 +15,6 @@
|
|||||||
#include "wx/defs.h"
|
#include "wx/defs.h"
|
||||||
#include "wx/string.h"
|
#include "wx/string.h"
|
||||||
|
|
||||||
WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortAscending(wxString*, wxString*);
|
|
||||||
WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortDescending(wxString*, wxString*);
|
|
||||||
|
|
||||||
#if wxUSE_STL
|
#if wxUSE_STL
|
||||||
|
|
||||||
#include "wx/dynarray.h"
|
#include "wx/dynarray.h"
|
||||||
@@ -177,7 +174,7 @@ public:
|
|||||||
// sort array elements in alphabetical order (or reversed alphabetical
|
// sort array elements in alphabetical order (or reversed alphabetical
|
||||||
// order if reverseOrder parameter is true)
|
// order if reverseOrder parameter is true)
|
||||||
void Sort(bool reverseOrder = false);
|
void Sort(bool reverseOrder = false);
|
||||||
// sort array elements using specified comparaison function
|
// sort array elements using specified comparison function
|
||||||
void Sort(CompareFunction compareFunction);
|
void Sort(CompareFunction compareFunction);
|
||||||
void Sort(CompareFunction2 compareFunction);
|
void Sort(CompareFunction2 compareFunction);
|
||||||
|
|
||||||
@@ -299,8 +296,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void Grow(size_t nIncrement = 0); // makes array bigger if needed
|
void Grow(size_t nIncrement = 0); // makes array bigger if needed
|
||||||
|
|
||||||
void DoSort(); // common part of all Sort() variants
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
@@ -21,7 +21,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/arrstr.h"
|
#include "wx/arrstr.h"
|
||||||
#include "wx/thread.h"
|
|
||||||
|
#include "wx/beforestd.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include "wx/afterstd.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ArrayString
|
// ArrayString
|
||||||
@@ -138,7 +142,7 @@ void wxArrayString::Grow(size_t nIncrement)
|
|||||||
pNew[j] = m_pItems[j];
|
pNew[j] = m_pItems[j];
|
||||||
|
|
||||||
// delete old memory (but do not release the strings!)
|
// delete old memory (but do not release the strings!)
|
||||||
wxDELETEA(m_pItems);
|
delete [] m_pItems;
|
||||||
|
|
||||||
m_pItems = pNew;
|
m_pItems = pNew;
|
||||||
}
|
}
|
||||||
@@ -163,7 +167,7 @@ void wxArrayString::Clear()
|
|||||||
// dtor
|
// dtor
|
||||||
wxArrayString::~wxArrayString()
|
wxArrayString::~wxArrayString()
|
||||||
{
|
{
|
||||||
wxDELETEA(m_pItems);
|
delete [] m_pItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxArrayString::reserve(size_t nSize)
|
void wxArrayString::reserve(size_t nSize)
|
||||||
@@ -385,74 +389,61 @@ void wxArrayString::assign(const_iterator first, const_iterator last)
|
|||||||
// sorting
|
// sorting
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// we can only sort one array at a time with the quick-sort based
|
// we need an adaptor as our predicates use qsort() convention and so return
|
||||||
// implementation
|
// negative, null or positive value depending on whether the first item is less
|
||||||
#if wxUSE_THREADS
|
// than, equal to or greater than the other one while we need a real boolean
|
||||||
// need a critical section to protect access to gs_compareFunction and
|
// predicate now that we use std::sort()
|
||||||
// gs_sortAscending variables
|
struct wxSortPredicateAdaptor
|
||||||
static wxCriticalSection gs_critsectStringSort;
|
|
||||||
#endif // wxUSE_THREADS
|
|
||||||
|
|
||||||
// function to use for string comparaison
|
|
||||||
static wxArrayString::CompareFunction gs_compareFunction = NULL;
|
|
||||||
|
|
||||||
// if we don't use the compare function, this flag tells us if we sort the
|
|
||||||
// array in ascending or descending order
|
|
||||||
static bool gs_sortAscending = true;
|
|
||||||
|
|
||||||
// function which is called by quick sort
|
|
||||||
extern "C" int wxC_CALLING_CONV // LINKAGEMODE
|
|
||||||
wxStringCompareFunction(const void *first, const void *second)
|
|
||||||
{
|
{
|
||||||
wxString *strFirst = (wxString *)first;
|
wxSortPredicateAdaptor(wxArrayString::CompareFunction compareFunction)
|
||||||
wxString *strSecond = (wxString *)second;
|
: m_compareFunction(compareFunction)
|
||||||
|
{
|
||||||
if ( gs_compareFunction ) {
|
|
||||||
return gs_compareFunction(*strFirst, *strSecond);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// maybe we should use wxStrcoll
|
|
||||||
int result = strFirst->Cmp(*strSecond);
|
|
||||||
|
|
||||||
return gs_sortAscending ? result : -result;
|
bool operator()(const wxString& first, const wxString& second) const
|
||||||
|
{
|
||||||
|
return (*m_compareFunction)(first, second) < 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// sort array elements using passed comparaison function
|
wxArrayString::CompareFunction m_compareFunction;
|
||||||
|
};
|
||||||
|
|
||||||
void wxArrayString::Sort(CompareFunction compareFunction)
|
void wxArrayString::Sort(CompareFunction compareFunction)
|
||||||
{
|
{
|
||||||
wxCRIT_SECT_LOCKER(lockCmpFunc, gs_critsectStringSort);
|
wxCHECK_RET( !m_autoSort, wxT("can't use this method with sorted arrays") );
|
||||||
|
|
||||||
wxASSERT( !gs_compareFunction ); // must have been reset to NULL
|
std::sort(m_pItems, m_pItems + m_nCount,
|
||||||
gs_compareFunction = compareFunction;
|
wxSortPredicateAdaptor(compareFunction));
|
||||||
|
|
||||||
DoSort();
|
|
||||||
|
|
||||||
// reset it to NULL so that Sort(bool) will work the next time
|
|
||||||
gs_compareFunction = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
struct wxSortPredicateAdaptor2
|
||||||
{
|
{
|
||||||
typedef int (wxC_CALLING_CONV * wxStringCompareFn)(const void *first,
|
wxSortPredicateAdaptor2(wxArrayString::CompareFunction2 compareFunction)
|
||||||
const void *second);
|
: m_compareFunction(compareFunction)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const wxString& first, const wxString& second) const
|
||||||
|
{
|
||||||
|
return (*m_compareFunction)(const_cast<wxString *>(&first),
|
||||||
|
const_cast<wxString *>(&second)) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxArrayString::CompareFunction2 m_compareFunction;
|
||||||
|
};
|
||||||
|
|
||||||
void wxArrayString::Sort(CompareFunction2 compareFunction)
|
void wxArrayString::Sort(CompareFunction2 compareFunction)
|
||||||
{
|
{
|
||||||
qsort(m_pItems, m_nCount, sizeof(wxString), (wxStringCompareFn)compareFunction);
|
std::sort(m_pItems, m_pItems + m_nCount,
|
||||||
|
wxSortPredicateAdaptor2(compareFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxArrayString::Sort(bool reverseOrder)
|
void wxArrayString::Sort(bool reverseOrder)
|
||||||
{
|
{
|
||||||
Sort(reverseOrder ? wxStringSortDescending : wxStringSortAscending);
|
if ( reverseOrder )
|
||||||
}
|
std::sort(m_pItems, m_pItems + m_nCount, std::greater<wxString>());
|
||||||
|
else // normal sort
|
||||||
void wxArrayString::DoSort()
|
std::sort(m_pItems, m_pItems + m_nCount);
|
||||||
{
|
|
||||||
wxCHECK_RET( !m_autoSort, wxT("can't use this method with sorted arrays") );
|
|
||||||
|
|
||||||
qsort(m_pItems, m_nCount, sizeof(wxString), wxStringCompareFunction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxArrayString::operator==(const wxArrayString& a) const
|
bool wxArrayString::operator==(const wxArrayString& a) const
|
||||||
@@ -471,18 +462,6 @@ bool wxArrayString::operator==(const wxArrayString& a) const
|
|||||||
|
|
||||||
#endif // !wxUSE_STL
|
#endif // !wxUSE_STL
|
||||||
|
|
||||||
int wxCMPFUNC_CONV wxStringSortAscending(wxString* s1, wxString* s2)
|
|
||||||
{
|
|
||||||
return s1->Cmp(*s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2)
|
|
||||||
{
|
|
||||||
return -s1->Cmp(*s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// wxJoin and wxSplit
|
// wxJoin and wxSplit
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
Reference in New Issue
Block a user