]> git.saurik.com Git - wxWidgets.git/blame - include/wx/string.h
wxHTML fixes
[wxWidgets.git] / include / wx / string.h
CommitLineData
3c67202d 1///////////////////////////////////////////////////////////////////////////////
c801d85f 2// Name: string.h
3c67202d 3// Purpose: wxString and wxArrayString classes
c801d85f
KB
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
dd1eaa89 9// Licence: wxWindows license
3c67202d 10///////////////////////////////////////////////////////////////////////////////
c801d85f 11
e90c1d2a
VZ
12/*
13 Efficient string class [more or less] compatible with MFC CString,
14 wxWindows version 1 wxString and std::string and some handy functions
15 missing from string.h.
16*/
17
34138703
JS
18#ifndef _WX_WXSTRINGH__
19#define _WX_WXSTRINGH__
c801d85f
KB
20
21#ifdef __GNUG__
e90c1d2a
VZ
22 #pragma interface "string.h"
23#endif
24
25// ----------------------------------------------------------------------------
26// conditinal compilation
27// ----------------------------------------------------------------------------
28
29// compile the std::string compatibility functions if defined
30#define wxSTD_STRING_COMPATIBILITY
31
32// define to derive wxString from wxObject (deprecated!)
33#ifdef WXSTRING_IS_WXOBJECT
34 #undef WXSTRING_IS_WXOBJECT
c801d85f
KB
35#endif
36
e90c1d2a
VZ
37// ----------------------------------------------------------------------------
38// headers
39// ----------------------------------------------------------------------------
40
9dea36ef 41#if defined(__WXMAC__) || defined(__VISAGECPP__)
3f4a0c5b 42 #include <ctype.h>
17dff81c 43#endif
3f4a0c5b 44
91b8de8d
RR
45#ifdef __EMX__
46 #include <std.h>
47#endif
48
9dea36ef
DW
49#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
50 // problem in VACPP V4 with including stdlib.h multiple times
51 // strconv includes it anyway
52# include <stdio.h>
53# include <string.h>
54# include <stdarg.h>
55# include <limits.h>
56#else
57# include <string.h>
58# include <stdio.h>
59# include <stdarg.h>
60# include <limits.h>
61# include <stdlib.h>
62#endif
c801d85f 63
57493f9f 64#ifdef HAVE_STRINGS_H
1bfcb0b6
VZ
65 #include <strings.h> // for strcasecmp()
66#endif // AIX
67
e90c1d2a 68#include "wx/defs.h" // everybody should include this
e90c1d2a
VZ
69#include "wx/wxchar.h" // for wxChar
70#include "wx/buffer.h" // for wxCharBuffer
71#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
3f4a0c5b 72
e90c1d2a 73#ifndef WX_PRECOMP
dd1eaa89 74 #ifdef WXSTRING_IS_WXOBJECT
e90c1d2a 75 #include "wx/object.h" // base class
dd1eaa89 76 #endif
3f4a0c5b 77#endif // !PCH
8fd0f20b 78
c801d85f
KB
79// ---------------------------------------------------------------------------
80// macros
81// ---------------------------------------------------------------------------
82
c801d85f 83// 'naughty' cast
2bb67b80 84#define WXSTRINGCAST (wxChar *)(const wxChar *)
e90c1d2a
VZ
85#define wxCSTRINGCAST (wxChar *)(const wxChar *)
86#define wxMBSTRINGCAST (char *)(const char *)
87#define wxWCSTRINGCAST (wchar_t *)(const wchar_t *)
c801d85f 88
3c67202d 89// implementation only
b1269691 90#define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) <= Len() )
c801d85f 91
e90c1d2a
VZ
92// ----------------------------------------------------------------------------
93// constants
94// ----------------------------------------------------------------------------
95
66b6b045 96#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
67b81440 97// must define this static for VA or else you get multiply defined symbols everywhere
5d33ed2c 98extern const unsigned int wxSTRING_MAXLEN;
66b6b045
DW
99
100#else
e90c1d2a
VZ
101// maximum possible length for a string means "take all string" everywhere
102// (as sizeof(StringData) is unknown here, we substract 100)
103const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
104
66b6b045
DW
105#endif
106
e90c1d2a
VZ
107// ----------------------------------------------------------------------------
108// global data
109// ----------------------------------------------------------------------------
110
111// global pointer to empty string
112WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
6001e347 113
c801d85f 114// ---------------------------------------------------------------------------
e90c1d2a 115// global functions complementing standard C string library replacements for
3c67202d
VZ
116// strlen() and portable strcasecmp()
117//---------------------------------------------------------------------------
e90c1d2a
VZ
118
119// Use wxXXX() functions from wxchar.h instead! These functions are for
120// backwards compatibility only.
88150e60 121
3c67202d 122// checks whether the passed in pointer is NULL and if the string is empty
6d56eb5c 123inline bool IsEmpty(const char *p) { return (!p || !*p); }
c801d85f 124
3c67202d 125// safe version of strlen() (returns 0 if passed NULL pointer)
6d56eb5c 126inline size_t Strlen(const char *psz)
c801d85f
KB
127 { return psz ? strlen(psz) : 0; }
128
3c67202d 129// portable strcasecmp/_stricmp
6d56eb5c 130inline int Stricmp(const char *psz1, const char *psz2)
dd1eaa89 131{
91b8de8d 132#if defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) )
dd1eaa89 133 return _stricmp(psz1, psz2);
91b8de8d 134#elif defined(__SC__)
2432b92d 135 return _stricmp(psz1, psz2);
91b8de8d 136#elif defined(__SALFORDC__)
a3ef5bf5 137 return stricmp(psz1, psz2);
dd1eaa89
VZ
138#elif defined(__BORLANDC__)
139 return stricmp(psz1, psz2);
7be1f0d9
JS
140#elif defined(__WATCOMC__)
141 return stricmp(psz1, psz2);
91b8de8d
RR
142#elif defined(__EMX__)
143 return stricmp(psz1, psz2);
e2c87f4c 144#elif defined(__WXPM__)
1777b9bb 145 return stricmp(psz1, psz2);
91b8de8d 146#elif defined(__UNIX__) || defined(__GNUWIN32__)
dd1eaa89 147 return strcasecmp(psz1, psz2);
8be97d65 148#elif defined(__MWERKS__) && !defined(__INTEL__)
17dff81c
SC
149 register char c1, c2;
150 do {
151 c1 = tolower(*psz1++);
152 c2 = tolower(*psz2++);
153 } while ( c1 && (c1 == c2) );
154
155 return c1 - c2;
dd1eaa89
VZ
156#else
157 // almost all compilers/libraries provide this function (unfortunately under
158 // different names), that's why we don't implement our own which will surely
159 // be more efficient than this code (uncomment to use):
160 /*
161 register char c1, c2;
162 do {
163 c1 = tolower(*psz1++);
164 c2 = tolower(*psz2++);
165 } while ( c1 && (c1 == c2) );
166
167 return c1 - c2;
168 */
169
170 #error "Please define string case-insensitive compare for your OS/compiler"
171#endif // OS/compiler
172}
c801d85f 173
378b05f7
VZ
174// wxSnprintf() is like snprintf() if it's available and sprintf() (always
175// available, but dangerous!) if not
176extern int WXDLLEXPORT wxSnprintf(wxChar *buf, size_t len,
177 const wxChar *format, ...);
178
179// and wxVsnprintf() is like vsnprintf() or vsprintf()
180extern int WXDLLEXPORT wxVsnprintf(wxChar *buf, size_t len,
181 const wxChar *format, va_list argptr);
182
f04f3991 183// return an empty wxString
f7bd2698 184class WXDLLEXPORT wxString; // not yet defined
e90c1d2a 185inline const wxString& wxGetEmptyString() { return *(wxString *)&wxEmptyString; }
f04f3991 186
c801d85f 187// ---------------------------------------------------------------------------
f04f3991 188// string data prepended with some housekeeping info (used by wxString class),
c801d85f
KB
189// is never used directly (but had to be put here to allow inlining)
190// ---------------------------------------------------------------------------
e90c1d2a 191
c801d85f
KB
192struct WXDLLEXPORT wxStringData
193{
194 int nRefs; // reference count
3c024cc2 195 size_t nDataLength, // actual string length
c801d85f
KB
196 nAllocLength; // allocated memory size
197
2bb67b80
OK
198 // mimics declaration 'wxChar data[nAllocLength]'
199 wxChar* data() const { return (wxChar*)(this + 1); }
c801d85f
KB
200
201 // empty string has a special ref count so it's never deleted
dbda9e86
JS
202 bool IsEmpty() const { return (nRefs == -1); }
203 bool IsShared() const { return (nRefs > 1); }
c801d85f
KB
204
205 // lock/unlock
dd1eaa89 206 void Lock() { if ( !IsEmpty() ) nRefs++; }
f6bcfd97
BP
207
208 // VC++ will refuse to inline this function but profiling shows that it
209 // is wrong
210#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
211 __forceinline
212#endif
dd1eaa89 213 void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
8fd0f20b 214
dd1eaa89 215 // if we had taken control over string memory (GetWriteBuf), it's
8fd0f20b 216 // intentionally put in invalid state
dbda9e86
JS
217 void Validate(bool b) { nRefs = (b ? 1 : 0); }
218 bool IsValid() const { return (nRefs != 0); }
c801d85f
KB
219};
220
c801d85f 221// ---------------------------------------------------------------------------
3c67202d
VZ
222// This is (yet another one) String class for C++ programmers. It doesn't use
223// any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
224// thus you should be able to compile it with practicaly any C++ compiler.
225// This class uses copy-on-write technique, i.e. identical strings share the
226// same memory as long as neither of them is changed.
227//
228// This class aims to be as compatible as possible with the new standard
229// std::string class, but adds some additional functions and should be at
230// least as efficient than the standard implementation.
231//
232// Performance note: it's more efficient to write functions which take "const
233// String&" arguments than "const char *" if you assign the argument to
234// another string.
235//
236// It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
237//
238// To do:
239// - ressource support (string tables in ressources)
240// - more wide character (UNICODE) support
241// - regular expressions support
c801d85f 242// ---------------------------------------------------------------------------
3c67202d 243
c801d85f 244#ifdef WXSTRING_IS_WXOBJECT
3c67202d
VZ
245class WXDLLEXPORT wxString : public wxObject
246{
c801d85f
KB
247 DECLARE_DYNAMIC_CLASS(wxString)
248#else //WXSTRING_IS_WXOBJECT
3c67202d
VZ
249class WXDLLEXPORT wxString
250{
c801d85f
KB
251#endif //WXSTRING_IS_WXOBJECT
252
fbcb4166 253friend class WXDLLEXPORT wxArrayString;
c801d85f 254
3c67202d
VZ
255 // NB: special care was taken in arranging the member functions in such order
256 // that all inline functions can be effectively inlined, verify that all
257 // performace critical functions are still inlined if you change order!
dd1eaa89
VZ
258private:
259 // points to data preceded by wxStringData structure with ref count info
2bb67b80 260 wxChar *m_pchData;
dd1eaa89
VZ
261
262 // accessor to string data
263 wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
264
6b95b20d
VZ
265 // string (re)initialization functions
266 // initializes the string to the empty value (must be called only from
267 // ctors, use Reinit() otherwise)
e90c1d2a 268 void Init() { m_pchData = (wxChar *)wxEmptyString; }
6b95b20d 269 // initializaes the string with (a part of) C-string
2bb67b80 270 void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = wxSTRING_MAXLEN);
6b95b20d
VZ
271 // as Init, but also frees old data
272 void Reinit() { GetStringData()->Unlock(); Init(); }
273
274 // memory allocation
275 // allocates memory for string of lenght nLen
276 void AllocBuffer(size_t nLen);
277 // copies data to another string
278 void AllocCopy(wxString&, int, int) const;
279 // effectively copies data to string
2bb67b80 280 void AssignCopy(size_t, const wxChar *);
6b95b20d
VZ
281
282 // append a (sub)string
2bb67b80 283 void ConcatSelf(int nLen, const wxChar *src);
6b95b20d
VZ
284
285 // functions called before writing to the string: they copy it if there
286 // are other references to our data (should be the only owner when writing)
287 void CopyBeforeWrite();
288 void AllocBeforeWrite(size_t);
289
c606a9a4
VZ
290 // this method is not implemented - there is _no_ conversion from int to
291 // string, you're doing something wrong if the compiler wants to call it!
292 //
293 // try `s << i' or `s.Printf("%d", i)' instead
294 wxString(int);
3ce65f6c 295 wxString(unsigned int);
c606a9a4 296 wxString(long);
3ce65f6c 297 wxString(unsigned long);
c606a9a4 298
c801d85f 299public:
3c67202d
VZ
300 // constructors and destructor
301 // ctor for an empty string
6b95b20d 302 wxString() { Init(); }
3c67202d 303 // copy ctor
6b95b20d
VZ
304 wxString(const wxString& stringSrc)
305 {
306 wxASSERT( stringSrc.GetStringData()->IsValid() );
307
308 if ( stringSrc.IsEmpty() ) {
309 // nothing to do for an empty string
310 Init();
311 }
312 else {
313 m_pchData = stringSrc.m_pchData; // share same data
314 GetStringData()->Lock(); // => one more copy
315 }
316 }
3c67202d 317 // string containing nRepeat copies of ch
2bb67b80 318 wxString(wxChar ch, size_t nRepeat = 1);
3c67202d 319 // ctor takes first nLength characters from C string
566b84d2 320 // (default value of wxSTRING_MAXLEN means take all the string)
2bb67b80 321 wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN)
6b95b20d 322 { InitWith(psz, 0, nLength); }
f6bcfd97
BP
323 wxString(const wxChar *psz, wxMBConv& WXUNUSED(conv), size_t nLength = wxSTRING_MAXLEN)
324 { InitWith(psz, 0, nLength); }
e90c1d2a 325
2bb67b80
OK
326#if wxUSE_UNICODE
327 // from multibyte string
328 // (NB: nLength is right now number of Unicode characters, not
329 // characters in psz! So try not to use it yet!)
5f709e67 330 wxString(const char *psz, wxMBConv& conv = wxConvLibc, size_t nLength = wxSTRING_MAXLEN);
2bb67b80
OK
331 // from wxWCharBuffer (i.e. return from wxGetString)
332 wxString(const wxWCharBuffer& psz)
333 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a 334#else // ANSI
3c67202d 335 // from C string (for compilers using unsigned char)
2bb67b80
OK
336 wxString(const unsigned char* psz, size_t nLength = wxSTRING_MAXLEN)
337 { InitWith((const char*)psz, 0, nLength); }
e90c1d2a 338
6f841509 339#if wxUSE_WCHAR_T
2bb67b80 340 // from wide (Unicode) string
f6bcfd97 341 wxString(const wchar_t *pwz, wxMBConv& conv = wxConvLibc);
e90c1d2a
VZ
342#endif // !wxUSE_WCHAR_T
343
2bb67b80
OK
344 // from wxCharBuffer
345 wxString(const wxCharBuffer& psz)
346 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a
VZ
347#endif // Unicode/ANSI
348
3c67202d 349 // dtor is not virtual, this class must not be inherited from!
6b95b20d 350 ~wxString() { GetStringData()->Unlock(); }
c801d85f 351
3c67202d
VZ
352 // generic attributes & operations
353 // as standard strlen()
47d67540 354 size_t Len() const { return GetStringData()->nDataLength; }
3c67202d 355 // string contains any characters?
dd1eaa89 356 bool IsEmpty() const { return Len() == 0; }
dcfde592
VZ
357 // empty string is "FALSE", so !str will return TRUE
358 bool operator!() const { return IsEmpty(); }
3c67202d 359 // empty string contents
dd1eaa89
VZ
360 void Empty()
361 {
2c3b684c 362 if ( !IsEmpty() )
dd1eaa89
VZ
363 Reinit();
364
7be07660 365 // should be empty
dd1eaa89 366 wxASSERT( GetStringData()->nDataLength == 0 );
7be07660 367 }
3c67202d 368 // empty the string and free memory
7be07660
VZ
369 void Clear()
370 {
371 if ( !GetStringData()->IsEmpty() )
372 Reinit();
373
374 wxASSERT( GetStringData()->nDataLength == 0 ); // should be empty
375 wxASSERT( GetStringData()->nAllocLength == 0 ); // and not own any memory
dd1eaa89
VZ
376 }
377
3c67202d
VZ
378 // contents test
379 // Is an ascii value
c801d85f 380 bool IsAscii() const;
3c67202d 381 // Is a number
c801d85f 382 bool IsNumber() const;
3c67202d 383 // Is a word
c801d85f 384 bool IsWord() const;
c801d85f 385
3c67202d
VZ
386 // data access (all indexes are 0 based)
387 // read access
2bb67b80 388 wxChar GetChar(size_t n) const
dd1eaa89 389 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
3c67202d 390 // read/write access
2bb67b80 391 wxChar& GetWritableChar(size_t n)
dd1eaa89 392 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
3c67202d 393 // write access
2bb67b80 394 void SetChar(size_t n, wxChar ch)
c801d85f
KB
395 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
396
3c67202d 397 // get last character
2bb67b80 398 wxChar Last() const
c801d85f 399 { wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
3c67202d 400 // get writable last character
2bb67b80 401 wxChar& Last()
c801d85f
KB
402 { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
403
d836ee96
VZ
404 /*
405 So why do we have all these overloaded operator[]s? A bit of history:
406 initially there was only one of them, taking size_t. Then people
407 started complaining because they wanted to use ints as indices (I
408 wonder why) and compilers were giving warnings about it, so we had to
409 add the operator[](int). Then it became apparent that you couldn't
410 write str[0] any longer because there was ambiguity between two
411 overloads and so you now had to write str[0u] (or, of course, use the
412 explicit casts to either int or size_t but nobody did this).
413
414 Finally, someone decided to compile wxWin on an Alpha machine and got
415 a surprize: str[0u] didn't compile there because it is of type
416 unsigned int and size_t is unsigned _long_ on Alpha and so there was
417 ambiguity between converting uint to int or ulong. To fix this one we
418 now add operator[](uint) for the machines where size_t is not already
419 the same as unsigned int - hopefully this fixes the problem (for some
420 time)
421
422 The only real fix is, of course, to remove all versions but the one
423 taking size_t...
424 */
425
3c67202d 426 // operator version of GetChar
2bb67b80 427 wxChar operator[](size_t n) const
c801d85f 428 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
c5248639 429
3c67202d 430 // operator version of GetChar
2bb67b80 431 wxChar operator[](int n) const
c801d85f 432 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
cd0b1709 433
f83db661 434 // operator version of GetWriteableChar
2bb67b80 435 wxChar& operator[](size_t n)
c801d85f 436 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96
VZ
437
438#ifndef wxSIZE_T_IS_UINT
439 // operator version of GetChar
440 wxChar operator[](unsigned int n) const
441 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
442
f83db661 443 // operator version of GetWriteableChar
d836ee96 444 wxChar& operator[](unsigned int n)
f83db661 445 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96 446#endif // size_t != unsigned int
c801d85f 447
3c67202d 448 // implicit conversion to C string
2bb67b80 449 operator const wxChar*() const { return m_pchData; }
3c67202d 450 // explicit conversion to C string (use this with printf()!)
2bb67b80 451 const wxChar* c_str() const { return m_pchData; }
f6bcfd97 452 // identical to c_str()
6f841509 453 const wxChar* wx_str() const { return m_pchData; }
e90c1d2a 454 // identical to c_str()
2bb67b80 455 const wxChar* GetData() const { return m_pchData; }
e90c1d2a
VZ
456
457 // conversions with (possible) format convertions: have to return a
458 // buffer with temporary data
f6bcfd97
BP
459 //
460 // the functions defined (in either Unicode or ANSI) mode are mb_str() to
461 // return an ANSI (multibyte) string, wc_str() to return a wide string and
462 // fn_str() to return a string which should be used with the OS APIs
463 // accepting the file names. The return value is always the same, but the
464 // type differs because a function may either return pointer to the buffer
465 // directly or have to use intermediate buffer for translation.
2bb67b80 466#if wxUSE_UNICODE
f6bcfd97
BP
467 const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const
468 { return conv.cWC2MB(m_pchData); }
469
e90c1d2a
VZ
470 const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
471
f6bcfd97
BP
472 const wxChar* wc_str() const { return m_pchData; }
473
474 // for compatibility with !wxUSE_UNICODE version
475 const wxChar* wc_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
e90c1d2a 476
2bb67b80 477#if wxMBFILES
5f709e67 478 const wxCharBuffer fn_str() const { return mb_str(wxConvFile); }
e90c1d2a 479#else // !wxMBFILES
2bb67b80 480 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a
VZ
481#endif // wxMBFILES/!wxMBFILES
482#else // ANSI
e90c1d2a 483 const wxChar* mb_str() const { return m_pchData; }
f6bcfd97
BP
484
485 // for compatibility with wxUSE_UNICODE version
486 const wxChar* mb_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
487
e90c1d2a 488 const wxWX2MBbuf mbc_str() const { return mb_str(); }
f6bcfd97 489
6f841509 490#if wxUSE_WCHAR_T
f6bcfd97
BP
491 const wxWCharBuffer wc_str(wxMBConv& conv) const
492 { return conv.cMB2WC(m_pchData); }
e90c1d2a 493#endif // wxUSE_WCHAR_T
f6bcfd97 494
2bb67b80 495 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a 496#endif // Unicode/ANSI
c801d85f 497
3c67202d
VZ
498 // overloaded assignment
499 // from another wxString
c801d85f 500 wxString& operator=(const wxString& stringSrc);
3c67202d 501 // from a character
2bb67b80 502 wxString& operator=(wxChar ch);
3c67202d 503 // from a C string
2bb67b80 504 wxString& operator=(const wxChar *psz);
111bb7f2
OK
505#if wxUSE_UNICODE
506 // from wxWCharBuffer
507 wxString& operator=(const wxWCharBuffer& psz) { return operator=((const wchar_t *)psz); }
e90c1d2a 508#else // ANSI
3c67202d 509 // from another kind of C string
c801d85f 510 wxString& operator=(const unsigned char* psz);
6f841509 511#if wxUSE_WCHAR_T
3c67202d 512 // from a wide string
c801d85f 513 wxString& operator=(const wchar_t *pwz);
6f841509 514#endif
111bb7f2
OK
515 // from wxCharBuffer
516 wxString& operator=(const wxCharBuffer& psz) { return operator=((const char *)psz); }
e90c1d2a 517#endif // Unicode/ANSI
3c67202d
VZ
518
519 // string concatenation
520 // in place concatenation
521 /*
522 Concatenate and return the result. Note that the left to right
523 associativity of << allows to write things like "str << str1 << str2
524 << ..." (unlike with +=)
525 */
526 // string += string
dd1eaa89
VZ
527 wxString& operator<<(const wxString& s)
528 {
529 wxASSERT( s.GetStringData()->IsValid() );
530
531 ConcatSelf(s.Len(), s);
532 return *this;
533 }
3c67202d 534 // string += C string
2bb67b80
OK
535 wxString& operator<<(const wxChar *psz)
536 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 537 // string += char
2bb67b80 538 wxString& operator<<(wxChar ch) { ConcatSelf(1, &ch); return *this; }
dd1eaa89 539
3c67202d 540 // string += string
6b95b20d 541 void operator+=(const wxString& s) { (void)operator<<(s); }
3c67202d 542 // string += C string
2bb67b80 543 void operator+=(const wxChar *psz) { (void)operator<<(psz); }
3c67202d 544 // string += char
2bb67b80
OK
545 void operator+=(wxChar ch) { (void)operator<<(ch); }
546
547 // string += buffer (i.e. from wxGetString)
548#if wxUSE_UNICODE
549 wxString& operator<<(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); return *this; }
550 void operator+=(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); }
551#else
552 wxString& operator<<(const wxCharBuffer& s) { (void)operator<<((const char *)s); return *this; }
553 void operator+=(const wxCharBuffer& s) { (void)operator<<((const char *)s); }
554#endif
6b95b20d 555
3c67202d 556 // string += C string
2bb67b80
OK
557 wxString& Append(const wxChar* psz)
558 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 559 // append count copies of given character
2bb67b80 560 wxString& Append(wxChar ch, size_t count = 1u)
3c67202d 561 { wxString str(ch, count); return *this << str; }
8f06a017
RD
562 wxString& Append(const wxChar* psz, size_t nLen)
563 { ConcatSelf(nLen, psz); return *this; }
3c67202d
VZ
564
565 // prepend a string, return the string itself
566 wxString& Prepend(const wxString& str)
567 { *this = str + *this; return *this; }
568
569 // non-destructive concatenation
570 //
c33534e5 571 friend wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
3c67202d 572 //
2bb67b80 573 friend wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
3c67202d 574 //
2bb67b80 575 friend wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
3c67202d 576 //
2bb67b80 577 friend wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
3c67202d 578 //
2bb67b80 579 friend wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
3c67202d
VZ
580
581 // stream-like functions
582 // insert an int into string
3ce65f6c
VZ
583 wxString& operator<<(int i)
584 { return (*this) << Format(_T("%d"), i); }
585 // insert an unsigned int into string
586 wxString& operator<<(unsigned int ui)
587 { return (*this) << Format(_T("%u"), ui); }
588 // insert a long into string
589 wxString& operator<<(long l)
590 { return (*this) << Format(_T("%ld"), l); }
591 // insert an unsigned long into string
592 wxString& operator<<(unsigned long ul)
593 { return (*this) << Format(_T("%lu"), ul); }
3c67202d 594 // insert a float into string
3ce65f6c
VZ
595 wxString& operator<<(float f)
596 { return (*this) << Format(_T("%f"), f); }
3c67202d 597 // insert a double into string
3ce65f6c
VZ
598 wxString& operator<<(double d)
599 { return (*this) << Format(_T("%g"), d); }
c84c52de 600
3c67202d 601 // string comparison
30b21f9a 602 // case-sensitive comparison (returns a value < 0, = 0 or > 0)
f33fee2a 603 int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); }
3c67202d 604 // same as Cmp() but not case-sensitive
f33fee2a 605 int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); }
3c67202d
VZ
606 // test for the string equality, either considering case or not
607 // (if compareWithCase then the case matters)
2bb67b80 608 bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const
3c67202d 609 { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
f33fee2a
VZ
610 // comparison with a signle character: returns TRUE if equal
611 bool IsSameAs(wxChar c, bool compareWithCase = TRUE) const
612 {
613 return (Len() == 1) && (compareWithCase ? GetChar(0u) == c
614 : wxToupper(GetChar(0u)) == wxToupper(c));
615 }
3c67202d
VZ
616
617 // simple sub-string extraction
618 // return substring starting at nFirst of length nCount (or till the end
619 // if nCount = default value)
566b84d2 620 wxString Mid(size_t nFirst, size_t nCount = wxSTRING_MAXLEN) const;
3c67202d 621
f6bcfd97 622 // operator version of Mid()
3c67202d
VZ
623 wxString operator()(size_t start, size_t len) const
624 { return Mid(start, len); }
625
f6bcfd97
BP
626 // check that the tring starts with prefix and return the rest of the
627 // string in the provided pointer if it is not NULL, otherwise return
628 // FALSE
629 bool StartsWith(const wxChar *prefix, wxString *rest = NULL) const;
630
3c67202d 631 // get first nCount characters
c801d85f 632 wxString Left(size_t nCount) const;
3c67202d 633 // get last nCount characters
c801d85f 634 wxString Right(size_t nCount) const;
3c67202d
VZ
635 // get all characters before the first occurence of ch
636 // (returns the whole string if ch not found)
2bb67b80 637 wxString BeforeFirst(wxChar ch) const;
3c67202d
VZ
638 // get all characters before the last occurence of ch
639 // (returns empty string if ch not found)
2bb67b80 640 wxString BeforeLast(wxChar ch) const;
3c67202d
VZ
641 // get all characters after the first occurence of ch
642 // (returns empty string if ch not found)
2bb67b80 643 wxString AfterFirst(wxChar ch) const;
3c67202d
VZ
644 // get all characters after the last occurence of ch
645 // (returns the whole string if ch not found)
2bb67b80 646 wxString AfterLast(wxChar ch) const;
3c67202d
VZ
647
648 // for compatibility only, use more explicitly named functions above
2bb67b80
OK
649 wxString Before(wxChar ch) const { return BeforeLast(ch); }
650 wxString After(wxChar ch) const { return AfterFirst(ch); }
3c67202d
VZ
651
652 // case conversion
c84c52de 653 // convert to upper case in place, return the string itself
c801d85f 654 wxString& MakeUpper();
c84c52de 655 // convert to upper case, return the copy of the string
03ab016d
JS
656 // Here's something to remember: BC++ doesn't like returns in inlines.
657 wxString Upper() const ;
c84c52de 658 // convert to lower case in place, return the string itself
c801d85f 659 wxString& MakeLower();
c84c52de 660 // convert to lower case, return the copy of the string
03ab016d 661 wxString Lower() const ;
c801d85f 662
3c67202d
VZ
663 // trimming/padding whitespace (either side) and truncating
664 // remove spaces from left or from right (default) side
c801d85f 665 wxString& Trim(bool bFromRight = TRUE);
3c67202d 666 // add nCount copies chPad in the beginning or at the end (default)
223d09f6 667 wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = TRUE);
3c67202d 668 // truncate string to given length
c801d85f 669 wxString& Truncate(size_t uiLen);
dd1eaa89 670
3c67202d
VZ
671 // searching and replacing
672 // searching (return starting index, or -1 if not found)
2bb67b80 673 int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
3c67202d 674 // searching (return starting index, or -1 if not found)
2bb67b80 675 int Find(const wxChar *pszSub) const; // like strstr
3c67202d
VZ
676 // replace first (or all of bReplaceAll) occurences of substring with
677 // another string, returns the number of replacements made
2bb67b80
OK
678 size_t Replace(const wxChar *szOld,
679 const wxChar *szNew,
3c67202d
VZ
680 bool bReplaceAll = TRUE);
681
682 // check if the string contents matches a mask containing '*' and '?'
2bb67b80 683 bool Matches(const wxChar *szMask) const;
c801d85f 684
cd0b1709
VZ
685 // conversion to numbers: all functions return TRUE only if the whole string
686 // is a number and put the value of this number into the pointer provided
687 // convert to a signed integer
688 bool ToLong(long *val) const;
689 // convert to an unsigned integer
690 bool ToULong(unsigned long *val) const;
691 // convert to a double
692 bool ToDouble(double *val) const;
693
3c67202d
VZ
694 // formated input/output
695 // as sprintf(), returns the number of characters written or < 0 on error
2bb67b80 696 int Printf(const wxChar *pszFormat, ...);
3c67202d 697 // as vprintf(), returns the number of characters written or < 0 on error
2bb67b80 698 int PrintfV(const wxChar* pszFormat, va_list argptr);
dd1eaa89 699
341e7d28
VZ
700 // returns the string containing the result of Printf() to it
701 static wxString Format(const wxChar *pszFormat, ...);
702 // the same as above, but takes a va_list
703 static wxString FormatV(const wxChar *pszFormat, va_list argptr);
704
3c67202d
VZ
705 // raw access to string memory
706 // ensure that string has space for at least nLen characters
dd1eaa89 707 // only works if the data of this string is not shared
c86f1403 708 void Alloc(size_t nLen);
3c67202d 709 // minimize the string's memory
dd1eaa89
VZ
710 // only works if the data of this string is not shared
711 void Shrink();
3c67202d
VZ
712 // get writable buffer of at least nLen bytes. Unget() *must* be called
713 // a.s.a.p. to put string back in a reasonable state!
2bb67b80 714 wxChar *GetWriteBuf(size_t nLen);
3c67202d 715 // call this immediately after GetWriteBuf() has been used
8fd0f20b 716 void UngetWriteBuf();
8f06a017 717 void UngetWriteBuf(size_t nLen);
c801d85f 718
3c67202d
VZ
719 // wxWindows version 1 compatibility functions
720
721 // use Mid()
722 wxString SubString(size_t from, size_t to) const
723 { return Mid(from, (to - from + 1)); }
724 // values for second parameter of CompareTo function
c801d85f 725 enum caseCompare {exact, ignoreCase};
3c67202d 726 // values for first parameter of Strip function
c801d85f 727 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
8870c26e 728
3c67202d 729 // use Printf()
2bb67b80 730 int sprintf(const wxChar *pszFormat, ...);
c801d85f 731
3c67202d 732 // use Cmp()
2bb67b80 733 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
6b95b20d 734 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
c801d85f 735
3c67202d 736 // use Len
c801d85f 737 size_t Length() const { return Len(); }
3c67202d 738 // Count the number of characters
2bb67b80 739 int Freq(wxChar ch) const;
3c67202d 740 // use MakeLower
c801d85f 741 void LowerCase() { MakeLower(); }
3c67202d 742 // use MakeUpper
c801d85f 743 void UpperCase() { MakeUpper(); }
3c67202d 744 // use Trim except that it doesn't change this string
c801d85f
KB
745 wxString Strip(stripType w = trailing) const;
746
3c67202d 747 // use Find (more general variants not yet supported)
2bb67b80
OK
748 size_t Index(const wxChar* psz) const { return Find(psz); }
749 size_t Index(wxChar ch) const { return Find(ch); }
3c67202d 750 // use Truncate
c801d85f 751 wxString& Remove(size_t pos) { return Truncate(pos); }
28a156b1 752 wxString& RemoveLast(size_t n = 1) { return Truncate(Len() - n); }
c801d85f 753
3ed358cb 754 wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
dd1eaa89 755
3c67202d 756 // use Find()
2bb67b80
OK
757 int First( const wxChar ch ) const { return Find(ch); }
758 int First( const wxChar* psz ) const { return Find(psz); }
3ed358cb 759 int First( const wxString &str ) const { return Find(str); }
2bb67b80 760 int Last( const wxChar ch ) const { return Find(ch, TRUE); }
3c67202d 761 bool Contains(const wxString& str) const { return Find(str) != -1; }
c801d85f 762
3c67202d 763 // use IsEmpty()
c801d85f 764 bool IsNull() const { return IsEmpty(); }
c801d85f 765
3c67202d
VZ
766#ifdef wxSTD_STRING_COMPATIBILITY
767 // std::string compatibility functions
dd1eaa89 768
2bc07607
VZ
769 // standard types
770 typedef wxChar value_type;
771 typedef const value_type *const_iterator;
772
3c67202d 773 // an 'invalid' value for string index
c801d85f 774 static const size_t npos;
dd1eaa89 775
3c67202d
VZ
776 // constructors
777 // take nLen chars starting at nPos
778 wxString(const wxString& str, size_t nPos, size_t nLen)
779 {
780 wxASSERT( str.GetStringData()->IsValid() );
781 InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen);
782 }
783 // take all characters from pStart to pEnd
784 wxString(const void *pStart, const void *pEnd);
785
786 // lib.string.capacity
787 // return the length of the string
788 size_t size() const { return Len(); }
789 // return the length of the string
790 size_t length() const { return Len(); }
791 // return the maximum size of the string
566b84d2 792 size_t max_size() const { return wxSTRING_MAXLEN; }
3c67202d 793 // resize the string, filling the space with c if c != 0
223d09f6 794 void resize(size_t nSize, wxChar ch = wxT('\0'));
3c67202d
VZ
795 // delete the contents of the string
796 void clear() { Empty(); }
797 // returns true if the string is empty
798 bool empty() const { return IsEmpty(); }
252a752e
VZ
799 // inform string about planned change in size
800 void reserve(size_t size) { Alloc(size); }
3c67202d
VZ
801
802 // lib.string.access
803 // return the character at position n
2bb67b80 804 wxChar at(size_t n) const { return GetChar(n); }
3c67202d 805 // returns the writable character at position n
2bb67b80 806 wxChar& at(size_t n) { return GetWritableChar(n); }
3c67202d 807
2bc07607
VZ
808 // first valid index position
809 const_iterator begin() const { return wx_str(); }
810 // position one after the last valid one
811 const_iterator end() const { return wx_str() + length(); }
812
3c67202d
VZ
813 // lib.string.modifiers
814 // append a string
815 wxString& append(const wxString& str)
816 { *this += str; return *this; }
817 // append elements str[pos], ..., str[pos+n]
818 wxString& append(const wxString& str, size_t pos, size_t n)
819 { ConcatSelf(n, str.c_str() + pos); return *this; }
820 // append first n (or all if n == npos) characters of sz
2bb67b80
OK
821 wxString& append(const wxChar *sz, size_t n = npos)
822 { ConcatSelf(n == npos ? wxStrlen(sz) : n, sz); return *this; }
3c67202d
VZ
823
824 // append n copies of ch
2bb67b80 825 wxString& append(size_t n, wxChar ch) { return Pad(n, ch); }
3c67202d
VZ
826
827 // same as `this_string = str'
828 wxString& assign(const wxString& str) { return (*this) = str; }
829 // same as ` = str[pos..pos + n]
830 wxString& assign(const wxString& str, size_t pos, size_t n)
2bb67b80 831 { return *this = wxString((const wxChar *)str + pos, n); }
3c67202d 832 // same as `= first n (or all if n == npos) characters of sz'
2bb67b80 833 wxString& assign(const wxChar *sz, size_t n = npos)
3c67202d
VZ
834 { return *this = wxString(sz, n); }
835 // same as `= n copies of ch'
2bb67b80 836 wxString& assign(size_t n, wxChar ch)
3c67202d
VZ
837 { return *this = wxString(ch, n); }
838
839 // insert another string
840 wxString& insert(size_t nPos, const wxString& str);
841 // insert n chars of str starting at nStart (in str)
842 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
2bb67b80 843 { return insert(nPos, wxString((const wxChar *)str + nStart, n)); }
3c67202d
VZ
844
845 // insert first n (or all if n == npos) characters of sz
2bb67b80 846 wxString& insert(size_t nPos, const wxChar *sz, size_t n = npos)
3c67202d
VZ
847 { return insert(nPos, wxString(sz, n)); }
848 // insert n copies of ch
2bb67b80 849 wxString& insert(size_t nPos, size_t n, wxChar ch)
3c67202d
VZ
850 { return insert(nPos, wxString(ch, n)); }
851
852 // delete characters from nStart to nStart + nLen
853 wxString& erase(size_t nStart = 0, size_t nLen = npos);
854
855 // replaces the substring of length nLen starting at nStart
2bb67b80 856 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz);
3c67202d 857 // replaces the substring with nCount copies of ch
2bb67b80 858 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
3c67202d
VZ
859 // replaces a substring with another substring
860 wxString& replace(size_t nStart, size_t nLen,
861 const wxString& str, size_t nStart2, size_t nLen2);
862 // replaces the substring with first nCount chars of sz
fb20fa43
VZ
863 wxString& replace(size_t nStart, size_t nLen,
864 const wxChar* sz, size_t nCount);
3c67202d
VZ
865
866 // swap two strings
867 void swap(wxString& str);
868
869 // All find() functions take the nStart argument which specifies the
870 // position to start the search on, the default value is 0. All functions
871 // return npos if there were no match.
872
873 // find a substring
874 size_t find(const wxString& str, size_t nStart = 0) const;
875
876 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 877#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 878 // find first n characters of sz
2bb67b80 879 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
fb20fa43 880#endif // VC++ 1.5
3c67202d
VZ
881
882 // Gives a duplicate symbol (presumably a case-insensitivity problem)
62448488 883#if !defined(__BORLANDC__)
3c67202d 884 // find the first occurence of character ch after nStart
2bb67b80 885 size_t find(wxChar ch, size_t nStart = 0) const;
62448488 886#endif
3c67202d
VZ
887 // rfind() family is exactly like find() but works right to left
888
889 // as find, but from the end
890 size_t rfind(const wxString& str, size_t nStart = npos) const;
891
892 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 893#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 894 // as find, but from the end
2bb67b80 895 size_t rfind(const wxChar* sz, size_t nStart = npos,
3c67202d
VZ
896 size_t n = npos) const;
897 // as find, but from the end
2bb67b80 898 size_t rfind(wxChar ch, size_t nStart = npos) const;
fb20fa43 899#endif // VC++ 1.5
3c67202d
VZ
900
901 // find first/last occurence of any character in the set
902
969d318c
VZ
903 // as strpbrk() but starts at nStart, returns npos if not found
904 size_t find_first_of(const wxString& str, size_t nStart = 0) const
905 { return find_first_of(str.c_str(), nStart); }
906 // same as above
2bb67b80 907 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
3c67202d 908 // same as find(char, size_t)
969d318c
VZ
909 size_t find_first_of(wxChar c, size_t nStart = 0) const
910 { return find(c, nStart); }
911 // find the last (starting from nStart) char from str in this string
912 size_t find_last_of (const wxString& str, size_t nStart = npos) const
913 { return find_last_of(str.c_str(), nStart); }
914 // same as above
915 size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
916 // same as above
917 size_t find_last_of(wxChar c, size_t nStart = npos) const
918 { return rfind(c, nStart); }
3c67202d
VZ
919
920 // find first/last occurence of any character not in the set
921
969d318c
VZ
922 // as strspn() (starting from nStart), returns npos on failure
923 size_t find_first_not_of(const wxString& str, size_t nStart = 0) const
924 { return find_first_not_of(str.c_str(), nStart); }
925 // same as above
926 size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
927 // same as above
2bb67b80 928 size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
969d318c 929 // as strcspn()
fb20fa43
VZ
930 size_t find_last_not_of(const wxString& str, size_t nStart = npos) const
931 { return find_first_not_of(str.c_str(), nStart); }
969d318c
VZ
932 // same as above
933 size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
934 // same as above
2bb67b80 935 size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
3c67202d
VZ
936
937 // All compare functions return -1, 0 or 1 if the [sub]string is less,
938 // equal or greater than the compare() argument.
939
940 // just like strcmp()
941 int compare(const wxString& str) const { return Cmp(str); }
942 // comparison with a substring
fb20fa43
VZ
943 int compare(size_t nStart, size_t nLen, const wxString& str) const
944 { return Mid(nStart, nLen).Cmp(str); }
3c67202d
VZ
945 // comparison of 2 substrings
946 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
947 const wxString& str, size_t nStart2, size_t nLen2) const
948 { return Mid(nStart, nLen).Cmp(str.Mid(nStart2, nLen2)); }
3c67202d 949 // just like strcmp()
2bb67b80 950 int compare(const wxChar* sz) const { return Cmp(sz); }
3c67202d
VZ
951 // substring comparison with first nCount characters of sz
952 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
953 const wxChar* sz, size_t nCount = npos) const
954 { return Mid(nStart, nLen).Cmp(wxString(sz, nCount)); }
3c67202d
VZ
955
956 // substring extraction
8c264b23
VZ
957 wxString substr(size_t nStart = 0, size_t nLen = npos) const
958 { return Mid(nStart, nLen); }
3c67202d 959#endif // wxSTD_STRING_COMPATIBILITY
c801d85f
KB
960};
961
962// ----------------------------------------------------------------------------
3c67202d
VZ
963// The string array uses it's knowledge of internal structure of the wxString
964// class to optimize string storage. Normally, we would store pointers to
965// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
966// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
967// really all we need to turn such pointer into a string!
968//
969// Of course, it can be called a dirty hack, but we use twice less memory and
970// this approach is also more speed efficient, so it's probably worth it.
971//
972// Usage notes: when a string is added/inserted, a new copy of it is created,
973// so the original string may be safely deleted. When a string is retrieved
974// from the array (operator[] or Item() method), a reference is returned.
c801d85f 975// ----------------------------------------------------------------------------
e90c1d2a 976
fbcb4166 977class WXDLLEXPORT wxArrayString
c801d85f
KB
978{
979public:
30b21f9a
VZ
980 // type of function used by wxArrayString::Sort()
981 typedef int (*CompareFunction)(const wxString& first,
982 const wxString& second);
983
3c67202d 984 // constructors and destructor
e87271f3
VZ
985 // default ctor: if autoSort is TRUE, the array is always sorted (in
986 // alphabetical order)
987 wxArrayString(bool autoSort = FALSE);
3c67202d 988 // copy ctor
c801d85f 989 wxArrayString(const wxArrayString& array);
3c67202d 990 // assignment operator
c801d85f 991 wxArrayString& operator=(const wxArrayString& src);
3c67202d 992 // not virtual, this class should not be derived from
c801d85f 993 ~wxArrayString();
c801d85f 994
3c67202d
VZ
995 // memory management
996 // empties the list, but doesn't release memory
c801d85f 997 void Empty();
3c67202d 998 // empties the list and releases memory
c801d85f 999 void Clear();
3c67202d 1000 // preallocates memory for given number of items
c801d85f 1001 void Alloc(size_t nCount);
3c67202d 1002 // minimzes the memory usage (by freeing all extra memory)
dd1eaa89 1003 void Shrink();
3c67202d
VZ
1004
1005 // simple accessors
1006 // number of elements in the array
1007 size_t GetCount() const { return m_nCount; }
1008 // is it empty?
1009 bool IsEmpty() const { return m_nCount == 0; }
1010 // number of elements in the array (GetCount is preferred API)
1011 size_t Count() const { return m_nCount; }
1012
1013 // items access (range checking is done in debug version)
1014 // get item at position uiIndex
c801d85f
KB
1015 wxString& Item(size_t nIndex) const
1016 { wxASSERT( nIndex < m_nCount ); return *(wxString *)&(m_pItems[nIndex]); }
3c67202d 1017 // same as Item()
c801d85f 1018 wxString& operator[](size_t nIndex) const { return Item(nIndex); }
3c67202d 1019 // get last item
c801d85f 1020 wxString& Last() const { wxASSERT( !IsEmpty() ); return Item(Count() - 1); }
3c67202d
VZ
1021
1022 // item management
1023 // Search the element in the array, starting from the beginning if
1024 // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case
1025 // sensitive (default). Returns index of the first item matched or
1026 // wxNOT_FOUND
2bb67b80 1027 int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
e01c8145
VZ
1028 // add new element at the end (if the array is not sorted), return its
1029 // index
1030 size_t Add(const wxString& str);
3c67202d 1031 // add new element at given position
c86f1403 1032 void Insert(const wxString& str, size_t uiIndex);
3c67202d 1033 // remove first item matching this value
2bb67b80 1034 void Remove(const wxChar *sz);
3c67202d 1035 // remove item by index
c801d85f 1036 void Remove(size_t nIndex);
28a156b1 1037 void RemoveAt(size_t nIndex) { Remove(nIndex); }
c801d85f 1038
30b21f9a
VZ
1039 // sorting
1040 // sort array elements in alphabetical order (or reversed alphabetical
1041 // order if reverseOrder parameter is TRUE)
1042 void Sort(bool reverseOrder = FALSE);
1043 // sort array elements using specified comparaison function
1044 void Sort(CompareFunction compareFunction);
c801d85f 1045
f6bcfd97
BP
1046 // comparison
1047 // compare two arrays case sensitively
1048 bool operator==(const wxArrayString& a) const;
1049 // compare two arrays case sensitively
1050 bool operator!=(const wxArrayString& a) const { return !(*this == a); }
1051
e87271f3
VZ
1052protected:
1053 void Copy(const wxArrayString& src); // copies the contents of another array
1054
c801d85f 1055private:
e87271f3
VZ
1056 void Grow(); // makes array bigger if needed
1057 void Free(); // free all the strings stored
c801d85f 1058
e87271f3 1059 void DoSort(); // common part of all Sort() variants
30b21f9a 1060
3c67202d 1061 size_t m_nSize, // current size of the array
c801d85f
KB
1062 m_nCount; // current number of elements
1063
e87271f3
VZ
1064 wxChar **m_pItems; // pointer to data
1065
1066 bool m_autoSort; // if TRUE, keep the array always sorted
1067};
1068
1069class WXDLLEXPORT wxSortedArrayString : public wxArrayString
1070{
1071public:
1072 wxSortedArrayString() : wxArrayString(TRUE)
1073 { }
1074 wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE)
1075 { Copy(array); }
c801d85f
KB
1076};
1077
c801d85f 1078// ---------------------------------------------------------------------------
3c67202d 1079// wxString comparison functions: operator versions are always case sensitive
c801d85f 1080// ---------------------------------------------------------------------------
f33fee2a 1081
0cbe5ee3
VZ
1082inline bool operator==(const wxString& s1, const wxString& s2)
1083 { return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); }
1084inline bool operator==(const wxString& s1, const wxChar * s2)
1085 { return s1.Cmp(s2) == 0; }
1086inline bool operator==(const wxChar * s1, const wxString& s2)
1087 { return s2.Cmp(s1) == 0; }
1088inline bool operator!=(const wxString& s1, const wxString& s2)
1089 { return (s1.Len() != s2.Len()) || (s1.Cmp(s2) != 0); }
1090inline bool operator!=(const wxString& s1, const wxChar * s2)
1091 { return s1.Cmp(s2) != 0; }
1092inline bool operator!=(const wxChar * s1, const wxString& s2)
1093 { return s2.Cmp(s1) != 0; }
1094inline bool operator< (const wxString& s1, const wxString& s2)
1095 { return s1.Cmp(s2) < 0; }
1096inline bool operator< (const wxString& s1, const wxChar * s2)
1097 { return s1.Cmp(s2) < 0; }
1098inline bool operator< (const wxChar * s1, const wxString& s2)
1099 { return s2.Cmp(s1) > 0; }
1100inline bool operator> (const wxString& s1, const wxString& s2)
1101 { return s1.Cmp(s2) > 0; }
1102inline bool operator> (const wxString& s1, const wxChar * s2)
1103 { return s1.Cmp(s2) > 0; }
1104inline bool operator> (const wxChar * s1, const wxString& s2)
1105 { return s2.Cmp(s1) < 0; }
1106inline bool operator<=(const wxString& s1, const wxString& s2)
1107 { return s1.Cmp(s2) <= 0; }
1108inline bool operator<=(const wxString& s1, const wxChar * s2)
1109 { return s1.Cmp(s2) <= 0; }
1110inline bool operator<=(const wxChar * s1, const wxString& s2)
1111 { return s2.Cmp(s1) >= 0; }
1112inline bool operator>=(const wxString& s1, const wxString& s2)
1113 { return s1.Cmp(s2) >= 0; }
1114inline bool operator>=(const wxString& s1, const wxChar * s2)
1115 { return s1.Cmp(s2) >= 0; }
1116inline bool operator>=(const wxChar * s1, const wxString& s2)
1117 { return s2.Cmp(s1) <= 0; }
3c67202d 1118
f33fee2a
VZ
1119// comparison with char
1120inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
1121inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
1122inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
1123inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
1124
5ca07d0f
OK
1125#if wxUSE_UNICODE
1126inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
f33fee2a 1127 { return (s1.Cmp((const wchar_t *)s2) == 0); }
5ca07d0f 1128inline bool operator==(const wxWCharBuffer& s1, const wxString& s2)
f33fee2a 1129 { return (s2.Cmp((const wchar_t *)s1) == 0); }
f6bcfd97
BP
1130inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2)
1131 { return (s1.Cmp((const wchar_t *)s2) != 0); }
1132inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2)
1133 { return (s2.Cmp((const wchar_t *)s1) != 0); }
0cbe5ee3 1134#else // !wxUSE_UNICODE
5ca07d0f 1135inline bool operator==(const wxString& s1, const wxCharBuffer& s2)
f33fee2a 1136 { return (s1.Cmp((const char *)s2) == 0); }
5ca07d0f 1137inline bool operator==(const wxCharBuffer& s1, const wxString& s2)
f33fee2a 1138 { return (s2.Cmp((const char *)s1) == 0); }
f6bcfd97
BP
1139inline bool operator!=(const wxString& s1, const wxCharBuffer& s2)
1140 { return (s1.Cmp((const char *)s2) != 0); }
1141inline bool operator!=(const wxCharBuffer& s1, const wxString& s2)
1142 { return (s2.Cmp((const char *)s1) != 0); }
0cbe5ee3 1143#endif // wxUSE_UNICODE/!wxUSE_UNICODE
5ca07d0f 1144
ed7174ba 1145wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
2bb67b80
OK
1146wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
1147wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
1148wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
1149wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
028a2b5d 1150#if wxUSE_UNICODE
6d56eb5c 1151inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
e90c1d2a 1152 { return string + (const wchar_t *)buf; }
6d56eb5c 1153inline wxString operator+(const wxWCharBuffer& buf, const wxString& string)
e90c1d2a 1154 { return (const wchar_t *)buf + string; }
0cbe5ee3 1155#else // !wxUSE_UNICODE
6d56eb5c 1156inline wxString operator+(const wxString& string, const wxCharBuffer& buf)
e90c1d2a 1157 { return string + (const char *)buf; }
6d56eb5c 1158inline wxString operator+(const wxCharBuffer& buf, const wxString& string)
e90c1d2a 1159 { return (const char *)buf + string; }
0cbe5ee3 1160#endif // wxUSE_UNICODE/!wxUSE_UNICODE
f04f3991 1161
c801d85f 1162// ---------------------------------------------------------------------------
3c67202d 1163// Implementation only from here until the end of file
c801d85f
KB
1164// ---------------------------------------------------------------------------
1165
e90c1d2a
VZ
1166// don't pollute the library user's name space
1167#undef ASSERT_VALID_INDEX
1168
38830220 1169#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM
c801d85f 1170
3f4a0c5b 1171#include "wx/ioswrap.h"
c801d85f 1172
dd107c50
VZ
1173WXDLLEXPORT wxSTD istream& operator>>(wxSTD istream&, wxString&);
1174WXDLLEXPORT wxSTD ostream& operator<<(wxSTD ostream&, const wxString&);
c801d85f 1175
3c67202d 1176#endif // wxSTD_STRING_COMPATIBILITY
c801d85f 1177
34138703 1178#endif // _WX_WXSTRINGH__