X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/375894195f3a1fb92fbde0aed2a92bfec1258d09..700d08c1092bd08150d47b952c1e0d817a64d75f:/include/wx/arrstr.h diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index 5e396cc283..a78d09e9dd 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -15,26 +15,48 @@ #include "wx/defs.h" #include "wx/string.h" -int WXDLLIMPEXP_BASE wxStringSortAscending(wxString*, wxString*); -int WXDLLIMPEXP_BASE wxStringSortDescending(wxString*, wxString*); +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 (*CMPFUNCwxString)(wxString*, wxString*); -WX_DECLARE_EXPORTED_BASEARRAY(wxString, wxBaseArrayStringBase); -WX_DEFINE_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase, - wxBaseArrayStringBase); -_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase, +typedef int (wxCMPFUNC_CONV *CMPFUNCwxString)(wxString*, wxString*); +typedef wxString _wxArraywxBaseArrayStringBase; +_WX_DECLARE_BASEARRAY_2(_wxArraywxBaseArrayStringBase, wxBaseArrayStringBase, + wxArray_SortFunction, + 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) { } + wxArrayString(size_t sz, const char** a); + wxArrayString(size_t sz, const wchar_t** a); + wxArrayString(size_t sz, const wxString* a); + + int Index(const wxString& str, bool bCase = true, bool bFromEnd = false) const; + + void Sort(bool reverseOrder = false); + void Sort(CompareFunction function); + void Sort(CMPFUNCwxString function) { wxArrayStringBase::Sort(function); } + + size_t Add(const wxString& string, size_t copies = 1) + { + wxArrayStringBase::Add(string, copies); + return size() - copies; + } }; class WXDLLIMPEXP_BASE wxSortedArrayString : public wxSortedArrayStringBase @@ -53,42 +75,27 @@ public: for ( size_t n = 0; n < src.size(); n++ ) Add(src[n]); } + + int Index(const wxString& str, 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 (*CompareFunction)(const wxString& first, + typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first, const wxString& second); // type of function used by wxArrayString::Sort(), for compatibility with // wxArray - typedef int (*CompareFunction2)(wxString* first, + typedef int (wxCMPFUNC_CONV *CompareFunction2)(wxString* first, wxString* second); // constructors and destructor // default ctor - wxArrayString() - : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) - { Init(FALSE); } - // if autoSort is TRUE, the array is always sorted (in alphabetical order) + 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 @@ -96,9 +103,12 @@ public: // // of course, using explicit would be even better - if all compilers // supported it... - wxArrayString(int autoSort) - : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) - { Init(autoSort != 0); } + wxArrayString(int autoSort) { Init(autoSort != 0); } + // C string array ctor + wxArrayString(size_t sz, const char** a); + wxArrayString(size_t sz, const wchar_t** a); + // wxString string array ctor + wxArrayString(size_t sz, const wxString* a); // copy ctor wxArrayString(const wxArrayString& array); // assignment operator @@ -131,7 +141,7 @@ public: wxASSERT_MSG( nIndex < m_nCount, _T("wxArrayString: index out of bounds") ); - return *(wxString *)&(m_pItems[nIndex]); + return m_pItems[nIndex]; } // same as Item() @@ -141,23 +151,16 @@ public: { wxASSERT_MSG( !IsEmpty(), _T("wxArrayString: index out of bounds") ); - return Item(Count() - 1); + return Item(GetCount() - 1); } -#if WXWIN_COMPATIBILITY_2_4 - // 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. - 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 + // 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; + int Index (const wxString& str, 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); @@ -166,17 +169,14 @@ public: // expand the array to have count elements void SetCount(size_t count); // remove first item matching this value - void Remove(const wxChar *sz); + void Remove(const wxString& 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); + // 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); @@ -198,7 +198,7 @@ public: typedef int difference_type; typedef size_t size_type; - // FIXME: same in dynarray.h + // TODO: this code duplicates the one in dynarray.h class reverse_iterator { typedef wxString value_type; @@ -216,13 +216,13 @@ public: 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) + itor& operator++() { --m_ptr; return *this; } + const 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; } + itor& operator--() { ++m_ptr; return *this; } + const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } + bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; } + bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; } }; class const_reverse_iterator @@ -243,22 +243,25 @@ public: 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& operator++() { --m_ptr; return *this; } + const 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; } + itor& operator--() { ++m_ptr; return *this; } + const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } + bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; } + bool operator !=(const itor& it) const { 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]); } + iterator begin() { return m_pItems; } + const_iterator begin() const { return m_pItems; } size_type capacity() const { return m_nSize; } void clear() { Clear(); } bool empty() const { return IsEmpty(); } @@ -295,27 +298,145 @@ protected: 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 + wxString *m_pItems; // pointer to data - bool m_autoSort; // if TRUE, keep the array always sorted + bool m_autoSort; // if true, keep the array always sorted }; class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString { public: - wxSortedArrayString() : wxArrayString(TRUE) + wxSortedArrayString() : wxArrayString(true) { } - wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE) + wxSortedArrayString(const wxArrayString& array) : wxArrayString(true) { Copy(array); } }; #endif // !wxUSE_STL -#endif +// 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; +}; + + +// ---------------------------------------------------------------------------- +// helper functions for working with arrays +// ---------------------------------------------------------------------------- + +// by default, these functions use the escape character to escape the +// separators occuring inside the string to be joined, this can be disabled by +// passing '\0' as escape + +WXDLLIMPEXP_BASE wxString wxJoin(const wxArrayString& arr, + const wxChar sep, + const wxChar escape = wxT('\\')); + +WXDLLIMPEXP_BASE wxArrayString wxSplit(const wxString& str, + const wxChar sep, + const wxChar escape = wxT('\\')); + + +// ---------------------------------------------------------------------------- +// This helper class allows to pass both C array of wxStrings or wxArrayString +// using the same interface. +// +// Use it when you have two methods taking wxArrayString or (int, wxString[]), +// that do the same thing. This class lets you iterate over input data in the +// same way whether it is a raw array of strings or wxArrayString. +// +// The object does not take ownership of the data -- internally it keeps +// pointers to the data, therefore the data must be disposed of by user +// and only after this object is destroyed. Usually it is not a problem as +// only temporary objects of this class are used. +// ---------------------------------------------------------------------------- + +class wxArrayStringsAdapter +{ +public: + // construct an adapter from a wxArrayString + wxArrayStringsAdapter(const wxArrayString& strings) + : m_type(wxSTRING_ARRAY), m_size(strings.size()) + { + m_data.array = &strings; + } + + // construct an adapter from a wxString[] + wxArrayStringsAdapter(unsigned int n, const wxString *strings) + : m_type(wxSTRING_POINTER), m_size(n) + { + m_data.ptr = strings; + } + + // construct an adapter from a single wxString + wxArrayStringsAdapter(const wxString& s) + : m_type(wxSTRING_POINTER), m_size(1) + { + m_data.ptr = &s; + } + + // default copy constructor is ok + + // iteration interface + unsigned int GetCount() const { return m_size; } + bool IsEmpty() const { return GetCount() == 0; } + const wxString& operator[] (unsigned int i) const + { + wxASSERT_MSG( i < GetCount(), wxT("index out of bounds") ); + if(m_type == wxSTRING_POINTER) + return m_data.ptr[i]; + return m_data.array->Item(i); + } + wxArrayString AsArrayString() const + { + if(m_type == wxSTRING_ARRAY) + return *m_data.array; + return wxArrayString(GetCount(), m_data.ptr); + } + +private: + // type of the data being held + enum wxStringContainerType + { + wxSTRING_ARRAY, // wxArrayString + wxSTRING_POINTER // wxString[] + }; + + wxStringContainerType m_type; + unsigned int m_size; + union + { + const wxString * ptr; + const wxArrayString * array; + } m_data; + + DECLARE_NO_ASSIGN_CLASS(wxArrayStringsAdapter) +}; + +#endif // _WX_ARRSTR_H