X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/001ad728a48bcfc7a763027b41f10ba1a25ce276..86ac84b8ce086e6bbda58f422d41f84268606e35:/include/wx/arrstr.h?ds=sidebyside diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index c76fb40dc4..a9e6f86f04 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -15,8 +15,18 @@ #include "wx/defs.h" #include "wx/string.h" -WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortAscending(wxString*, wxString*); -WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortDescending(wxString*, wxString*); +// these functions are only used in STL build now but we define them in any +// case for compatibility with the existing code outside of the library which +// could be using them +inline int wxCMPFUNC_CONV wxStringSortAscending(wxString* s1, wxString* s2) +{ + return s1->Cmp(*s2); +} + +inline int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2) +{ + return wxStringSortAscending(s2, s1); +} #if wxUSE_STL @@ -42,10 +52,11 @@ public: wxArrayString() { } wxArrayString(const wxArrayString& a) : wxArrayStringBase(a) { } - wxArrayString(size_t sz, const wxChar** 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); @@ -75,25 +86,26 @@ 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! +// this shouldn't be defined for compilers not supporting template methods or +// without std::distance() // -// 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. -// ---------------------------------------------------------------------------- +// FIXME-VC6: currently it's only not defined for VC6 in DLL build as it +// doesn't export template methods from DLL correctly so even though +// it compiles them fine, we get link errors when using wxArrayString +#if !defined(__VISUALC6__) || !(defined(WXMAKINGDLL) || defined(WXUSINGDLL)) + #define wxHAS_VECTOR_TEMPLATE_ASSIGN +#endif + +#ifdef wxHAS_VECTOR_TEMPLATE_ASSIGN + #include "wx/beforestd.h" + #include + #include "wx/afterstd.h" +#endif // wxHAS_VECTOR_TEMPLATE_ASSIGN class WXDLLIMPEXP_BASE wxArrayString { @@ -119,7 +131,8 @@ public: // supported it... wxArrayString(int autoSort) { Init(autoSort != 0); } // C string array ctor - wxArrayString(size_t sz, const wxChar** a); + 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 @@ -154,7 +167,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() @@ -164,23 +177,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 - wxDEPRECATED( 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); @@ -189,18 +195,15 @@ 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 - wxDEPRECATED( void Remove(size_t nIndex, size_t nRemove = 1) ); -#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 + // sort array elements using specified comparison function void Sort(CompareFunction compareFunction); void Sort(CompareFunction2 compareFunction); @@ -278,13 +281,32 @@ public: 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); + +#ifdef wxHAS_VECTOR_TEMPLATE_ASSIGN + template + void assign(Iterator first, Iterator last) + { + clear(); + reserve(std::distance(first, last)); + for(; first != last; ++first) + push_back(*first); + } +#else // !wxHAS_VECTOR_TEMPLATE_ASSIGN + void assign(const_iterator first, const_iterator last) + { + clear(); + reserve(last - first); + for(; first != last; ++first) + push_back(*first); + } +#endif // wxHAS_VECTOR_TEMPLATE_ASSIGN/!wxHAS_VECTOR_TEMPLATE_ASSIGN + 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(); } @@ -308,12 +330,21 @@ public: 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; + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end() - 1); } reverse_iterator rend() { return reverse_iterator(begin() - 1); } - const_reverse_iterator rend() const; + const_reverse_iterator rend() const + { return const_reverse_iterator(begin() - 1); } void reserve(size_type n) /* base::reserve*/; void resize(size_type n, value_type v = value_type()); size_type size() const { return GetCount(); } + void swap(wxArrayString& other) + { + wxSwap(m_nSize, other.m_nSize); + wxSwap(m_nCount, other.m_nCount); + wxSwap(m_pItems, other.m_pItems); + wxSwap(m_autoSort, other.m_autoSort); + } protected: void Init(bool autoSort); // common part of all ctors @@ -321,14 +352,11 @@ 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 - const wxChar **m_pItems; // pointer to data + wxString *m_pItems; // pointer to data bool m_autoSort; // if true, keep the array always sorted }; @@ -364,9 +392,111 @@ public: m_strings[i] = m_array[i]; return m_strings; } + + wxString* Release() + { + wxString *r = GetStrings(); + m_strings = NULL; + return r; + } + private: const wxArrayString& m_array; 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 + size_t 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; + size_t m_size; + union + { + const wxString * ptr; + const wxArrayString * array; + } m_data; + + wxDECLARE_NO_ASSIGN_CLASS(wxArrayStringsAdapter); +}; + +#endif // _WX_ARRSTR_H