Use RIAA wrapper for wxSpinCtrl event disabling in wxGTK.
[wxWidgets.git] / include / wx / arrstr.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/arrstr.h
3 // Purpose: wxArrayString class
4 // Author: Mattia Barbon and Vadim Zeitlin
5 // Modified by:
6 // Created: 07/07/03
7 // Copyright: (c) 2003 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_ARRSTR_H
12 #define _WX_ARRSTR_H
13
14 #include "wx/defs.h"
15 #include "wx/string.h"
16
17 // these functions are only used in STL build now but we define them in any
18 // case for compatibility with the existing code outside of the library which
19 // could be using them
20 inline int wxCMPFUNC_CONV wxStringSortAscending(wxString* s1, wxString* s2)
21 {
22 return s1->Cmp(*s2);
23 }
24
25 inline int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2)
26 {
27 return wxStringSortAscending(s2, s1);
28 }
29
30 #if wxUSE_STD_CONTAINERS
31
32 #include "wx/dynarray.h"
33
34 typedef int (wxCMPFUNC_CONV *CMPFUNCwxString)(wxString*, wxString*);
35 typedef wxString _wxArraywxBaseArrayStringBase;
36 _WX_DECLARE_BASEARRAY_2(_wxArraywxBaseArrayStringBase, wxBaseArrayStringBase,
37 wxArray_SortFunction<wxString>,
38 class WXDLLIMPEXP_BASE);
39 WX_DEFINE_USER_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase,
40 wxBaseArrayStringBase, WXDLLIMPEXP_BASE);
41 _WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase,
42 wxBaseArrayStringBase, = wxStringSortAscending,
43 class WXDLLIMPEXP_BASE, CMPFUNCwxString);
44
45 class WXDLLIMPEXP_BASE wxArrayString : public wxArrayStringBase
46 {
47 public:
48 // type of function used by wxArrayString::Sort()
49 typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
50 const wxString& second);
51
52 wxArrayString() { }
53 wxArrayString(const wxArrayString& a) : wxArrayStringBase(a) { }
54 wxArrayString(size_t sz, const char** a);
55 wxArrayString(size_t sz, const wchar_t** a);
56 wxArrayString(size_t sz, const wxString* a);
57
58 int Index(const wxString& str, bool bCase = true, bool bFromEnd = false) const;
59
60 void Sort(bool reverseOrder = false);
61 void Sort(CompareFunction function);
62 void Sort(CMPFUNCwxString function) { wxArrayStringBase::Sort(function); }
63
64 size_t Add(const wxString& string, size_t copies = 1)
65 {
66 wxArrayStringBase::Add(string, copies);
67 return size() - copies;
68 }
69 };
70
71 class WXDLLIMPEXP_BASE wxSortedArrayString : public wxSortedArrayStringBase
72 {
73 public:
74 wxSortedArrayString() : wxSortedArrayStringBase(wxStringSortAscending)
75 { }
76 wxSortedArrayString(const wxSortedArrayString& array)
77 : wxSortedArrayStringBase(array)
78 { }
79 wxSortedArrayString(const wxArrayString& src)
80 : wxSortedArrayStringBase(wxStringSortAscending)
81 {
82 reserve(src.size());
83
84 for ( size_t n = 0; n < src.size(); n++ )
85 Add(src[n]);
86 }
87
88 int Index(const wxString& str, bool bCase = true, bool bFromEnd = false) const;
89
90 private:
91 void Insert()
92 {
93 wxFAIL_MSG( "wxSortedArrayString::Insert() is not to be used" );
94 }
95
96 void Sort()
97 {
98 wxFAIL_MSG( "wxSortedArrayString::Sort() is not to be used" );
99 }
100 };
101
102 #else // if !wxUSE_STD_CONTAINERS
103
104 // this shouldn't be defined for compilers not supporting template methods or
105 // without std::distance()
106 //
107 // FIXME-VC6: currently it's only not defined for VC6 in DLL build as it
108 // doesn't export template methods from DLL correctly so even though
109 // it compiles them fine, we get link errors when using wxArrayString
110 #if !defined(__VISUALC6__) || !(defined(WXMAKINGDLL) || defined(WXUSINGDLL))
111 #define wxHAS_VECTOR_TEMPLATE_ASSIGN
112 #endif
113
114 #ifdef wxHAS_VECTOR_TEMPLATE_ASSIGN
115 #include "wx/beforestd.h"
116 #include <iterator>
117 #include "wx/afterstd.h"
118 #endif // wxHAS_VECTOR_TEMPLATE_ASSIGN
119
120 class WXDLLIMPEXP_BASE wxArrayString
121 {
122 public:
123 // type of function used by wxArrayString::Sort()
124 typedef int (wxCMPFUNC_CONV *CompareFunction)(const wxString& first,
125 const wxString& second);
126 // type of function used by wxArrayString::Sort(), for compatibility with
127 // wxArray
128 typedef int (wxCMPFUNC_CONV *CompareFunction2)(wxString* first,
129 wxString* second);
130
131 // constructors and destructor
132 // default ctor
133 wxArrayString() { Init(false); }
134 // if autoSort is true, the array is always sorted (in alphabetical order)
135 //
136 // NB: the reason for using int and not bool is that like this we can avoid
137 // using this ctor for implicit conversions from "const char *" (which
138 // we'd like to be implicitly converted to wxString instead!). This
139 // wouldn't be needed if the 'explicit' keyword was supported by all
140 // compilers, or if this was protected ctor for wxSortedArrayString,
141 // but we're stuck with it now.
142 wxEXPLICIT wxArrayString(int autoSort) { Init(autoSort != 0); }
143 // C string array ctor
144 wxArrayString(size_t sz, const char** a);
145 wxArrayString(size_t sz, const wchar_t** a);
146 // wxString string array ctor
147 wxArrayString(size_t sz, const wxString* a);
148 // copy ctor
149 wxArrayString(const wxArrayString& array);
150 // assignment operator
151 wxArrayString& operator=(const wxArrayString& src);
152 // not virtual, this class should not be derived from
153 ~wxArrayString();
154
155 // memory management
156 // empties the list, but doesn't release memory
157 void Empty();
158 // empties the list and releases memory
159 void Clear();
160 // preallocates memory for given number of items
161 void Alloc(size_t nCount);
162 // minimzes the memory usage (by freeing all extra memory)
163 void Shrink();
164
165 // simple accessors
166 // number of elements in the array
167 size_t GetCount() const { return m_nCount; }
168 // is it empty?
169 bool IsEmpty() const { return m_nCount == 0; }
170 // number of elements in the array (GetCount is preferred API)
171 size_t Count() const { return m_nCount; }
172
173 // items access (range checking is done in debug version)
174 // get item at position uiIndex
175 wxString& Item(size_t nIndex)
176 {
177 wxASSERT_MSG( nIndex < m_nCount,
178 wxT("wxArrayString: index out of bounds") );
179
180 return m_pItems[nIndex];
181 }
182 const wxString& Item(size_t nIndex) const { return const_cast<wxArrayString*>(this)->Item(nIndex); }
183
184 // same as Item()
185 wxString& operator[](size_t nIndex) { return Item(nIndex); }
186 const wxString& operator[](size_t nIndex) const { return Item(nIndex); }
187 // get last item
188 wxString& Last()
189 {
190 wxASSERT_MSG( !IsEmpty(),
191 wxT("wxArrayString: index out of bounds") );
192 return Item(GetCount() - 1);
193 }
194 const wxString& Last() const { return const_cast<wxArrayString*>(this)->Last(); }
195
196
197 // item management
198 // Search the element in the array, starting from the beginning if
199 // bFromEnd is false or from end otherwise. If bCase, comparison is case
200 // sensitive (default). Returns index of the first item matched or
201 // wxNOT_FOUND
202 int Index (const wxString& str, bool bCase = true, bool bFromEnd = false) const;
203 // add new element at the end (if the array is not sorted), return its
204 // index
205 size_t Add(const wxString& str, size_t nInsert = 1);
206 // add new element at given position
207 void Insert(const wxString& str, size_t uiIndex, size_t nInsert = 1);
208 // expand the array to have count elements
209 void SetCount(size_t count);
210 // remove first item matching this value
211 void Remove(const wxString& sz);
212 // remove item by index
213 void RemoveAt(size_t nIndex, size_t nRemove = 1);
214
215 // sorting
216 // sort array elements in alphabetical order (or reversed alphabetical
217 // order if reverseOrder parameter is true)
218 void Sort(bool reverseOrder = false);
219 // sort array elements using specified comparison function
220 void Sort(CompareFunction compareFunction);
221 void Sort(CompareFunction2 compareFunction);
222
223 // comparison
224 // compare two arrays case sensitively
225 bool operator==(const wxArrayString& a) const;
226 // compare two arrays case sensitively
227 bool operator!=(const wxArrayString& a) const { return !(*this == a); }
228
229 // STL-like interface
230 typedef wxString value_type;
231 typedef value_type* pointer;
232 typedef const value_type* const_pointer;
233 typedef value_type* iterator;
234 typedef const value_type* const_iterator;
235 typedef value_type& reference;
236 typedef const value_type& const_reference;
237 typedef int difference_type;
238 typedef size_t size_type;
239
240 // TODO: this code duplicates the one in dynarray.h
241 class reverse_iterator
242 {
243 typedef wxString value_type;
244 typedef value_type* pointer;
245 typedef value_type& reference;
246 typedef reverse_iterator itor;
247 friend itor operator+(int o, const itor& it);
248 friend itor operator+(const itor& it, int o);
249 friend itor operator-(const itor& it, int o);
250 friend difference_type operator -(const itor& i1, const itor& i2);
251 public:
252 pointer m_ptr;
253 reverse_iterator() : m_ptr(NULL) { }
254 wxEXPLICIT reverse_iterator(pointer ptr) : m_ptr(ptr) { }
255 reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
256 reference operator*() const { return *m_ptr; }
257 pointer operator->() const { return m_ptr; }
258 itor& operator++() { --m_ptr; return *this; }
259 const itor operator++(int)
260 { reverse_iterator tmp = *this; --m_ptr; return tmp; }
261 itor& operator--() { ++m_ptr; return *this; }
262 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
263 bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }
264 bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }
265 };
266
267 class const_reverse_iterator
268 {
269 typedef wxString value_type;
270 typedef const value_type* pointer;
271 typedef const value_type& reference;
272 typedef const_reverse_iterator itor;
273 friend itor operator+(int o, const itor& it);
274 friend itor operator+(const itor& it, int o);
275 friend itor operator-(const itor& it, int o);
276 friend difference_type operator -(const itor& i1, const itor& i2);
277 public:
278 pointer m_ptr;
279 const_reverse_iterator() : m_ptr(NULL) { }
280 wxEXPLICIT const_reverse_iterator(pointer ptr) : m_ptr(ptr) { }
281 const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { }
282 const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }
283 reference operator*() const { return *m_ptr; }
284 pointer operator->() const { return m_ptr; }
285 itor& operator++() { --m_ptr; return *this; }
286 const itor operator++(int)
287 { itor tmp = *this; --m_ptr; return tmp; }
288 itor& operator--() { ++m_ptr; return *this; }
289 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }
290 bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }
291 bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }
292 };
293
294 wxArrayString(const_iterator first, const_iterator last)
295 { Init(false); assign(first, last); }
296 wxArrayString(size_type n, const_reference v) { Init(false); assign(n, v); }
297
298 #ifdef wxHAS_VECTOR_TEMPLATE_ASSIGN
299 template <class Iterator>
300 void assign(Iterator first, Iterator last)
301 {
302 clear();
303 reserve(std::distance(first, last));
304 for(; first != last; ++first)
305 push_back(*first);
306 }
307 #else // !wxHAS_VECTOR_TEMPLATE_ASSIGN
308 void assign(const_iterator first, const_iterator last)
309 {
310 clear();
311 reserve(last - first);
312 for(; first != last; ++first)
313 push_back(*first);
314 }
315 #endif // wxHAS_VECTOR_TEMPLATE_ASSIGN/!wxHAS_VECTOR_TEMPLATE_ASSIGN
316
317 void assign(size_type n, const_reference v)
318 { clear(); Add(v, n); }
319 reference back() { return *(end() - 1); }
320 const_reference back() const { return *(end() - 1); }
321 iterator begin() { return m_pItems; }
322 const_iterator begin() const { return m_pItems; }
323 size_type capacity() const { return m_nSize; }
324 void clear() { Clear(); }
325 bool empty() const { return IsEmpty(); }
326 iterator end() { return begin() + GetCount(); }
327 const_iterator end() const { return begin() + GetCount(); }
328 iterator erase(iterator first, iterator last)
329 {
330 size_t idx = first - begin();
331 RemoveAt(idx, last - first);
332 return begin() + idx;
333 }
334 iterator erase(iterator it) { return erase(it, it + 1); }
335 reference front() { return *begin(); }
336 const_reference front() const { return *begin(); }
337 void insert(iterator it, size_type n, const_reference v)
338 { Insert(v, it - begin(), n); }
339 iterator insert(iterator it, const_reference v = value_type())
340 { size_t idx = it - begin(); Insert(v, idx); return begin() + idx; }
341 void insert(iterator it, const_iterator first, const_iterator last);
342 size_type max_size() const { return INT_MAX; }
343 void pop_back() { RemoveAt(GetCount() - 1); }
344 void push_back(const_reference v) { Add(v); }
345 reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
346 const_reverse_iterator rbegin() const
347 { return const_reverse_iterator(end() - 1); }
348 reverse_iterator rend() { return reverse_iterator(begin() - 1); }
349 const_reverse_iterator rend() const
350 { return const_reverse_iterator(begin() - 1); }
351 void reserve(size_type n) /* base::reserve*/;
352 void resize(size_type n, value_type v = value_type());
353 size_type size() const { return GetCount(); }
354 void swap(wxArrayString& other)
355 {
356 wxSwap(m_nSize, other.m_nSize);
357 wxSwap(m_nCount, other.m_nCount);
358 wxSwap(m_pItems, other.m_pItems);
359 wxSwap(m_autoSort, other.m_autoSort);
360 }
361
362 protected:
363 void Init(bool autoSort); // common part of all ctors
364 void Copy(const wxArrayString& src); // copies the contents of another array
365
366 private:
367 void Grow(size_t nIncrement = 0); // makes array bigger if needed
368
369 size_t m_nSize, // current size of the array
370 m_nCount; // current number of elements
371
372 wxString *m_pItems; // pointer to data
373
374 bool m_autoSort; // if true, keep the array always sorted
375 };
376
377 class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString
378 {
379 public:
380 wxSortedArrayString() : wxArrayString(true)
381 { }
382 wxSortedArrayString(const wxArrayString& array) : wxArrayString(true)
383 { Copy(array); }
384 };
385
386 #endif // !wxUSE_STD_CONTAINERS
387
388 // this class provides a temporary wxString* from a
389 // wxArrayString
390 class WXDLLIMPEXP_BASE wxCArrayString
391 {
392 public:
393 wxCArrayString( const wxArrayString& array )
394 : m_array( array ), m_strings( NULL )
395 { }
396 ~wxCArrayString() { delete[] m_strings; }
397
398 size_t GetCount() const { return m_array.GetCount(); }
399 wxString* GetStrings()
400 {
401 if( m_strings ) return m_strings;
402 size_t count = m_array.GetCount();
403 m_strings = new wxString[count];
404 for( size_t i = 0; i < count; ++i )
405 m_strings[i] = m_array[i];
406 return m_strings;
407 }
408
409 wxString* Release()
410 {
411 wxString *r = GetStrings();
412 m_strings = NULL;
413 return r;
414 }
415
416 private:
417 const wxArrayString& m_array;
418 wxString* m_strings;
419 };
420
421
422 // ----------------------------------------------------------------------------
423 // helper functions for working with arrays
424 // ----------------------------------------------------------------------------
425
426 // by default, these functions use the escape character to escape the
427 // separators occurring inside the string to be joined, this can be disabled by
428 // passing '\0' as escape
429
430 WXDLLIMPEXP_BASE wxString wxJoin(const wxArrayString& arr,
431 const wxChar sep,
432 const wxChar escape = wxT('\\'));
433
434 WXDLLIMPEXP_BASE wxArrayString wxSplit(const wxString& str,
435 const wxChar sep,
436 const wxChar escape = wxT('\\'));
437
438
439 // ----------------------------------------------------------------------------
440 // This helper class allows to pass both C array of wxStrings or wxArrayString
441 // using the same interface.
442 //
443 // Use it when you have two methods taking wxArrayString or (int, wxString[]),
444 // that do the same thing. This class lets you iterate over input data in the
445 // same way whether it is a raw array of strings or wxArrayString.
446 //
447 // The object does not take ownership of the data -- internally it keeps
448 // pointers to the data, therefore the data must be disposed of by user
449 // and only after this object is destroyed. Usually it is not a problem as
450 // only temporary objects of this class are used.
451 // ----------------------------------------------------------------------------
452
453 class wxArrayStringsAdapter
454 {
455 public:
456 // construct an adapter from a wxArrayString
457 wxArrayStringsAdapter(const wxArrayString& strings)
458 : m_type(wxSTRING_ARRAY), m_size(strings.size())
459 {
460 m_data.array = &strings;
461 }
462
463 // construct an adapter from a wxString[]
464 wxArrayStringsAdapter(unsigned int n, const wxString *strings)
465 : m_type(wxSTRING_POINTER), m_size(n)
466 {
467 m_data.ptr = strings;
468 }
469
470 // construct an adapter from a single wxString
471 wxArrayStringsAdapter(const wxString& s)
472 : m_type(wxSTRING_POINTER), m_size(1)
473 {
474 m_data.ptr = &s;
475 }
476
477 // default copy constructor is ok
478
479 // iteration interface
480 size_t GetCount() const { return m_size; }
481 bool IsEmpty() const { return GetCount() == 0; }
482 const wxString& operator[] (unsigned int i) const
483 {
484 wxASSERT_MSG( i < GetCount(), wxT("index out of bounds") );
485 if(m_type == wxSTRING_POINTER)
486 return m_data.ptr[i];
487 return m_data.array->Item(i);
488 }
489 wxArrayString AsArrayString() const
490 {
491 if(m_type == wxSTRING_ARRAY)
492 return *m_data.array;
493 return wxArrayString(GetCount(), m_data.ptr);
494 }
495
496 private:
497 // type of the data being held
498 enum wxStringContainerType
499 {
500 wxSTRING_ARRAY, // wxArrayString
501 wxSTRING_POINTER // wxString[]
502 };
503
504 wxStringContainerType m_type;
505 size_t m_size;
506 union
507 {
508 const wxString * ptr;
509 const wxArrayString * array;
510 } m_data;
511
512 wxDECLARE_NO_ASSIGN_CLASS(wxArrayStringsAdapter);
513 };
514
515 #endif // _WX_ARRSTR_H