#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
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
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:
// 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
wxASSERT_MSG( nIndex < m_nCount,
_T("wxArrayString: index out of bounds") );
- return *(wxString *)&(m_pItems[nIndex]);
+ return m_pItems[nIndex];
}
// same as Item()
{
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);
// 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);
- // sort array elements using specified comparaison function
+ // sort array elements using specified comparison function
void Sort(CompareFunction compareFunction);
void Sort(CompareFunction2 compareFunction);
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
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)
{ 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(); }
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
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
};
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;
+
+ DECLARE_NO_ASSIGN_CLASS(wxArrayStringsAdapter)
+};
+
+#endif // _WX_ARRSTR_H