]> git.saurik.com Git - wxWidgets.git/blame - include/wx/string.h
simplified WXDLLEXPORT/IMPORT defines, added WXEXPORT/IMPORT
[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 65 #include <strings.h> // for strcasecmp()
d739313f 66#endif // HAVE_STRINGS_H
1bfcb0b6 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(); }
735d1db6
VZ
365 // truncate the string to given length
366 wxString& Truncate(size_t uiLen);
3c67202d 367 // empty string contents
dd1eaa89
VZ
368 void Empty()
369 {
735d1db6 370 Truncate(0);
dd1eaa89 371
735d1db6 372 wxASSERT_MSG( IsEmpty(), _T("string not empty after call to Empty()?") );
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
c0881dc3 632 // check that the string starts with prefix and return the rest of the
f6bcfd97
BP
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;
c0881dc3 641 // get all characters before the first occurance of ch
3c67202d 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);
dd1eaa89 674
3c67202d
VZ
675 // searching and replacing
676 // searching (return starting index, or -1 if not found)
2bb67b80 677 int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
3c67202d 678 // searching (return starting index, or -1 if not found)
2bb67b80 679 int Find(const wxChar *pszSub) const; // like strstr
3c67202d
VZ
680 // replace first (or all of bReplaceAll) occurences of substring with
681 // another string, returns the number of replacements made
2bb67b80
OK
682 size_t Replace(const wxChar *szOld,
683 const wxChar *szNew,
3c67202d
VZ
684 bool bReplaceAll = TRUE);
685
686 // check if the string contents matches a mask containing '*' and '?'
2bb67b80 687 bool Matches(const wxChar *szMask) const;
c801d85f 688
cd0b1709
VZ
689 // conversion to numbers: all functions return TRUE only if the whole string
690 // is a number and put the value of this number into the pointer provided
691 // convert to a signed integer
4eb438cf 692 bool ToLong(long *val, int base = 0) const;
cd0b1709 693 // convert to an unsigned integer
4eb438cf 694 bool ToULong(unsigned long *val, int base = 0) const;
cd0b1709
VZ
695 // convert to a double
696 bool ToDouble(double *val) const;
697
3c67202d
VZ
698 // formated input/output
699 // as sprintf(), returns the number of characters written or < 0 on error
2bb67b80 700 int Printf(const wxChar *pszFormat, ...);
3c67202d 701 // as vprintf(), returns the number of characters written or < 0 on error
2bb67b80 702 int PrintfV(const wxChar* pszFormat, va_list argptr);
dd1eaa89 703
341e7d28
VZ
704 // returns the string containing the result of Printf() to it
705 static wxString Format(const wxChar *pszFormat, ...);
706 // the same as above, but takes a va_list
707 static wxString FormatV(const wxChar *pszFormat, va_list argptr);
708
3c67202d
VZ
709 // raw access to string memory
710 // ensure that string has space for at least nLen characters
dd1eaa89 711 // only works if the data of this string is not shared
c86f1403 712 void Alloc(size_t nLen);
3c67202d 713 // minimize the string's memory
dd1eaa89
VZ
714 // only works if the data of this string is not shared
715 void Shrink();
3c67202d
VZ
716 // get writable buffer of at least nLen bytes. Unget() *must* be called
717 // a.s.a.p. to put string back in a reasonable state!
2bb67b80 718 wxChar *GetWriteBuf(size_t nLen);
3c67202d 719 // call this immediately after GetWriteBuf() has been used
8fd0f20b 720 void UngetWriteBuf();
8f06a017 721 void UngetWriteBuf(size_t nLen);
c801d85f 722
3c67202d
VZ
723 // wxWindows version 1 compatibility functions
724
725 // use Mid()
726 wxString SubString(size_t from, size_t to) const
727 { return Mid(from, (to - from + 1)); }
728 // values for second parameter of CompareTo function
c801d85f 729 enum caseCompare {exact, ignoreCase};
3c67202d 730 // values for first parameter of Strip function
c801d85f 731 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
8870c26e 732
3c67202d 733 // use Printf()
2bb67b80 734 int sprintf(const wxChar *pszFormat, ...);
c801d85f 735
3c67202d 736 // use Cmp()
2bb67b80 737 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
6b95b20d 738 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
c801d85f 739
3c67202d 740 // use Len
c801d85f 741 size_t Length() const { return Len(); }
3c67202d 742 // Count the number of characters
2bb67b80 743 int Freq(wxChar ch) const;
3c67202d 744 // use MakeLower
c801d85f 745 void LowerCase() { MakeLower(); }
3c67202d 746 // use MakeUpper
c801d85f 747 void UpperCase() { MakeUpper(); }
3c67202d 748 // use Trim except that it doesn't change this string
c801d85f
KB
749 wxString Strip(stripType w = trailing) const;
750
3c67202d 751 // use Find (more general variants not yet supported)
2bb67b80
OK
752 size_t Index(const wxChar* psz) const { return Find(psz); }
753 size_t Index(wxChar ch) const { return Find(ch); }
3c67202d 754 // use Truncate
c801d85f 755 wxString& Remove(size_t pos) { return Truncate(pos); }
28a156b1 756 wxString& RemoveLast(size_t n = 1) { return Truncate(Len() - n); }
c801d85f 757
3ed358cb 758 wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
dd1eaa89 759
3c67202d 760 // use Find()
2bb67b80
OK
761 int First( const wxChar ch ) const { return Find(ch); }
762 int First( const wxChar* psz ) const { return Find(psz); }
3ed358cb 763 int First( const wxString &str ) const { return Find(str); }
2bb67b80 764 int Last( const wxChar ch ) const { return Find(ch, TRUE); }
3c67202d 765 bool Contains(const wxString& str) const { return Find(str) != -1; }
c801d85f 766
3c67202d 767 // use IsEmpty()
c801d85f 768 bool IsNull() const { return IsEmpty(); }
c801d85f 769
3c67202d
VZ
770#ifdef wxSTD_STRING_COMPATIBILITY
771 // std::string compatibility functions
dd1eaa89 772
2bc07607
VZ
773 // standard types
774 typedef wxChar value_type;
775 typedef const value_type *const_iterator;
776
3c67202d 777 // an 'invalid' value for string index
c801d85f 778 static const size_t npos;
dd1eaa89 779
3c67202d
VZ
780 // constructors
781 // take nLen chars starting at nPos
782 wxString(const wxString& str, size_t nPos, size_t nLen)
783 {
784 wxASSERT( str.GetStringData()->IsValid() );
785 InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen);
786 }
787 // take all characters from pStart to pEnd
788 wxString(const void *pStart, const void *pEnd);
789
790 // lib.string.capacity
791 // return the length of the string
792 size_t size() const { return Len(); }
793 // return the length of the string
794 size_t length() const { return Len(); }
795 // return the maximum size of the string
566b84d2 796 size_t max_size() const { return wxSTRING_MAXLEN; }
3c67202d 797 // resize the string, filling the space with c if c != 0
223d09f6 798 void resize(size_t nSize, wxChar ch = wxT('\0'));
3c67202d
VZ
799 // delete the contents of the string
800 void clear() { Empty(); }
801 // returns true if the string is empty
802 bool empty() const { return IsEmpty(); }
252a752e
VZ
803 // inform string about planned change in size
804 void reserve(size_t size) { Alloc(size); }
3c67202d
VZ
805
806 // lib.string.access
807 // return the character at position n
2bb67b80 808 wxChar at(size_t n) const { return GetChar(n); }
3c67202d 809 // returns the writable character at position n
2bb67b80 810 wxChar& at(size_t n) { return GetWritableChar(n); }
3c67202d 811
2bc07607
VZ
812 // first valid index position
813 const_iterator begin() const { return wx_str(); }
814 // position one after the last valid one
815 const_iterator end() const { return wx_str() + length(); }
816
3c67202d
VZ
817 // lib.string.modifiers
818 // append a string
819 wxString& append(const wxString& str)
820 { *this += str; return *this; }
821 // append elements str[pos], ..., str[pos+n]
822 wxString& append(const wxString& str, size_t pos, size_t n)
823 { ConcatSelf(n, str.c_str() + pos); return *this; }
824 // append first n (or all if n == npos) characters of sz
2bb67b80
OK
825 wxString& append(const wxChar *sz, size_t n = npos)
826 { ConcatSelf(n == npos ? wxStrlen(sz) : n, sz); return *this; }
3c67202d
VZ
827
828 // append n copies of ch
2bb67b80 829 wxString& append(size_t n, wxChar ch) { return Pad(n, ch); }
3c67202d
VZ
830
831 // same as `this_string = str'
735d1db6
VZ
832 wxString& assign(const wxString& str)
833 { return *this = str; }
3c67202d
VZ
834 // same as ` = str[pos..pos + n]
835 wxString& assign(const wxString& str, size_t pos, size_t n)
735d1db6 836 { Empty(); return Append(str.c_str() + pos, n); }
3c67202d 837 // same as `= first n (or all if n == npos) characters of sz'
2bb67b80 838 wxString& assign(const wxChar *sz, size_t n = npos)
735d1db6 839 { Empty(); return Append(sz, n == npos ? wxStrlen(sz) : n); }
3c67202d 840 // same as `= n copies of ch'
2bb67b80 841 wxString& assign(size_t n, wxChar ch)
735d1db6 842 { Empty(); return Append(ch, n); }
3c67202d
VZ
843
844 // insert another string
845 wxString& insert(size_t nPos, const wxString& str);
846 // insert n chars of str starting at nStart (in str)
847 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
2bb67b80 848 { return insert(nPos, wxString((const wxChar *)str + nStart, n)); }
3c67202d
VZ
849
850 // insert first n (or all if n == npos) characters of sz
2bb67b80 851 wxString& insert(size_t nPos, const wxChar *sz, size_t n = npos)
3c67202d
VZ
852 { return insert(nPos, wxString(sz, n)); }
853 // insert n copies of ch
2bb67b80 854 wxString& insert(size_t nPos, size_t n, wxChar ch)
3c67202d
VZ
855 { return insert(nPos, wxString(ch, n)); }
856
857 // delete characters from nStart to nStart + nLen
858 wxString& erase(size_t nStart = 0, size_t nLen = npos);
859
860 // replaces the substring of length nLen starting at nStart
2bb67b80 861 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz);
3c67202d 862 // replaces the substring with nCount copies of ch
2bb67b80 863 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
3c67202d
VZ
864 // replaces a substring with another substring
865 wxString& replace(size_t nStart, size_t nLen,
866 const wxString& str, size_t nStart2, size_t nLen2);
867 // replaces the substring with first nCount chars of sz
fb20fa43
VZ
868 wxString& replace(size_t nStart, size_t nLen,
869 const wxChar* sz, size_t nCount);
3c67202d
VZ
870
871 // swap two strings
872 void swap(wxString& str);
873
874 // All find() functions take the nStart argument which specifies the
875 // position to start the search on, the default value is 0. All functions
876 // return npos if there were no match.
877
878 // find a substring
879 size_t find(const wxString& str, size_t nStart = 0) const;
880
881 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 882#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 883 // find first n characters of sz
2bb67b80 884 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
fb20fa43 885#endif // VC++ 1.5
3c67202d
VZ
886
887 // Gives a duplicate symbol (presumably a case-insensitivity problem)
62448488 888#if !defined(__BORLANDC__)
3c67202d 889 // find the first occurence of character ch after nStart
2bb67b80 890 size_t find(wxChar ch, size_t nStart = 0) const;
62448488 891#endif
3c67202d
VZ
892 // rfind() family is exactly like find() but works right to left
893
894 // as find, but from the end
895 size_t rfind(const wxString& str, size_t nStart = npos) const;
896
897 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 898#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 899 // as find, but from the end
2bb67b80 900 size_t rfind(const wxChar* sz, size_t nStart = npos,
3c67202d
VZ
901 size_t n = npos) const;
902 // as find, but from the end
2bb67b80 903 size_t rfind(wxChar ch, size_t nStart = npos) const;
fb20fa43 904#endif // VC++ 1.5
3c67202d
VZ
905
906 // find first/last occurence of any character in the set
907
969d318c
VZ
908 // as strpbrk() but starts at nStart, returns npos if not found
909 size_t find_first_of(const wxString& str, size_t nStart = 0) const
910 { return find_first_of(str.c_str(), nStart); }
911 // same as above
2bb67b80 912 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
3c67202d 913 // same as find(char, size_t)
969d318c
VZ
914 size_t find_first_of(wxChar c, size_t nStart = 0) const
915 { return find(c, nStart); }
916 // find the last (starting from nStart) char from str in this string
917 size_t find_last_of (const wxString& str, size_t nStart = npos) const
918 { return find_last_of(str.c_str(), nStart); }
919 // same as above
920 size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
921 // same as above
922 size_t find_last_of(wxChar c, size_t nStart = npos) const
923 { return rfind(c, nStart); }
3c67202d
VZ
924
925 // find first/last occurence of any character not in the set
926
969d318c
VZ
927 // as strspn() (starting from nStart), returns npos on failure
928 size_t find_first_not_of(const wxString& str, size_t nStart = 0) const
929 { return find_first_not_of(str.c_str(), nStart); }
930 // same as above
931 size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
932 // same as above
2bb67b80 933 size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
969d318c 934 // as strcspn()
fb20fa43
VZ
935 size_t find_last_not_of(const wxString& str, size_t nStart = npos) const
936 { return find_first_not_of(str.c_str(), nStart); }
969d318c
VZ
937 // same as above
938 size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
939 // same as above
2bb67b80 940 size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
3c67202d
VZ
941
942 // All compare functions return -1, 0 or 1 if the [sub]string is less,
943 // equal or greater than the compare() argument.
944
945 // just like strcmp()
946 int compare(const wxString& str) const { return Cmp(str); }
947 // comparison with a substring
fb20fa43
VZ
948 int compare(size_t nStart, size_t nLen, const wxString& str) const
949 { return Mid(nStart, nLen).Cmp(str); }
3c67202d
VZ
950 // comparison of 2 substrings
951 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
952 const wxString& str, size_t nStart2, size_t nLen2) const
953 { return Mid(nStart, nLen).Cmp(str.Mid(nStart2, nLen2)); }
3c67202d 954 // just like strcmp()
2bb67b80 955 int compare(const wxChar* sz) const { return Cmp(sz); }
3c67202d
VZ
956 // substring comparison with first nCount characters of sz
957 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
958 const wxChar* sz, size_t nCount = npos) const
959 { return Mid(nStart, nLen).Cmp(wxString(sz, nCount)); }
3c67202d
VZ
960
961 // substring extraction
8c264b23
VZ
962 wxString substr(size_t nStart = 0, size_t nLen = npos) const
963 { return Mid(nStart, nLen); }
3c67202d 964#endif // wxSTD_STRING_COMPATIBILITY
c801d85f
KB
965};
966
967// ----------------------------------------------------------------------------
3c67202d
VZ
968// The string array uses it's knowledge of internal structure of the wxString
969// class to optimize string storage. Normally, we would store pointers to
970// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
971// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
972// really all we need to turn such pointer into a string!
973//
974// Of course, it can be called a dirty hack, but we use twice less memory and
975// this approach is also more speed efficient, so it's probably worth it.
976//
977// Usage notes: when a string is added/inserted, a new copy of it is created,
978// so the original string may be safely deleted. When a string is retrieved
979// from the array (operator[] or Item() method), a reference is returned.
c801d85f 980// ----------------------------------------------------------------------------
e90c1d2a 981
fbcb4166 982class WXDLLEXPORT wxArrayString
c801d85f
KB
983{
984public:
30b21f9a
VZ
985 // type of function used by wxArrayString::Sort()
986 typedef int (*CompareFunction)(const wxString& first,
987 const wxString& second);
988
3c67202d 989 // constructors and destructor
e87271f3
VZ
990 // default ctor: if autoSort is TRUE, the array is always sorted (in
991 // alphabetical order)
992 wxArrayString(bool autoSort = FALSE);
3c67202d 993 // copy ctor
c801d85f 994 wxArrayString(const wxArrayString& array);
3c67202d 995 // assignment operator
c801d85f 996 wxArrayString& operator=(const wxArrayString& src);
3c67202d 997 // not virtual, this class should not be derived from
c801d85f 998 ~wxArrayString();
c801d85f 999
3c67202d
VZ
1000 // memory management
1001 // empties the list, but doesn't release memory
c801d85f 1002 void Empty();
3c67202d 1003 // empties the list and releases memory
c801d85f 1004 void Clear();
3c67202d 1005 // preallocates memory for given number of items
c801d85f 1006 void Alloc(size_t nCount);
3c67202d 1007 // minimzes the memory usage (by freeing all extra memory)
dd1eaa89 1008 void Shrink();
3c67202d
VZ
1009
1010 // simple accessors
1011 // number of elements in the array
1012 size_t GetCount() const { return m_nCount; }
1013 // is it empty?
1014 bool IsEmpty() const { return m_nCount == 0; }
1015 // number of elements in the array (GetCount is preferred API)
1016 size_t Count() const { return m_nCount; }
1017
1018 // items access (range checking is done in debug version)
1019 // get item at position uiIndex
c801d85f
KB
1020 wxString& Item(size_t nIndex) const
1021 { wxASSERT( nIndex < m_nCount ); return *(wxString *)&(m_pItems[nIndex]); }
3c67202d 1022 // same as Item()
c801d85f 1023 wxString& operator[](size_t nIndex) const { return Item(nIndex); }
3c67202d 1024 // get last item
c801d85f 1025 wxString& Last() const { wxASSERT( !IsEmpty() ); return Item(Count() - 1); }
3c67202d
VZ
1026
1027 // item management
1028 // Search the element in the array, starting from the beginning if
1029 // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case
1030 // sensitive (default). Returns index of the first item matched or
1031 // wxNOT_FOUND
2bb67b80 1032 int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
e01c8145
VZ
1033 // add new element at the end (if the array is not sorted), return its
1034 // index
1035 size_t Add(const wxString& str);
3c67202d 1036 // add new element at given position
c86f1403 1037 void Insert(const wxString& str, size_t uiIndex);
71e03035
VZ
1038 // expand the array to have count elements
1039 void SetCount(size_t count);
3c67202d 1040 // remove first item matching this value
2bb67b80 1041 void Remove(const wxChar *sz);
3c67202d 1042 // remove item by index
c801d85f 1043 void Remove(size_t nIndex);
28a156b1 1044 void RemoveAt(size_t nIndex) { Remove(nIndex); }
c801d85f 1045
30b21f9a
VZ
1046 // sorting
1047 // sort array elements in alphabetical order (or reversed alphabetical
1048 // order if reverseOrder parameter is TRUE)
1049 void Sort(bool reverseOrder = FALSE);
1050 // sort array elements using specified comparaison function
1051 void Sort(CompareFunction compareFunction);
c801d85f 1052
f6bcfd97
BP
1053 // comparison
1054 // compare two arrays case sensitively
1055 bool operator==(const wxArrayString& a) const;
1056 // compare two arrays case sensitively
1057 bool operator!=(const wxArrayString& a) const { return !(*this == a); }
1058
e87271f3
VZ
1059protected:
1060 void Copy(const wxArrayString& src); // copies the contents of another array
1061
c801d85f 1062private:
e87271f3
VZ
1063 void Grow(); // makes array bigger if needed
1064 void Free(); // free all the strings stored
c801d85f 1065
e87271f3 1066 void DoSort(); // common part of all Sort() variants
30b21f9a 1067
3c67202d 1068 size_t m_nSize, // current size of the array
c801d85f
KB
1069 m_nCount; // current number of elements
1070
e87271f3
VZ
1071 wxChar **m_pItems; // pointer to data
1072
1073 bool m_autoSort; // if TRUE, keep the array always sorted
1074};
1075
1076class WXDLLEXPORT wxSortedArrayString : public wxArrayString
1077{
1078public:
1079 wxSortedArrayString() : wxArrayString(TRUE)
1080 { }
1081 wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE)
1082 { Copy(array); }
c801d85f
KB
1083};
1084
c801d85f 1085// ---------------------------------------------------------------------------
3c67202d 1086// wxString comparison functions: operator versions are always case sensitive
c801d85f 1087// ---------------------------------------------------------------------------
f33fee2a 1088
0cbe5ee3
VZ
1089inline bool operator==(const wxString& s1, const wxString& s2)
1090 { return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); }
1091inline bool operator==(const wxString& s1, const wxChar * s2)
1092 { return s1.Cmp(s2) == 0; }
1093inline bool operator==(const wxChar * s1, const wxString& s2)
1094 { return s2.Cmp(s1) == 0; }
1095inline bool operator!=(const wxString& s1, const wxString& s2)
1096 { return (s1.Len() != s2.Len()) || (s1.Cmp(s2) != 0); }
1097inline bool operator!=(const wxString& s1, const wxChar * s2)
1098 { return s1.Cmp(s2) != 0; }
1099inline bool operator!=(const wxChar * s1, const wxString& s2)
1100 { return s2.Cmp(s1) != 0; }
1101inline bool operator< (const wxString& s1, const wxString& s2)
1102 { return s1.Cmp(s2) < 0; }
1103inline bool operator< (const wxString& s1, const wxChar * s2)
1104 { return s1.Cmp(s2) < 0; }
1105inline bool operator< (const wxChar * s1, const wxString& s2)
1106 { return s2.Cmp(s1) > 0; }
1107inline bool operator> (const wxString& s1, const wxString& s2)
1108 { return s1.Cmp(s2) > 0; }
1109inline bool operator> (const wxString& s1, const wxChar * s2)
1110 { return s1.Cmp(s2) > 0; }
1111inline bool operator> (const wxChar * s1, const wxString& s2)
1112 { return s2.Cmp(s1) < 0; }
1113inline bool operator<=(const wxString& s1, const wxString& s2)
1114 { return s1.Cmp(s2) <= 0; }
1115inline bool operator<=(const wxString& s1, const wxChar * s2)
1116 { return s1.Cmp(s2) <= 0; }
1117inline bool operator<=(const wxChar * s1, const wxString& s2)
1118 { return s2.Cmp(s1) >= 0; }
1119inline bool operator>=(const wxString& s1, const wxString& s2)
1120 { return s1.Cmp(s2) >= 0; }
1121inline bool operator>=(const wxString& s1, const wxChar * s2)
1122 { return s1.Cmp(s2) >= 0; }
1123inline bool operator>=(const wxChar * s1, const wxString& s2)
1124 { return s2.Cmp(s1) <= 0; }
3c67202d 1125
f33fee2a
VZ
1126// comparison with char
1127inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
1128inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
1129inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
1130inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
1131
5ca07d0f
OK
1132#if wxUSE_UNICODE
1133inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
f33fee2a 1134 { return (s1.Cmp((const wchar_t *)s2) == 0); }
5ca07d0f 1135inline bool operator==(const wxWCharBuffer& s1, const wxString& s2)
f33fee2a 1136 { return (s2.Cmp((const wchar_t *)s1) == 0); }
f6bcfd97
BP
1137inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2)
1138 { return (s1.Cmp((const wchar_t *)s2) != 0); }
1139inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2)
1140 { return (s2.Cmp((const wchar_t *)s1) != 0); }
0cbe5ee3 1141#else // !wxUSE_UNICODE
5ca07d0f 1142inline bool operator==(const wxString& s1, const wxCharBuffer& s2)
f33fee2a 1143 { return (s1.Cmp((const char *)s2) == 0); }
5ca07d0f 1144inline bool operator==(const wxCharBuffer& s1, const wxString& s2)
f33fee2a 1145 { return (s2.Cmp((const char *)s1) == 0); }
f6bcfd97
BP
1146inline bool operator!=(const wxString& s1, const wxCharBuffer& s2)
1147 { return (s1.Cmp((const char *)s2) != 0); }
1148inline bool operator!=(const wxCharBuffer& s1, const wxString& s2)
1149 { return (s2.Cmp((const char *)s1) != 0); }
0cbe5ee3 1150#endif // wxUSE_UNICODE/!wxUSE_UNICODE
5ca07d0f 1151
ed7174ba 1152wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
2bb67b80
OK
1153wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
1154wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
1155wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
1156wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
028a2b5d 1157#if wxUSE_UNICODE
6d56eb5c 1158inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
e90c1d2a 1159 { return string + (const wchar_t *)buf; }
6d56eb5c 1160inline wxString operator+(const wxWCharBuffer& buf, const wxString& string)
e90c1d2a 1161 { return (const wchar_t *)buf + string; }
0cbe5ee3 1162#else // !wxUSE_UNICODE
6d56eb5c 1163inline wxString operator+(const wxString& string, const wxCharBuffer& buf)
e90c1d2a 1164 { return string + (const char *)buf; }
6d56eb5c 1165inline wxString operator+(const wxCharBuffer& buf, const wxString& string)
e90c1d2a 1166 { return (const char *)buf + string; }
0cbe5ee3 1167#endif // wxUSE_UNICODE/!wxUSE_UNICODE
f04f3991 1168
c801d85f 1169// ---------------------------------------------------------------------------
3c67202d 1170// Implementation only from here until the end of file
c801d85f
KB
1171// ---------------------------------------------------------------------------
1172
e90c1d2a
VZ
1173// don't pollute the library user's name space
1174#undef ASSERT_VALID_INDEX
1175
38830220 1176#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM
c801d85f 1177
3f4a0c5b 1178#include "wx/ioswrap.h"
c801d85f 1179
dd107c50
VZ
1180WXDLLEXPORT wxSTD istream& operator>>(wxSTD istream&, wxString&);
1181WXDLLEXPORT wxSTD ostream& operator<<(wxSTD ostream&, const wxString&);
c801d85f 1182
3c67202d 1183#endif // wxSTD_STRING_COMPATIBILITY
c801d85f 1184
34138703 1185#endif // _WX_WXSTRINGH__