1///////////////////////////////////////////////////////////////////////////////
2// Name:        include/wx/arrstr.h
3// Purpose:     wxArrayString class
4// Author:      Mattia Barbon and Vadim Zeitlin
5// Modified by:
6// Created:     07/07/03
7// RCS-ID:      $Id: arrstr.h 61872 2009-09-09 22:37:05Z VZ $
8// Copyright:   (c) 2003 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_ARRSTR_H
13#define _WX_ARRSTR_H
14
15#include "wx/defs.h"
16#include "wx/string.h"
17
18WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortAscending(wxString*, wxString*);
19WXDLLIMPEXP_BASE int wxCMPFUNC_CONV wxStringSortDescending(wxString*, wxString*);
20
21#if wxUSE_STL
22
23#include "wx/dynarray.h"
24
25typedef int (wxCMPFUNC_CONV *CMPFUNCwxString)(wxString*, wxString*);
26typedef wxString _wxArraywxBaseArrayStringBase;
27_WX_DECLARE_BASEARRAY_2(_wxArraywxBaseArrayStringBase, wxBaseArrayStringBase,
28                        wxArray_SortFunction<wxString>,
29                        class WXDLLIMPEXP_BASE);
30WX_DEFINE_USER_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase,
31                                  wxBaseArrayStringBase, WXDLLIMPEXP_BASE);
32_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase,
33                              wxBaseArrayStringBase, = wxStringSortAscending,
34                              class WXDLLIMPEXP_BASE, CMPFUNCwxString);
35
36class WXDLLIMPEXP_BASE wxArrayString : public wxArrayStringBase
37{
38public:
39    // type of function used by wxArrayString::Sort()
40    typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
41                                                  const wxString& second);
42
43    wxArrayString() { }
44    wxArrayString(const wxArrayString& a) : wxArrayStringBase(a) { }
45    wxArrayString(size_t sz, const wxChar** a);
46    wxArrayString(size_t sz, const wxString* a);
47
48    int Index(const wxChar* sz, bool bCase = true, bool bFromEnd = false) const;
49
50    void Sort(bool reverseOrder = false);
51    void Sort(CompareFunction function);
52    void Sort(CMPFUNCwxString function) { wxArrayStringBase::Sort(function); }
53
54    size_t Add(const wxString& string, size_t copies = 1)
55    {
56        wxArrayStringBase::Add(string, copies);
57        return size() - copies;
58    }
59};
60
61class WXDLLIMPEXP_BASE wxSortedArrayString : public wxSortedArrayStringBase
62{
63public:
64    wxSortedArrayString() : wxSortedArrayStringBase(wxStringSortAscending)
65        { }
66    wxSortedArrayString(const wxSortedArrayString& array)
67        : wxSortedArrayStringBase(array)
68        { }
69    wxSortedArrayString(const wxArrayString& src)
70        : wxSortedArrayStringBase(wxStringSortAscending)
71    {
72        reserve(src.size());
73
74        for ( size_t n = 0; n < src.size(); n++ )
75            Add(src[n]);
76    }
77
78    int Index(const wxChar* sz, bool bCase = true, bool bFromEnd = false) const;
79};
80
81#else // if !wxUSE_STL
82
83// ----------------------------------------------------------------------------
84// The string array uses it's knowledge of internal structure of the wxString
85// class to optimize string storage. Normally, we would store pointers to
86// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
87// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
88// really all we need to turn such pointer into a string!
89//
90// Of course, it can be called a dirty hack, but we use twice less memory and
91// this approach is also more speed efficient, so it's probably worth it.
92//
93// Usage notes: when a string is added/inserted, a new copy of it is created,
94// so the original string may be safely deleted. When a string is retrieved
95// from the array (operator[] or Item() method), a reference is returned.
96// ----------------------------------------------------------------------------
97
98class WXDLLIMPEXP_BASE wxArrayString
99{
100public:
101  // type of function used by wxArrayString::Sort()
102  typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
103                                 const wxString& second);
104  // type of function used by wxArrayString::Sort(), for compatibility with
105  // wxArray
106  typedef int (wxCMPFUNC_CONV *CompareFunction2)(wxString* first,
107                                  wxString* second);
108
109  // constructors and destructor
110    // default ctor
111  wxArrayString() { Init(false); }
112    // if autoSort is true, the array is always sorted (in alphabetical order)
113    //
114    // NB: the reason for using int and not bool is that like this we can avoid
115    //     using this ctor for implicit conversions from "const char *" (which
116    //     we'd like to be implicitly converted to wxString instead!)
117    //
118    //     of course, using explicit would be even better - if all compilers
119    //     supported it...
120  wxArrayString(int autoSort) { Init(autoSort != 0); }
121    // C string array ctor
122  wxArrayString(size_t sz, const wxChar** a);
123    // wxString string array ctor
124  wxArrayString(size_t sz, const wxString* a);
125    // copy ctor
126  wxArrayString(const wxArrayString& array);
127    // assignment operator
128  wxArrayString& operator=(const wxArrayString& src);
129    // not virtual, this class should not be derived from
130 ~wxArrayString();
131
132  // memory management
133    // empties the list, but doesn't release memory
134  void Empty();
135    // empties the list and releases memory
136  void Clear();
137    // preallocates memory for given number of items
138  void Alloc(size_t nCount);
139    // minimzes the memory usage (by freeing all extra memory)
140  void Shrink();
141
142  // simple accessors
143    // number of elements in the array
144  size_t GetCount() const { return m_nCount; }
145    // is it empty?
146  bool IsEmpty() const { return m_nCount == 0; }
147    // number of elements in the array (GetCount is preferred API)
148  size_t Count() const { return m_nCount; }
149
150  // items access (range checking is done in debug version)
151    // get item at position uiIndex
152  wxString& Item(size_t nIndex) const
153    {
154        wxASSERT_MSG( nIndex < m_nCount,
155                      wxT("wxArrayString: index out of bounds") );
156
157        return *(wxString *)&(m_pItems[nIndex]);
158    }
159
160    // same as Item()
161  wxString& operator[](size_t nIndex) const { return Item(nIndex); }
162    // get last item
163  wxString& Last() const
164  {
165      wxASSERT_MSG( !IsEmpty(),
166                    wxT("wxArrayString: index out of bounds") );
167      return Item(Count() - 1);
168  }
169
170    // return a wxString[], useful for the controls which
171    // take one in their ctor.  You must delete[] it yourself
172    // once you are done with it.  Will return NULL if the
173    // ArrayString was empty.
174#if WXWIN_COMPATIBILITY_2_4
175  wxDEPRECATED( wxString* GetStringArray() const );
176#endif
177
178  // item management
179    // Search the element in the array, starting from the beginning if
180    // bFromEnd is false or from end otherwise. If bCase, comparison is case
181    // sensitive (default). Returns index of the first item matched or
182    // wxNOT_FOUND
183  int  Index (const wxChar *sz, bool bCase = true, bool bFromEnd = false) const;
184    // add new element at the end (if the array is not sorted), return its
185    // index
186  size_t Add(const wxString& str, size_t nInsert = 1);
187    // add new element at given position
188  void Insert(const wxString& str, size_t uiIndex, size_t nInsert = 1);
189    // expand the array to have count elements
190  void SetCount(size_t count);
191    // remove first item matching this value
192  void Remove(const wxChar *sz);
193    // remove item by index
194#if WXWIN_COMPATIBILITY_2_4
195  wxDEPRECATED( void Remove(size_t nIndex, size_t nRemove = 1) );
196#endif
197  void RemoveAt(size_t nIndex, size_t nRemove = 1);
198
199  // sorting
200    // sort array elements in alphabetical order (or reversed alphabetical
201    // order if reverseOrder parameter is true)
202  void Sort(bool reverseOrder = false);
203    // sort array elements using specified comparaison function
204  void Sort(CompareFunction compareFunction);
205  void Sort(CompareFunction2 compareFunction);
206
207  // comparison
208    // compare two arrays case sensitively
209  bool operator==(const wxArrayString& a) const;
210    // compare two arrays case sensitively
211  bool operator!=(const wxArrayString& a) const { return !(*this == a); }
212
213  // STL-like interface
214  typedef wxString value_type;
215  typedef value_type* pointer;
216  typedef const value_type* const_pointer;
217  typedef value_type* iterator;
218  typedef const value_type* const_iterator;
219  typedef value_type& reference;
220  typedef const value_type& const_reference;
221  typedef int difference_type;
222  typedef size_t size_type;
223
224  // TODO: this code duplicates the one in dynarray.h
225  class reverse_iterator
226  {
227    typedef wxString value_type;
228    typedef value_type* pointer;
229    typedef value_type& reference;
230    typedef reverse_iterator itor;
231    friend itor operator+(int o, const itor& it);
232    friend itor operator+(const itor& it, int o);
233    friend itor operator-(const itor& it, int o);
234    friend difference_type operator -(const itor& i1, const itor& i2);
235  public:
236    pointer m_ptr;
237    reverse_iterator() : m_ptr(NULL) { }
238    reverse_iterator(pointer ptr) : m_ptr(ptr) { }
239    reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
240    reference operator*() const { return *m_ptr; }
241    pointer operator->() const { return m_ptr; }
242    itor& operator++() { --m_ptr; return *this; }
243    const itor operator++(int)
244      { reverse_iterator tmp = *this; --m_ptr; return tmp; }
245    itor& operator--() { ++m_ptr; return *this; }
246    const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
247    bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }
248    bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }
249  };
250
251  class const_reverse_iterator
252  {
253    typedef wxString value_type;
254    typedef const value_type* pointer;
255    typedef const value_type& reference;
256    typedef const_reverse_iterator itor;
257    friend itor operator+(int o, const itor& it);
258    friend itor operator+(const itor& it, int o);
259    friend itor operator-(const itor& it, int o);
260    friend difference_type operator -(const itor& i1, const itor& i2);
261  public:
262    pointer m_ptr;
263    const_reverse_iterator() : m_ptr(NULL) { }
264    const_reverse_iterator(pointer ptr) : m_ptr(ptr) { }
265    const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
266    const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }
267    reference operator*() const { return *m_ptr; }
268    pointer operator->() const { return m_ptr; }
269    itor& operator++() { --m_ptr; return *this; }
270    const itor operator++(int)
271      { itor tmp = *this; --m_ptr; return tmp; }
272    itor& operator--() { ++m_ptr; return *this; }
273    const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
274    bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }
275    bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }
276  };
277
278  wxArrayString(const_iterator first, const_iterator last)
279    { Init(false); assign(first, last); }
280  wxArrayString(size_type n, const_reference v) { Init(false); assign(n, v); }
281  void assign(const_iterator first, const_iterator last);
282  void assign(size_type n, const_reference v)
283    { clear(); Add(v, n); }
284  reference back() { return *(end() - 1); }
285  const_reference back() const { return *(end() - 1); }
286  iterator begin() { return (wxString *)&(m_pItems[0]); }
287  const_iterator begin() const { return (wxString *)&(m_pItems[0]); }
288  size_type capacity() const { return m_nSize; }
289  void clear() { Clear(); }
290  bool empty() const { return IsEmpty(); }
291  iterator end() { return begin() + GetCount(); }
292  const_iterator end() const { return begin() + GetCount(); }
293  iterator erase(iterator first, iterator last)
294  {
295      size_t idx = first - begin();
296      RemoveAt(idx, last - first);
297      return begin() + idx;
298  }
299  iterator erase(iterator it) { return erase(it, it + 1); }
300  reference front() { return *begin(); }
301  const_reference front() const { return *begin(); }
302  void insert(iterator it, size_type n, const_reference v)
303    { Insert(v, it - begin(), n); }
304  iterator insert(iterator it, const_reference v = value_type())
305    { size_t idx = it - begin(); Insert(v, idx); return begin() + idx; }
306  void insert(iterator it, const_iterator first, const_iterator last);
307  size_type max_size() const { return INT_MAX; }
308  void pop_back() { RemoveAt(GetCount() - 1); }
309  void push_back(const_reference v) { Add(v); }
310  reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
311  const_reverse_iterator rbegin() const;
312  reverse_iterator rend() { return reverse_iterator(begin() - 1); }
313  const_reverse_iterator rend() const;
314  void reserve(size_type n) /* base::reserve*/;
315  void resize(size_type n, value_type v = value_type());
316  size_type size() const { return GetCount(); }
317
318protected:
319  void Init(bool autoSort);             // common part of all ctors
320  void Copy(const wxArrayString& src);  // copies the contents of another array
321
322private:
323  void Grow(size_t nIncrement = 0);     // makes array bigger if needed
324  void Free();                          // free all the strings stored
325
326  void DoSort();                        // common part of all Sort() variants
327
328  size_t  m_nSize,    // current size of the array
329          m_nCount;   // current number of elements
330
331  wxChar  **m_pItems; // pointer to data
332
333  bool    m_autoSort; // if true, keep the array always sorted
334};
335
336class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString
337{
338public:
339  wxSortedArrayString() : wxArrayString(true)
340    { }
341  wxSortedArrayString(const wxArrayString& array) : wxArrayString(true)
342    { Copy(array); }
343};
344
345#endif // !wxUSE_STL
346
347// this class provides a temporary wxString* from a
348// wxArrayString
349class WXDLLIMPEXP_BASE wxCArrayString
350{
351public:
352    wxCArrayString( const wxArrayString& array )
353        : m_array( array ), m_strings( NULL )
354    { }
355    ~wxCArrayString() { delete[] m_strings; }
356
357    size_t GetCount() const { return m_array.GetCount(); }
358    wxString* GetStrings()
359    {
360        if( m_strings ) return m_strings;
361        size_t count = m_array.GetCount();
362        m_strings = new wxString[count];
363        for( size_t i = 0; i < count; ++i )
364            m_strings[i] = m_array[i];
365        return m_strings;
366    }
367
368#if wxABI_VERSION >= 20810
369    wxString* Release();
370#endif // wxABI_VERSION >= 20810
371
372private:
373    const wxArrayString& m_array;
374    wxString* m_strings;
375};
376
377#endif
378