4e75b65f7c
void wxArrayString::Sort(CompareFunction function) void wxArrayString::Sort(bool reverseOrder). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
360 lines
13 KiB
C++
360 lines
13 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: include/wx/arrstr.h
|
|
// Purpose: wxArrayString class
|
|
// Author: Mattia Barbon and Vadim Zeitlin
|
|
// Modified by:
|
|
// Created: 07/07/03
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 2003 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _WX_ARRSTR_H
|
|
#define _WX_ARRSTR_H
|
|
|
|
#include "wx/defs.h"
|
|
#include "wx/string.h"
|
|
|
|
WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortAscending(wxString*, wxString*);
|
|
WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortDescending(wxString*, wxString*);
|
|
|
|
#if wxUSE_STL
|
|
|
|
#include "wx/dynarray.h"
|
|
|
|
typedef int (wxCMPFUNC_CONV *CMPFUNCwxString)(wxString*, wxString*);
|
|
typedef wxString _wxArraywxBaseArrayStringBase;
|
|
_WX_DECLARE_BASEARRAY_2(_wxArraywxBaseArrayStringBase, wxBaseArrayStringBase,
|
|
wxArray_SortFunction<wxString>,
|
|
class WXDLLIMPEXP_BASE);
|
|
WX_DEFINE_USER_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase,
|
|
wxBaseArrayStringBase, WXDLLIMPEXP_BASE);
|
|
_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase,
|
|
wxBaseArrayStringBase, = wxStringSortAscending,
|
|
class WXDLLIMPEXP_BASE, CMPFUNCwxString);
|
|
|
|
class WXDLLIMPEXP_BASE wxArrayString : public wxArrayStringBase
|
|
{
|
|
public:
|
|
// type of function used by wxArrayString::Sort()
|
|
typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
|
|
const wxString& second);
|
|
|
|
wxArrayString() { }
|
|
wxArrayString(const wxArrayString& a) : wxArrayStringBase(a) { }
|
|
|
|
int Index(const wxChar* sz, bool bCase = true, bool bFromEnd = false) const;
|
|
|
|
void Sort(bool reverseOrder = false);
|
|
void Sort(CompareFunction function);
|
|
};
|
|
|
|
class WXDLLIMPEXP_BASE wxSortedArrayString : public wxSortedArrayStringBase
|
|
{
|
|
public:
|
|
wxSortedArrayString() : wxSortedArrayStringBase(wxStringSortAscending)
|
|
{ }
|
|
wxSortedArrayString(const wxSortedArrayString& array)
|
|
: wxSortedArrayStringBase(array)
|
|
{ }
|
|
wxSortedArrayString(const wxArrayString& src)
|
|
: wxSortedArrayStringBase(wxStringSortAscending)
|
|
{
|
|
reserve(src.size());
|
|
|
|
for ( size_t n = 0; n < src.size(); n++ )
|
|
Add(src[n]);
|
|
}
|
|
|
|
int Index(const wxChar* sz, bool bCase = true, bool bFromEnd = false) const;
|
|
};
|
|
|
|
#else // if !wxUSE_STL
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// The string array uses it's knowledge of internal structure of the wxString
|
|
// class to optimize string storage. Normally, we would store pointers to
|
|
// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
|
|
// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
|
|
// really all we need to turn such pointer into a string!
|
|
//
|
|
// Of course, it can be called a dirty hack, but we use twice less memory and
|
|
// this approach is also more speed efficient, so it's probably worth it.
|
|
//
|
|
// Usage notes: when a string is added/inserted, a new copy of it is created,
|
|
// so the original string may be safely deleted. When a string is retrieved
|
|
// from the array (operator[] or Item() method), a reference is returned.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class WXDLLIMPEXP_BASE wxArrayString
|
|
{
|
|
public:
|
|
// type of function used by wxArrayString::Sort()
|
|
typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
|
|
const wxString& second);
|
|
// type of function used by wxArrayString::Sort(), for compatibility with
|
|
// wxArray
|
|
typedef int (wxCMPFUNC_CONV *CompareFunction2)(wxString* first,
|
|
wxString* second);
|
|
|
|
// constructors and destructor
|
|
// default ctor
|
|
wxArrayString() { Init(false); }
|
|
// if autoSort is true, the array is always sorted (in alphabetical order)
|
|
//
|
|
// NB: the reason for using int and not bool is that like this we can avoid
|
|
// using this ctor for implicit conversions from "const char *" (which
|
|
// we'd like to be implicitly converted to wxString instead!)
|
|
//
|
|
// of course, using explicit would be even better - if all compilers
|
|
// supported it...
|
|
wxArrayString(int autoSort) { Init(autoSort != 0); }
|
|
// copy ctor
|
|
wxArrayString(const wxArrayString& array);
|
|
// assignment operator
|
|
wxArrayString& operator=(const wxArrayString& src);
|
|
// not virtual, this class should not be derived from
|
|
~wxArrayString();
|
|
|
|
// memory management
|
|
// empties the list, but doesn't release memory
|
|
void Empty();
|
|
// empties the list and releases memory
|
|
void Clear();
|
|
// preallocates memory for given number of items
|
|
void Alloc(size_t nCount);
|
|
// minimzes the memory usage (by freeing all extra memory)
|
|
void Shrink();
|
|
|
|
// simple accessors
|
|
// number of elements in the array
|
|
size_t GetCount() const { return m_nCount; }
|
|
// is it empty?
|
|
bool IsEmpty() const { return m_nCount == 0; }
|
|
// number of elements in the array (GetCount is preferred API)
|
|
size_t Count() const { return m_nCount; }
|
|
|
|
// items access (range checking is done in debug version)
|
|
// get item at position uiIndex
|
|
wxString& Item(size_t nIndex) const
|
|
{
|
|
wxASSERT_MSG( nIndex < m_nCount,
|
|
_T("wxArrayString: index out of bounds") );
|
|
|
|
return *(wxString *)&(m_pItems[nIndex]);
|
|
}
|
|
|
|
// same as Item()
|
|
wxString& operator[](size_t nIndex) const { return Item(nIndex); }
|
|
// get last item
|
|
wxString& Last() const
|
|
{
|
|
wxASSERT_MSG( !IsEmpty(),
|
|
_T("wxArrayString: index out of bounds") );
|
|
return Item(Count() - 1);
|
|
}
|
|
|
|
// return a wxString[], useful for the controls which
|
|
// take one in their ctor. You must delete[] it yourself
|
|
// once you are done with it. Will return NULL if the
|
|
// ArrayString was empty.
|
|
#if WXWIN_COMPATIBILITY_2_4
|
|
wxString* GetStringArray() const;
|
|
#endif
|
|
|
|
// item management
|
|
// Search the element in the array, starting from the beginning if
|
|
// bFromEnd is false or from end otherwise. If bCase, comparison is case
|
|
// sensitive (default). Returns index of the first item matched or
|
|
// wxNOT_FOUND
|
|
int Index (const wxChar *sz, bool bCase = true, bool bFromEnd = false) const;
|
|
// add new element at the end (if the array is not sorted), return its
|
|
// index
|
|
size_t Add(const wxString& str, size_t nInsert = 1);
|
|
// add new element at given position
|
|
void Insert(const wxString& str, size_t uiIndex, size_t nInsert = 1);
|
|
// expand the array to have count elements
|
|
void SetCount(size_t count);
|
|
// remove first item matching this value
|
|
void Remove(const wxChar *sz);
|
|
// remove item by index
|
|
#if WXWIN_COMPATIBILITY_2_4
|
|
void Remove(size_t nIndex, size_t nRemove = 1) { RemoveAt(nIndex, nRemove); }
|
|
#endif
|
|
void RemoveAt(size_t nIndex, size_t nRemove = 1);
|
|
|
|
// sorting
|
|
// sort array elements in alphabetical order (or reversed alphabetical
|
|
// order if reverseOrder parameter is true)
|
|
void Sort(bool reverseOrder = false);
|
|
// sort array elements using specified comparaison function
|
|
void Sort(CompareFunction compareFunction);
|
|
void Sort(CompareFunction2 compareFunction);
|
|
|
|
// comparison
|
|
// compare two arrays case sensitively
|
|
bool operator==(const wxArrayString& a) const;
|
|
// compare two arrays case sensitively
|
|
bool operator!=(const wxArrayString& a) const { return !(*this == a); }
|
|
|
|
// STL-like interface
|
|
typedef wxString value_type;
|
|
typedef value_type* pointer;
|
|
typedef const value_type* const_pointer;
|
|
typedef value_type* iterator;
|
|
typedef const value_type* const_iterator;
|
|
typedef value_type& reference;
|
|
typedef const value_type& const_reference;
|
|
typedef int difference_type;
|
|
typedef size_t size_type;
|
|
|
|
// FIXME: same in dynarray.h
|
|
class reverse_iterator
|
|
{
|
|
typedef wxString value_type;
|
|
typedef value_type* pointer;
|
|
typedef value_type& reference;
|
|
typedef reverse_iterator itor;
|
|
friend itor operator+(int o, const itor& it);
|
|
friend itor operator+(const itor& it, int o);
|
|
friend itor operator-(const itor& it, int o);
|
|
friend difference_type operator -(const itor& i1, const itor& i2);
|
|
public:
|
|
pointer m_ptr;
|
|
reverse_iterator() : m_ptr(NULL) { }
|
|
reverse_iterator(pointer ptr) : m_ptr(ptr) { }
|
|
reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
|
|
reference operator*() const { return *m_ptr; }
|
|
pointer operator->() const { return m_ptr; }
|
|
itor operator++() { --m_ptr; return *this; }
|
|
itor operator++(int)
|
|
{ reverse_iterator tmp = *this; --m_ptr; return tmp; }
|
|
itor operator--() { ++m_ptr; return *this; }
|
|
itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
|
|
bool operator ==(const itor& it) { return m_ptr == it.m_ptr; }
|
|
bool operator !=(const itor& it) { return m_ptr != it.m_ptr; }
|
|
};
|
|
|
|
class const_reverse_iterator
|
|
{
|
|
typedef wxString value_type;
|
|
typedef const value_type* pointer;
|
|
typedef const value_type& reference;
|
|
typedef const_reverse_iterator itor;
|
|
friend itor operator+(int o, const itor& it);
|
|
friend itor operator+(const itor& it, int o);
|
|
friend itor operator-(const itor& it, int o);
|
|
friend difference_type operator -(const itor& i1, const itor& i2);
|
|
public:
|
|
pointer m_ptr;
|
|
const_reverse_iterator() : m_ptr(NULL) { }
|
|
const_reverse_iterator(pointer ptr) : m_ptr(ptr) { }
|
|
const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
|
|
const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }
|
|
reference operator*() const { return *m_ptr; }
|
|
pointer operator->() const { return m_ptr; }
|
|
itor operator++() { --m_ptr; return *this; }
|
|
itor operator++(int)
|
|
{ itor tmp = *this; --m_ptr; return tmp; }
|
|
itor operator--() { ++m_ptr; return *this; }
|
|
itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
|
|
bool operator ==(const itor& it) { return m_ptr == it.m_ptr; }
|
|
bool operator !=(const itor& it) { return m_ptr != it.m_ptr; }
|
|
};
|
|
|
|
wxArrayString(const_iterator first, const_iterator last)
|
|
{ Init(false); assign(first, last); }
|
|
wxArrayString(size_type n, const_reference v) { Init(false); assign(n, v); }
|
|
void assign(const_iterator first, const_iterator last);
|
|
void assign(size_type n, const_reference v)
|
|
{ clear(); Add(v, n); }
|
|
reference back() { return *(end() - 1); }
|
|
const_reference back() const { return *(end() - 1); }
|
|
iterator begin() { return (wxString *)&(m_pItems[0]); }
|
|
const_iterator begin() const { return (wxString *)&(m_pItems[0]); }
|
|
size_type capacity() const { return m_nSize; }
|
|
void clear() { Clear(); }
|
|
bool empty() const { return IsEmpty(); }
|
|
iterator end() { return begin() + GetCount(); }
|
|
const_iterator end() const { return begin() + GetCount(); }
|
|
iterator erase(iterator first, iterator last)
|
|
{
|
|
size_t idx = first - begin();
|
|
RemoveAt(idx, last - first);
|
|
return begin() + idx;
|
|
}
|
|
iterator erase(iterator it) { return erase(it, it + 1); }
|
|
reference front() { return *begin(); }
|
|
const_reference front() const { return *begin(); }
|
|
void insert(iterator it, size_type n, const_reference v)
|
|
{ Insert(v, it - begin(), n); }
|
|
iterator insert(iterator it, const_reference v = value_type())
|
|
{ size_t idx = it - begin(); Insert(v, idx); return begin() + idx; }
|
|
void insert(iterator it, const_iterator first, const_iterator last);
|
|
size_type max_size() const { return INT_MAX; }
|
|
void pop_back() { RemoveAt(GetCount() - 1); }
|
|
void push_back(const_reference v) { Add(v); }
|
|
reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
|
|
const_reverse_iterator rbegin() const;
|
|
reverse_iterator rend() { return reverse_iterator(begin() - 1); }
|
|
const_reverse_iterator rend() const;
|
|
void reserve(size_type n) /* base::reserve*/;
|
|
void resize(size_type n, value_type v = value_type());
|
|
size_type size() const { return GetCount(); }
|
|
|
|
protected:
|
|
void Init(bool autoSort); // common part of all ctors
|
|
void Copy(const wxArrayString& src); // copies the contents of another array
|
|
|
|
private:
|
|
void Grow(size_t nIncrement = 0); // makes array bigger if needed
|
|
void Free(); // free all the strings stored
|
|
|
|
void DoSort(); // common part of all Sort() variants
|
|
|
|
size_t m_nSize, // current size of the array
|
|
m_nCount; // current number of elements
|
|
|
|
wxChar **m_pItems; // pointer to data
|
|
|
|
bool m_autoSort; // if true, keep the array always sorted
|
|
};
|
|
|
|
class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString
|
|
{
|
|
public:
|
|
wxSortedArrayString() : wxArrayString(true)
|
|
{ }
|
|
wxSortedArrayString(const wxArrayString& array) : wxArrayString(true)
|
|
{ Copy(array); }
|
|
};
|
|
|
|
#endif // !wxUSE_STL
|
|
|
|
// this class provides a temporary wxString* from a
|
|
// wxArrayString
|
|
class WXDLLIMPEXP_BASE wxCArrayString
|
|
{
|
|
public:
|
|
wxCArrayString( const wxArrayString& array )
|
|
: m_array( array ), m_strings( NULL )
|
|
{ }
|
|
~wxCArrayString() { delete[] m_strings; }
|
|
|
|
size_t GetCount() const { return m_array.GetCount(); }
|
|
wxString* GetStrings()
|
|
{
|
|
if( m_strings ) return m_strings;
|
|
size_t count = m_array.GetCount();
|
|
m_strings = new wxString[count];
|
|
for( size_t i = 0; i < count; ++i )
|
|
m_strings[i] = m_array[i];
|
|
return m_strings;
|
|
}
|
|
private:
|
|
const wxArrayString& m_array;
|
|
wxString* m_strings;
|
|
};
|
|
|
|
#endif
|