arrstr.h 18 KB

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