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