X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14baddc9b862a51e551df4b6f2e313f2bc8a392a..6f3f9b50aa275243ade3541ecccb95de22cf57a9:/include/wx/arrstr.h?ds=sidebyside diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index 7e0ee7116a..a78d09e9dd 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -27,9 +27,9 @@ typedef wxString _wxArraywxBaseArrayStringBase; _WX_DECLARE_BASEARRAY_2(_wxArraywxBaseArrayStringBase, wxBaseArrayStringBase, wxArray_SortFunction, class WXDLLIMPEXP_BASE); -WX_DEFINE_USER_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase, +WX_DEFINE_USER_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase, wxBaseArrayStringBase, WXDLLIMPEXP_BASE); -_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase, +_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase, wxBaseArrayStringBase, = wxStringSortAscending, class WXDLLIMPEXP_BASE, CMPFUNCwxString); @@ -42,12 +42,21 @@ public: 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 wxChar* sz, bool bCase = true, bool bFromEnd = false) const; + 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 @@ -67,26 +76,11 @@ public: Add(src[n]); } - int Index(const wxChar* sz, bool bCase = true, bool bFromEnd = false) const; + 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: @@ -110,6 +104,11 @@ public: // of course, using explicit would be even better - if all compilers // supported it... 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 @@ -142,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() @@ -152,23 +151,16 @@ public: { wxASSERT_MSG( !IsEmpty(), _T("wxArrayString: index out of bounds") ); - return Item(Count() - 1); + return Item(GetCount() - 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; + 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); @@ -177,11 +169,8 @@ 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 @@ -209,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; @@ -227,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 @@ -254,13 +243,13 @@ 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) @@ -271,8 +260,8 @@ public: { 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(); } @@ -309,14 +298,13 @@ 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 }; @@ -357,4 +345,98 @@ private: wxString* m_strings; }; -#endif + +// ---------------------------------------------------------------------------- +// 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