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