]> git.saurik.com Git - wxWidgets.git/blame - include/wx/string.h
fixed a canonical example of Stupid Bug(tm)
[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
00b4a13e
VZ
290 // if we hadn't made these operators private, it would be possible to
291 // compile "wxString s; s = 17;" without any warnings as 17 is implicitly
292 // converted to char in C and we do have operator=(char)
293 //
294 // NB: we don't need other versions (short/long and unsigned) as attempt
295 // to assign another numeric type to wxString will now result in
296 // ambiguity between operator=(char) and operator=(int)
297 wxString& operator=(int);
298
299 // these methods are not implemented - there is _no_ conversion from int to
c606a9a4
VZ
300 // string, you're doing something wrong if the compiler wants to call it!
301 //
302 // try `s << i' or `s.Printf("%d", i)' instead
303 wxString(int);
c606a9a4 304
c801d85f 305public:
3c67202d
VZ
306 // constructors and destructor
307 // ctor for an empty string
6b95b20d 308 wxString() { Init(); }
3c67202d 309 // copy ctor
6b95b20d
VZ
310 wxString(const wxString& stringSrc)
311 {
312 wxASSERT( stringSrc.GetStringData()->IsValid() );
313
314 if ( stringSrc.IsEmpty() ) {
315 // nothing to do for an empty string
316 Init();
317 }
318 else {
319 m_pchData = stringSrc.m_pchData; // share same data
320 GetStringData()->Lock(); // => one more copy
321 }
322 }
3c67202d 323 // string containing nRepeat copies of ch
2bb67b80 324 wxString(wxChar ch, size_t nRepeat = 1);
3c67202d 325 // ctor takes first nLength characters from C string
566b84d2 326 // (default value of wxSTRING_MAXLEN means take all the string)
2bb67b80 327 wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN)
6b95b20d 328 { InitWith(psz, 0, nLength); }
f6bcfd97
BP
329 wxString(const wxChar *psz, wxMBConv& WXUNUSED(conv), size_t nLength = wxSTRING_MAXLEN)
330 { InitWith(psz, 0, nLength); }
e90c1d2a 331
2bb67b80
OK
332#if wxUSE_UNICODE
333 // from multibyte string
334 // (NB: nLength is right now number of Unicode characters, not
335 // characters in psz! So try not to use it yet!)
5f709e67 336 wxString(const char *psz, wxMBConv& conv = wxConvLibc, size_t nLength = wxSTRING_MAXLEN);
2bb67b80
OK
337 // from wxWCharBuffer (i.e. return from wxGetString)
338 wxString(const wxWCharBuffer& psz)
339 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a 340#else // ANSI
3c67202d 341 // from C string (for compilers using unsigned char)
2bb67b80
OK
342 wxString(const unsigned char* psz, size_t nLength = wxSTRING_MAXLEN)
343 { InitWith((const char*)psz, 0, nLength); }
e90c1d2a 344
6f841509 345#if wxUSE_WCHAR_T
2bb67b80 346 // from wide (Unicode) string
f6bcfd97 347 wxString(const wchar_t *pwz, wxMBConv& conv = wxConvLibc);
e90c1d2a
VZ
348#endif // !wxUSE_WCHAR_T
349
2bb67b80
OK
350 // from wxCharBuffer
351 wxString(const wxCharBuffer& psz)
352 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a
VZ
353#endif // Unicode/ANSI
354
3c67202d 355 // dtor is not virtual, this class must not be inherited from!
6b95b20d 356 ~wxString() { GetStringData()->Unlock(); }
c801d85f 357
3c67202d
VZ
358 // generic attributes & operations
359 // as standard strlen()
47d67540 360 size_t Len() const { return GetStringData()->nDataLength; }
3c67202d 361 // string contains any characters?
dd1eaa89 362 bool IsEmpty() const { return Len() == 0; }
dcfde592
VZ
363 // empty string is "FALSE", so !str will return TRUE
364 bool operator!() const { return IsEmpty(); }
3c67202d 365 // empty string contents
dd1eaa89
VZ
366 void Empty()
367 {
2c3b684c 368 if ( !IsEmpty() )
dd1eaa89
VZ
369 Reinit();
370
7be07660 371 // should be empty
dd1eaa89 372 wxASSERT( GetStringData()->nDataLength == 0 );
7be07660 373 }
3c67202d 374 // empty the string and free memory
7be07660
VZ
375 void Clear()
376 {
377 if ( !GetStringData()->IsEmpty() )
378 Reinit();
379
380 wxASSERT( GetStringData()->nDataLength == 0 ); // should be empty
381 wxASSERT( GetStringData()->nAllocLength == 0 ); // and not own any memory
dd1eaa89
VZ
382 }
383
3c67202d
VZ
384 // contents test
385 // Is an ascii value
c801d85f 386 bool IsAscii() const;
3c67202d 387 // Is a number
c801d85f 388 bool IsNumber() const;
3c67202d 389 // Is a word
c801d85f 390 bool IsWord() const;
c801d85f 391
3c67202d
VZ
392 // data access (all indexes are 0 based)
393 // read access
2bb67b80 394 wxChar GetChar(size_t n) const
dd1eaa89 395 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
3c67202d 396 // read/write access
2bb67b80 397 wxChar& GetWritableChar(size_t n)
dd1eaa89 398 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
3c67202d 399 // write access
2bb67b80 400 void SetChar(size_t n, wxChar ch)
c801d85f
KB
401 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
402
3c67202d 403 // get last character
2bb67b80 404 wxChar Last() const
c801d85f 405 { wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
3c67202d 406 // get writable last character
2bb67b80 407 wxChar& Last()
c801d85f
KB
408 { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
409
d836ee96
VZ
410 /*
411 So why do we have all these overloaded operator[]s? A bit of history:
412 initially there was only one of them, taking size_t. Then people
413 started complaining because they wanted to use ints as indices (I
414 wonder why) and compilers were giving warnings about it, so we had to
415 add the operator[](int). Then it became apparent that you couldn't
416 write str[0] any longer because there was ambiguity between two
417 overloads and so you now had to write str[0u] (or, of course, use the
418 explicit casts to either int or size_t but nobody did this).
419
420 Finally, someone decided to compile wxWin on an Alpha machine and got
421 a surprize: str[0u] didn't compile there because it is of type
422 unsigned int and size_t is unsigned _long_ on Alpha and so there was
423 ambiguity between converting uint to int or ulong. To fix this one we
424 now add operator[](uint) for the machines where size_t is not already
425 the same as unsigned int - hopefully this fixes the problem (for some
426 time)
427
428 The only real fix is, of course, to remove all versions but the one
429 taking size_t...
430 */
431
3c67202d 432 // operator version of GetChar
2bb67b80 433 wxChar operator[](size_t n) const
c801d85f 434 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
c5248639 435
3c67202d 436 // operator version of GetChar
2bb67b80 437 wxChar operator[](int n) const
c801d85f 438 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
cd0b1709 439
f83db661 440 // operator version of GetWriteableChar
2bb67b80 441 wxChar& operator[](size_t n)
c801d85f 442 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96
VZ
443
444#ifndef wxSIZE_T_IS_UINT
445 // operator version of GetChar
446 wxChar operator[](unsigned int n) const
447 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
448
f83db661 449 // operator version of GetWriteableChar
d836ee96 450 wxChar& operator[](unsigned int n)
f83db661 451 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96 452#endif // size_t != unsigned int
c801d85f 453
3c67202d 454 // implicit conversion to C string
2bb67b80 455 operator const wxChar*() const { return m_pchData; }
3c67202d 456 // explicit conversion to C string (use this with printf()!)
2bb67b80 457 const wxChar* c_str() const { return m_pchData; }
f6bcfd97 458 // identical to c_str()
6f841509 459 const wxChar* wx_str() const { return m_pchData; }
e90c1d2a 460 // identical to c_str()
2bb67b80 461 const wxChar* GetData() const { return m_pchData; }
e90c1d2a
VZ
462
463 // conversions with (possible) format convertions: have to return a
464 // buffer with temporary data
f6bcfd97
BP
465 //
466 // the functions defined (in either Unicode or ANSI) mode are mb_str() to
467 // return an ANSI (multibyte) string, wc_str() to return a wide string and
468 // fn_str() to return a string which should be used with the OS APIs
469 // accepting the file names. The return value is always the same, but the
470 // type differs because a function may either return pointer to the buffer
471 // directly or have to use intermediate buffer for translation.
2bb67b80 472#if wxUSE_UNICODE
f6bcfd97
BP
473 const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const
474 { return conv.cWC2MB(m_pchData); }
475
e90c1d2a
VZ
476 const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
477
f6bcfd97
BP
478 const wxChar* wc_str() const { return m_pchData; }
479
480 // for compatibility with !wxUSE_UNICODE version
481 const wxChar* wc_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
e90c1d2a 482
2bb67b80 483#if wxMBFILES
5f709e67 484 const wxCharBuffer fn_str() const { return mb_str(wxConvFile); }
e90c1d2a 485#else // !wxMBFILES
2bb67b80 486 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a
VZ
487#endif // wxMBFILES/!wxMBFILES
488#else // ANSI
e90c1d2a 489 const wxChar* mb_str() const { return m_pchData; }
f6bcfd97
BP
490
491 // for compatibility with wxUSE_UNICODE version
492 const wxChar* mb_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
493
e90c1d2a 494 const wxWX2MBbuf mbc_str() const { return mb_str(); }
f6bcfd97 495
6f841509 496#if wxUSE_WCHAR_T
f6bcfd97
BP
497 const wxWCharBuffer wc_str(wxMBConv& conv) const
498 { return conv.cMB2WC(m_pchData); }
e90c1d2a 499#endif // wxUSE_WCHAR_T
f6bcfd97 500
2bb67b80 501 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a 502#endif // Unicode/ANSI
c801d85f 503
3c67202d
VZ
504 // overloaded assignment
505 // from another wxString
c801d85f 506 wxString& operator=(const wxString& stringSrc);
3c67202d 507 // from a character
2bb67b80 508 wxString& operator=(wxChar ch);
3c67202d 509 // from a C string
2bb67b80 510 wxString& operator=(const wxChar *psz);
111bb7f2
OK
511#if wxUSE_UNICODE
512 // from wxWCharBuffer
513 wxString& operator=(const wxWCharBuffer& psz) { return operator=((const wchar_t *)psz); }
e90c1d2a 514#else // ANSI
3c67202d 515 // from another kind of C string
c801d85f 516 wxString& operator=(const unsigned char* psz);
6f841509 517#if wxUSE_WCHAR_T
3c67202d 518 // from a wide string
c801d85f 519 wxString& operator=(const wchar_t *pwz);
6f841509 520#endif
111bb7f2
OK
521 // from wxCharBuffer
522 wxString& operator=(const wxCharBuffer& psz) { return operator=((const char *)psz); }
e90c1d2a 523#endif // Unicode/ANSI
3c67202d
VZ
524
525 // string concatenation
526 // in place concatenation
527 /*
528 Concatenate and return the result. Note that the left to right
529 associativity of << allows to write things like "str << str1 << str2
530 << ..." (unlike with +=)
531 */
532 // string += string
dd1eaa89
VZ
533 wxString& operator<<(const wxString& s)
534 {
535 wxASSERT( s.GetStringData()->IsValid() );
536
537 ConcatSelf(s.Len(), s);
538 return *this;
539 }
3c67202d 540 // string += C string
2bb67b80
OK
541 wxString& operator<<(const wxChar *psz)
542 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 543 // string += char
2bb67b80 544 wxString& operator<<(wxChar ch) { ConcatSelf(1, &ch); return *this; }
dd1eaa89 545
3c67202d 546 // string += string
6b95b20d 547 void operator+=(const wxString& s) { (void)operator<<(s); }
3c67202d 548 // string += C string
2bb67b80 549 void operator+=(const wxChar *psz) { (void)operator<<(psz); }
3c67202d 550 // string += char
2bb67b80
OK
551 void operator+=(wxChar ch) { (void)operator<<(ch); }
552
553 // string += buffer (i.e. from wxGetString)
554#if wxUSE_UNICODE
555 wxString& operator<<(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); return *this; }
556 void operator+=(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); }
557#else
558 wxString& operator<<(const wxCharBuffer& s) { (void)operator<<((const char *)s); return *this; }
559 void operator+=(const wxCharBuffer& s) { (void)operator<<((const char *)s); }
560#endif
6b95b20d 561
3c67202d 562 // string += C string
2bb67b80
OK
563 wxString& Append(const wxChar* psz)
564 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 565 // append count copies of given character
2bb67b80 566 wxString& Append(wxChar ch, size_t count = 1u)
3c67202d 567 { wxString str(ch, count); return *this << str; }
8f06a017
RD
568 wxString& Append(const wxChar* psz, size_t nLen)
569 { ConcatSelf(nLen, psz); return *this; }
3c67202d
VZ
570
571 // prepend a string, return the string itself
572 wxString& Prepend(const wxString& str)
573 { *this = str + *this; return *this; }
574
575 // non-destructive concatenation
576 //
c33534e5 577 friend wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
3c67202d 578 //
2bb67b80 579 friend wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
3c67202d 580 //
2bb67b80 581 friend wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
3c67202d 582 //
2bb67b80 583 friend wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
3c67202d 584 //
2bb67b80 585 friend wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
3c67202d
VZ
586
587 // stream-like functions
588 // insert an int into string
3ce65f6c
VZ
589 wxString& operator<<(int i)
590 { return (*this) << Format(_T("%d"), i); }
591 // insert an unsigned int into string
592 wxString& operator<<(unsigned int ui)
593 { return (*this) << Format(_T("%u"), ui); }
594 // insert a long into string
595 wxString& operator<<(long l)
596 { return (*this) << Format(_T("%ld"), l); }
597 // insert an unsigned long into string
598 wxString& operator<<(unsigned long ul)
599 { return (*this) << Format(_T("%lu"), ul); }
3c67202d 600 // insert a float into string
3ce65f6c
VZ
601 wxString& operator<<(float f)
602 { return (*this) << Format(_T("%f"), f); }
3c67202d 603 // insert a double into string
3ce65f6c
VZ
604 wxString& operator<<(double d)
605 { return (*this) << Format(_T("%g"), d); }
c84c52de 606
3c67202d 607 // string comparison
30b21f9a 608 // case-sensitive comparison (returns a value < 0, = 0 or > 0)
f33fee2a 609 int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); }
3c67202d 610 // same as Cmp() but not case-sensitive
f33fee2a 611 int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); }
3c67202d
VZ
612 // test for the string equality, either considering case or not
613 // (if compareWithCase then the case matters)
2bb67b80 614 bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const
3c67202d 615 { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
f33fee2a
VZ
616 // comparison with a signle character: returns TRUE if equal
617 bool IsSameAs(wxChar c, bool compareWithCase = TRUE) const
618 {
619 return (Len() == 1) && (compareWithCase ? GetChar(0u) == c
620 : wxToupper(GetChar(0u)) == wxToupper(c));
621 }
3c67202d
VZ
622
623 // simple sub-string extraction
624 // return substring starting at nFirst of length nCount (or till the end
625 // if nCount = default value)
566b84d2 626 wxString Mid(size_t nFirst, size_t nCount = wxSTRING_MAXLEN) const;
3c67202d 627
f6bcfd97 628 // operator version of Mid()
3c67202d
VZ
629 wxString operator()(size_t start, size_t len) const
630 { return Mid(start, len); }
631
f6bcfd97
BP
632 // check that the tring starts with prefix and return the rest of the
633 // string in the provided pointer if it is not NULL, otherwise return
634 // FALSE
635 bool StartsWith(const wxChar *prefix, wxString *rest = NULL) const;
636
3c67202d 637 // get first nCount characters
c801d85f 638 wxString Left(size_t nCount) const;
3c67202d 639 // get last nCount characters
c801d85f 640 wxString Right(size_t nCount) const;
3c67202d
VZ
641 // get all characters before the first occurence of ch
642 // (returns the whole string if ch not found)
2bb67b80 643 wxString BeforeFirst(wxChar ch) const;
3c67202d
VZ
644 // get all characters before the last occurence of ch
645 // (returns empty string if ch not found)
2bb67b80 646 wxString BeforeLast(wxChar ch) const;
3c67202d
VZ
647 // get all characters after the first occurence of ch
648 // (returns empty string if ch not found)
2bb67b80 649 wxString AfterFirst(wxChar ch) const;
3c67202d
VZ
650 // get all characters after the last occurence of ch
651 // (returns the whole string if ch not found)
2bb67b80 652 wxString AfterLast(wxChar ch) const;
3c67202d
VZ
653
654 // for compatibility only, use more explicitly named functions above
2bb67b80
OK
655 wxString Before(wxChar ch) const { return BeforeLast(ch); }
656 wxString After(wxChar ch) const { return AfterFirst(ch); }
3c67202d
VZ
657
658 // case conversion
c84c52de 659 // convert to upper case in place, return the string itself
c801d85f 660 wxString& MakeUpper();
c84c52de 661 // convert to upper case, return the copy of the string
03ab016d
JS
662 // Here's something to remember: BC++ doesn't like returns in inlines.
663 wxString Upper() const ;
c84c52de 664 // convert to lower case in place, return the string itself
c801d85f 665 wxString& MakeLower();
c84c52de 666 // convert to lower case, return the copy of the string
03ab016d 667 wxString Lower() const ;
c801d85f 668
3c67202d
VZ
669 // trimming/padding whitespace (either side) and truncating
670 // remove spaces from left or from right (default) side
c801d85f 671 wxString& Trim(bool bFromRight = TRUE);
3c67202d 672 // add nCount copies chPad in the beginning or at the end (default)
223d09f6 673 wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = TRUE);
3c67202d 674 // truncate string to given length
c801d85f 675 wxString& Truncate(size_t uiLen);
dd1eaa89 676
3c67202d
VZ
677 // searching and replacing
678 // searching (return starting index, or -1 if not found)
2bb67b80 679 int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
3c67202d 680 // searching (return starting index, or -1 if not found)
2bb67b80 681 int Find(const wxChar *pszSub) const; // like strstr
3c67202d
VZ
682 // replace first (or all of bReplaceAll) occurences of substring with
683 // another string, returns the number of replacements made
2bb67b80
OK
684 size_t Replace(const wxChar *szOld,
685 const wxChar *szNew,
3c67202d
VZ
686 bool bReplaceAll = TRUE);
687
688 // check if the string contents matches a mask containing '*' and '?'
2bb67b80 689 bool Matches(const wxChar *szMask) const;
c801d85f 690
cd0b1709
VZ
691 // conversion to numbers: all functions return TRUE only if the whole string
692 // is a number and put the value of this number into the pointer provided
693 // convert to a signed integer
694 bool ToLong(long *val) const;
695 // convert to an unsigned integer
696 bool ToULong(unsigned long *val) const;
697 // convert to a double
698 bool ToDouble(double *val) const;
699
3c67202d
VZ
700 // formated input/output
701 // as sprintf(), returns the number of characters written or < 0 on error
2bb67b80 702 int Printf(const wxChar *pszFormat, ...);
3c67202d 703 // as vprintf(), returns the number of characters written or < 0 on error
2bb67b80 704 int PrintfV(const wxChar* pszFormat, va_list argptr);
dd1eaa89 705
341e7d28
VZ
706 // returns the string containing the result of Printf() to it
707 static wxString Format(const wxChar *pszFormat, ...);
708 // the same as above, but takes a va_list
709 static wxString FormatV(const wxChar *pszFormat, va_list argptr);
710
3c67202d
VZ
711 // raw access to string memory
712 // ensure that string has space for at least nLen characters
dd1eaa89 713 // only works if the data of this string is not shared
c86f1403 714 void Alloc(size_t nLen);
3c67202d 715 // minimize the string's memory
dd1eaa89
VZ
716 // only works if the data of this string is not shared
717 void Shrink();
3c67202d
VZ
718 // get writable buffer of at least nLen bytes. Unget() *must* be called
719 // a.s.a.p. to put string back in a reasonable state!
2bb67b80 720 wxChar *GetWriteBuf(size_t nLen);
3c67202d 721 // call this immediately after GetWriteBuf() has been used
8fd0f20b 722 void UngetWriteBuf();
8f06a017 723 void UngetWriteBuf(size_t nLen);
c801d85f 724
3c67202d
VZ
725 // wxWindows version 1 compatibility functions
726
727 // use Mid()
728 wxString SubString(size_t from, size_t to) const
729 { return Mid(from, (to - from + 1)); }
730 // values for second parameter of CompareTo function
c801d85f 731 enum caseCompare {exact, ignoreCase};
3c67202d 732 // values for first parameter of Strip function
c801d85f 733 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
8870c26e 734
3c67202d 735 // use Printf()
2bb67b80 736 int sprintf(const wxChar *pszFormat, ...);
c801d85f 737
3c67202d 738 // use Cmp()
2bb67b80 739 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
6b95b20d 740 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
c801d85f 741
3c67202d 742 // use Len
c801d85f 743 size_t Length() const { return Len(); }
3c67202d 744 // Count the number of characters
2bb67b80 745 int Freq(wxChar ch) const;
3c67202d 746 // use MakeLower
c801d85f 747 void LowerCase() { MakeLower(); }
3c67202d 748 // use MakeUpper
c801d85f 749 void UpperCase() { MakeUpper(); }
3c67202d 750 // use Trim except that it doesn't change this string
c801d85f
KB
751 wxString Strip(stripType w = trailing) const;
752
3c67202d 753 // use Find (more general variants not yet supported)
2bb67b80
OK
754 size_t Index(const wxChar* psz) const { return Find(psz); }
755 size_t Index(wxChar ch) const { return Find(ch); }
3c67202d 756 // use Truncate
c801d85f 757 wxString& Remove(size_t pos) { return Truncate(pos); }
28a156b1 758 wxString& RemoveLast(size_t n = 1) { return Truncate(Len() - n); }
c801d85f 759
3ed358cb 760 wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
dd1eaa89 761
3c67202d 762 // use Find()
2bb67b80
OK
763 int First( const wxChar ch ) const { return Find(ch); }
764 int First( const wxChar* psz ) const { return Find(psz); }
3ed358cb 765 int First( const wxString &str ) const { return Find(str); }
2bb67b80 766 int Last( const wxChar ch ) const { return Find(ch, TRUE); }
3c67202d 767 bool Contains(const wxString& str) const { return Find(str) != -1; }
c801d85f 768
3c67202d 769 // use IsEmpty()
c801d85f 770 bool IsNull() const { return IsEmpty(); }
c801d85f 771
3c67202d
VZ
772#ifdef wxSTD_STRING_COMPATIBILITY
773 // std::string compatibility functions
dd1eaa89 774
2bc07607
VZ
775 // standard types
776 typedef wxChar value_type;
777 typedef const value_type *const_iterator;
778
3c67202d 779 // an 'invalid' value for string index
c801d85f 780 static const size_t npos;
dd1eaa89 781
3c67202d
VZ
782 // constructors
783 // take nLen chars starting at nPos
784 wxString(const wxString& str, size_t nPos, size_t nLen)
785 {
786 wxASSERT( str.GetStringData()->IsValid() );
787 InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen);
788 }
789 // take all characters from pStart to pEnd
790 wxString(const void *pStart, const void *pEnd);
791
792 // lib.string.capacity
793 // return the length of the string
794 size_t size() const { return Len(); }
795 // return the length of the string
796 size_t length() const { return Len(); }
797 // return the maximum size of the string
566b84d2 798 size_t max_size() const { return wxSTRING_MAXLEN; }
3c67202d 799 // resize the string, filling the space with c if c != 0
223d09f6 800 void resize(size_t nSize, wxChar ch = wxT('\0'));
3c67202d
VZ
801 // delete the contents of the string
802 void clear() { Empty(); }
803 // returns true if the string is empty
804 bool empty() const { return IsEmpty(); }
252a752e
VZ
805 // inform string about planned change in size
806 void reserve(size_t size) { Alloc(size); }
3c67202d
VZ
807
808 // lib.string.access
809 // return the character at position n
2bb67b80 810 wxChar at(size_t n) const { return GetChar(n); }
3c67202d 811 // returns the writable character at position n
2bb67b80 812 wxChar& at(size_t n) { return GetWritableChar(n); }
3c67202d 813
2bc07607
VZ
814 // first valid index position
815 const_iterator begin() const { return wx_str(); }
816 // position one after the last valid one
817 const_iterator end() const { return wx_str() + length(); }
818
3c67202d
VZ
819 // lib.string.modifiers
820 // append a string
821 wxString& append(const wxString& str)
822 { *this += str; return *this; }
823 // append elements str[pos], ..., str[pos+n]
824 wxString& append(const wxString& str, size_t pos, size_t n)
825 { ConcatSelf(n, str.c_str() + pos); return *this; }
826 // append first n (or all if n == npos) characters of sz
2bb67b80
OK
827 wxString& append(const wxChar *sz, size_t n = npos)
828 { ConcatSelf(n == npos ? wxStrlen(sz) : n, sz); return *this; }
3c67202d
VZ
829
830 // append n copies of ch
2bb67b80 831 wxString& append(size_t n, wxChar ch) { return Pad(n, ch); }
3c67202d
VZ
832
833 // same as `this_string = str'
834 wxString& assign(const wxString& str) { return (*this) = str; }
835 // same as ` = str[pos..pos + n]
836 wxString& assign(const wxString& str, size_t pos, size_t n)
2bb67b80 837 { return *this = wxString((const wxChar *)str + pos, n); }
3c67202d 838 // same as `= first n (or all if n == npos) characters of sz'
2bb67b80 839 wxString& assign(const wxChar *sz, size_t n = npos)
3c67202d
VZ
840 { return *this = wxString(sz, n); }
841 // same as `= n copies of ch'
2bb67b80 842 wxString& assign(size_t n, wxChar ch)
3c67202d
VZ
843 { return *this = wxString(ch, n); }
844
845 // insert another string
846 wxString& insert(size_t nPos, const wxString& str);
847 // insert n chars of str starting at nStart (in str)
848 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
2bb67b80 849 { return insert(nPos, wxString((const wxChar *)str + nStart, n)); }
3c67202d
VZ
850
851 // insert first n (or all if n == npos) characters of sz
2bb67b80 852 wxString& insert(size_t nPos, const wxChar *sz, size_t n = npos)
3c67202d
VZ
853 { return insert(nPos, wxString(sz, n)); }
854 // insert n copies of ch
2bb67b80 855 wxString& insert(size_t nPos, size_t n, wxChar ch)
3c67202d
VZ
856 { return insert(nPos, wxString(ch, n)); }
857
858 // delete characters from nStart to nStart + nLen
859 wxString& erase(size_t nStart = 0, size_t nLen = npos);
860
861 // replaces the substring of length nLen starting at nStart
2bb67b80 862 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz);
3c67202d 863 // replaces the substring with nCount copies of ch
2bb67b80 864 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
3c67202d
VZ
865 // replaces a substring with another substring
866 wxString& replace(size_t nStart, size_t nLen,
867 const wxString& str, size_t nStart2, size_t nLen2);
868 // replaces the substring with first nCount chars of sz
fb20fa43
VZ
869 wxString& replace(size_t nStart, size_t nLen,
870 const wxChar* sz, size_t nCount);
3c67202d
VZ
871
872 // swap two strings
873 void swap(wxString& str);
874
875 // All find() functions take the nStart argument which specifies the
876 // position to start the search on, the default value is 0. All functions
877 // return npos if there were no match.
878
879 // find a substring
880 size_t find(const wxString& str, size_t nStart = 0) const;
881
882 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 883#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 884 // find first n characters of sz
2bb67b80 885 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
fb20fa43 886#endif // VC++ 1.5
3c67202d
VZ
887
888 // Gives a duplicate symbol (presumably a case-insensitivity problem)
62448488 889#if !defined(__BORLANDC__)
3c67202d 890 // find the first occurence of character ch after nStart
2bb67b80 891 size_t find(wxChar ch, size_t nStart = 0) const;
62448488 892#endif
3c67202d
VZ
893 // rfind() family is exactly like find() but works right to left
894
895 // as find, but from the end
896 size_t rfind(const wxString& str, size_t nStart = npos) const;
897
898 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 899#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 900 // as find, but from the end
2bb67b80 901 size_t rfind(const wxChar* sz, size_t nStart = npos,
3c67202d
VZ
902 size_t n = npos) const;
903 // as find, but from the end
2bb67b80 904 size_t rfind(wxChar ch, size_t nStart = npos) const;
fb20fa43 905#endif // VC++ 1.5
3c67202d
VZ
906
907 // find first/last occurence of any character in the set
908
969d318c
VZ
909 // as strpbrk() but starts at nStart, returns npos if not found
910 size_t find_first_of(const wxString& str, size_t nStart = 0) const
911 { return find_first_of(str.c_str(), nStart); }
912 // same as above
2bb67b80 913 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
3c67202d 914 // same as find(char, size_t)
969d318c
VZ
915 size_t find_first_of(wxChar c, size_t nStart = 0) const
916 { return find(c, nStart); }
917 // find the last (starting from nStart) char from str in this string
918 size_t find_last_of (const wxString& str, size_t nStart = npos) const
919 { return find_last_of(str.c_str(), nStart); }
920 // same as above
921 size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
922 // same as above
923 size_t find_last_of(wxChar c, size_t nStart = npos) const
924 { return rfind(c, nStart); }
3c67202d
VZ
925
926 // find first/last occurence of any character not in the set
927
969d318c
VZ
928 // as strspn() (starting from nStart), returns npos on failure
929 size_t find_first_not_of(const wxString& str, size_t nStart = 0) const
930 { return find_first_not_of(str.c_str(), nStart); }
931 // same as above
932 size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
933 // same as above
2bb67b80 934 size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
969d318c 935 // as strcspn()
fb20fa43
VZ
936 size_t find_last_not_of(const wxString& str, size_t nStart = npos) const
937 { return find_first_not_of(str.c_str(), nStart); }
969d318c
VZ
938 // same as above
939 size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
940 // same as above
2bb67b80 941 size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
3c67202d
VZ
942
943 // All compare functions return -1, 0 or 1 if the [sub]string is less,
944 // equal or greater than the compare() argument.
945
946 // just like strcmp()
947 int compare(const wxString& str) const { return Cmp(str); }
948 // comparison with a substring
fb20fa43
VZ
949 int compare(size_t nStart, size_t nLen, const wxString& str) const
950 { return Mid(nStart, nLen).Cmp(str); }
3c67202d
VZ
951 // comparison of 2 substrings
952 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
953 const wxString& str, size_t nStart2, size_t nLen2) const
954 { return Mid(nStart, nLen).Cmp(str.Mid(nStart2, nLen2)); }
3c67202d 955 // just like strcmp()
2bb67b80 956 int compare(const wxChar* sz) const { return Cmp(sz); }
3c67202d
VZ
957 // substring comparison with first nCount characters of sz
958 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
959 const wxChar* sz, size_t nCount = npos) const
960 { return Mid(nStart, nLen).Cmp(wxString(sz, nCount)); }
3c67202d
VZ
961
962 // substring extraction
8c264b23
VZ
963 wxString substr(size_t nStart = 0, size_t nLen = npos) const
964 { return Mid(nStart, nLen); }
3c67202d 965#endif // wxSTD_STRING_COMPATIBILITY
c801d85f
KB
966};
967
968// ----------------------------------------------------------------------------
3c67202d
VZ
969// The string array uses it's knowledge of internal structure of the wxString
970// class to optimize string storage. Normally, we would store pointers to
971// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
972// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
973// really all we need to turn such pointer into a string!
974//
975// Of course, it can be called a dirty hack, but we use twice less memory and
976// this approach is also more speed efficient, so it's probably worth it.
977//
978// Usage notes: when a string is added/inserted, a new copy of it is created,
979// so the original string may be safely deleted. When a string is retrieved
980// from the array (operator[] or Item() method), a reference is returned.
c801d85f 981// ----------------------------------------------------------------------------
e90c1d2a 982
fbcb4166 983class WXDLLEXPORT wxArrayString
c801d85f
KB
984{
985public:
30b21f9a
VZ
986 // type of function used by wxArrayString::Sort()
987 typedef int (*CompareFunction)(const wxString& first,
988 const wxString& second);
989
3c67202d 990 // constructors and destructor
e87271f3
VZ
991 // default ctor: if autoSort is TRUE, the array is always sorted (in
992 // alphabetical order)
993 wxArrayString(bool autoSort = FALSE);
3c67202d 994 // copy ctor
c801d85f 995 wxArrayString(const wxArrayString& array);
3c67202d 996 // assignment operator
c801d85f 997 wxArrayString& operator=(const wxArrayString& src);
3c67202d 998 // not virtual, this class should not be derived from
c801d85f 999 ~wxArrayString();
c801d85f 1000
3c67202d
VZ
1001 // memory management
1002 // empties the list, but doesn't release memory
c801d85f 1003 void Empty();
3c67202d 1004 // empties the list and releases memory
c801d85f 1005 void Clear();
3c67202d 1006 // preallocates memory for given number of items
c801d85f 1007 void Alloc(size_t nCount);
3c67202d 1008 // minimzes the memory usage (by freeing all extra memory)
dd1eaa89 1009 void Shrink();
3c67202d
VZ
1010
1011 // simple accessors
1012 // number of elements in the array
1013 size_t GetCount() const { return m_nCount; }
1014 // is it empty?
1015 bool IsEmpty() const { return m_nCount == 0; }
1016 // number of elements in the array (GetCount is preferred API)
1017 size_t Count() const { return m_nCount; }
1018
1019 // items access (range checking is done in debug version)
1020 // get item at position uiIndex
c801d85f
KB
1021 wxString& Item(size_t nIndex) const
1022 { wxASSERT( nIndex < m_nCount ); return *(wxString *)&(m_pItems[nIndex]); }
3c67202d 1023 // same as Item()
c801d85f 1024 wxString& operator[](size_t nIndex) const { return Item(nIndex); }
3c67202d 1025 // get last item
c801d85f 1026 wxString& Last() const { wxASSERT( !IsEmpty() ); return Item(Count() - 1); }
3c67202d
VZ
1027
1028 // item management
1029 // Search the element in the array, starting from the beginning if
1030 // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case
1031 // sensitive (default). Returns index of the first item matched or
1032 // wxNOT_FOUND
2bb67b80 1033 int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
e01c8145
VZ
1034 // add new element at the end (if the array is not sorted), return its
1035 // index
1036 size_t Add(const wxString& str);
3c67202d 1037 // add new element at given position
c86f1403 1038 void Insert(const wxString& str, size_t uiIndex);
3c67202d 1039 // remove first item matching this value
2bb67b80 1040 void Remove(const wxChar *sz);
3c67202d 1041 // remove item by index
c801d85f 1042 void Remove(size_t nIndex);
28a156b1 1043 void RemoveAt(size_t nIndex) { Remove(nIndex); }
c801d85f 1044
30b21f9a
VZ
1045 // sorting
1046 // sort array elements in alphabetical order (or reversed alphabetical
1047 // order if reverseOrder parameter is TRUE)
1048 void Sort(bool reverseOrder = FALSE);
1049 // sort array elements using specified comparaison function
1050 void Sort(CompareFunction compareFunction);
c801d85f 1051
f6bcfd97
BP
1052 // comparison
1053 // compare two arrays case sensitively
1054 bool operator==(const wxArrayString& a) const;
1055 // compare two arrays case sensitively
1056 bool operator!=(const wxArrayString& a) const { return !(*this == a); }
1057
e87271f3
VZ
1058protected:
1059 void Copy(const wxArrayString& src); // copies the contents of another array
1060
c801d85f 1061private:
e87271f3
VZ
1062 void Grow(); // makes array bigger if needed
1063 void Free(); // free all the strings stored
c801d85f 1064
e87271f3 1065 void DoSort(); // common part of all Sort() variants
30b21f9a 1066
3c67202d 1067 size_t m_nSize, // current size of the array
c801d85f
KB
1068 m_nCount; // current number of elements
1069
e87271f3
VZ
1070 wxChar **m_pItems; // pointer to data
1071
1072 bool m_autoSort; // if TRUE, keep the array always sorted
1073};
1074
1075class WXDLLEXPORT wxSortedArrayString : public wxArrayString
1076{
1077public:
1078 wxSortedArrayString() : wxArrayString(TRUE)
1079 { }
1080 wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE)
1081 { Copy(array); }
c801d85f
KB
1082};
1083
c801d85f 1084// ---------------------------------------------------------------------------
3c67202d 1085// wxString comparison functions: operator versions are always case sensitive
c801d85f 1086// ---------------------------------------------------------------------------
f33fee2a 1087
0cbe5ee3
VZ
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.Len() != s2.Len()) || (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; }
1118inline bool operator>=(const wxString& s1, const wxString& s2)
1119 { return s1.Cmp(s2) >= 0; }
1120inline bool operator>=(const wxString& s1, const wxChar * s2)
1121 { return s1.Cmp(s2) >= 0; }
1122inline bool operator>=(const wxChar * s1, const wxString& s2)
1123 { return s2.Cmp(s1) <= 0; }
3c67202d 1124
f33fee2a
VZ
1125// comparison with char
1126inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
1127inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
1128inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
1129inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
1130
5ca07d0f
OK
1131#if wxUSE_UNICODE
1132inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
f33fee2a 1133 { return (s1.Cmp((const wchar_t *)s2) == 0); }
5ca07d0f 1134inline bool operator==(const wxWCharBuffer& s1, const wxString& s2)
f33fee2a 1135 { return (s2.Cmp((const wchar_t *)s1) == 0); }
f6bcfd97
BP
1136inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2)
1137 { return (s1.Cmp((const wchar_t *)s2) != 0); }
1138inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2)
1139 { return (s2.Cmp((const wchar_t *)s1) != 0); }
0cbe5ee3 1140#else // !wxUSE_UNICODE
5ca07d0f 1141inline bool operator==(const wxString& s1, const wxCharBuffer& s2)
f33fee2a 1142 { return (s1.Cmp((const char *)s2) == 0); }
5ca07d0f 1143inline bool operator==(const wxCharBuffer& s1, const wxString& s2)
f33fee2a 1144 { return (s2.Cmp((const char *)s1) == 0); }
f6bcfd97
BP
1145inline bool operator!=(const wxString& s1, const wxCharBuffer& s2)
1146 { return (s1.Cmp((const char *)s2) != 0); }
1147inline bool operator!=(const wxCharBuffer& s1, const wxString& s2)
1148 { return (s2.Cmp((const char *)s1) != 0); }
0cbe5ee3 1149#endif // wxUSE_UNICODE/!wxUSE_UNICODE
5ca07d0f 1150
ed7174ba 1151wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
2bb67b80
OK
1152wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
1153wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
1154wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
1155wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
028a2b5d 1156#if wxUSE_UNICODE
6d56eb5c 1157inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
e90c1d2a 1158 { return string + (const wchar_t *)buf; }
6d56eb5c 1159inline wxString operator+(const wxWCharBuffer& buf, const wxString& string)
e90c1d2a 1160 { return (const wchar_t *)buf + string; }
0cbe5ee3 1161#else // !wxUSE_UNICODE
6d56eb5c 1162inline wxString operator+(const wxString& string, const wxCharBuffer& buf)
e90c1d2a 1163 { return string + (const char *)buf; }
6d56eb5c 1164inline wxString operator+(const wxCharBuffer& buf, const wxString& string)
e90c1d2a 1165 { return (const char *)buf + string; }
0cbe5ee3 1166#endif // wxUSE_UNICODE/!wxUSE_UNICODE
f04f3991 1167
c801d85f 1168// ---------------------------------------------------------------------------
3c67202d 1169// Implementation only from here until the end of file
c801d85f
KB
1170// ---------------------------------------------------------------------------
1171
e90c1d2a
VZ
1172// don't pollute the library user's name space
1173#undef ASSERT_VALID_INDEX
1174
38830220 1175#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM
c801d85f 1176
3f4a0c5b 1177#include "wx/ioswrap.h"
c801d85f 1178
dd107c50
VZ
1179WXDLLEXPORT wxSTD istream& operator>>(wxSTD istream&, wxString&);
1180WXDLLEXPORT wxSTD ostream& operator<<(wxSTD ostream&, const wxString&);
c801d85f 1181
3c67202d 1182#endif // wxSTD_STRING_COMPATIBILITY
c801d85f 1183
34138703 1184#endif // _WX_WXSTRINGH__