]> git.saurik.com Git - wxWidgets.git/blob - include/wx/string.h
a00d97d59d026a17d88aa8de987305ecf8370c43
[wxWidgets.git] / include / wx / string.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/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 licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 /*
13 Efficient string class [more or less] compatible with MFC CString,
14 wxWidgets 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 // ----------------------------------------------------------------------------
22 // headers
23 // ----------------------------------------------------------------------------
24
25 #include "wx/defs.h" // everybody should include this
26
27 #if defined(__WXMAC__) || defined(__VISAGECPP__)
28 #include <ctype.h>
29 #endif
30
31 #if defined(__VISAGECPP__) && __IBMCPP__ >= 400
32 // problem in VACPP V4 with including stdlib.h multiple times
33 // strconv includes it anyway
34 # include <stdio.h>
35 # include <string.h>
36 # include <stdarg.h>
37 # include <limits.h>
38 #else
39 # include <string.h>
40 # include <stdio.h>
41 # include <stdarg.h>
42 # include <limits.h>
43 # include <stdlib.h>
44 #endif
45
46 #ifdef HAVE_STRCASECMP_IN_STRINGS_H
47 #include <strings.h> // for strcasecmp()
48 #endif // HAVE_STRCASECMP_IN_STRINGS_H
49
50 #ifdef __WXPALMOS__
51 #include <StringMgr.h>
52 #endif
53
54 #include "wx/wxchar.h" // for wxChar, wxStrlen() etc.
55 #include "wx/unichar.h"
56 #include "wx/strvararg.h"
57 #include "wx/buffer.h" // for wxCharBuffer
58 #include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
59
60 class WXDLLIMPEXP_BASE wxString;
61
62 // ---------------------------------------------------------------------------
63 // macros
64 // ---------------------------------------------------------------------------
65
66 // casts [unfortunately!] needed to call some broken functions which require
67 // "char *" instead of "const char *"
68 #define WXSTRINGCAST (wxChar *)(const wxChar *)
69 #define wxCSTRINGCAST (wxChar *)(const wxChar *)
70 #define wxMBSTRINGCAST (char *)(const char *)
71 #define wxWCSTRINGCAST (wchar_t *)(const wchar_t *)
72
73 // implementation only
74 #define wxASSERT_VALID_INDEX(i) \
75 wxASSERT_MSG( (size_t)(i) <= length(), _T("invalid index in wxString") )
76
77 // ----------------------------------------------------------------------------
78 // constants
79 // ----------------------------------------------------------------------------
80
81 #if WXWIN_COMPATIBILITY_2_6
82
83 // deprecated in favour of wxString::npos, don't use in new code
84 //
85 // maximum possible length for a string means "take all string" everywhere
86 #define wxSTRING_MAXLEN wxStringBase::npos
87
88 #endif // WXWIN_COMPATIBILITY_2_6
89
90 // ----------------------------------------------------------------------------
91 // global data
92 // ----------------------------------------------------------------------------
93
94 // global pointer to empty string
95 extern WXDLLIMPEXP_DATA_BASE(const wxChar*) wxEmptyString;
96
97 // ---------------------------------------------------------------------------
98 // global functions complementing standard C string library replacements for
99 // strlen() and portable strcasecmp()
100 //---------------------------------------------------------------------------
101
102 // Use wxXXX() functions from wxcrt.h instead! These functions are for
103 // backwards compatibility only.
104
105 // checks whether the passed in pointer is NULL and if the string is empty
106 inline bool IsEmpty(const char *p) { return (!p || !*p); }
107
108 // safe version of strlen() (returns 0 if passed NULL pointer)
109 inline size_t Strlen(const char *psz)
110 { return psz ? strlen(psz) : 0; }
111
112 // portable strcasecmp/_stricmp
113 inline int Stricmp(const char *psz1, const char *psz2)
114 {
115 #if defined(__VISUALC__) && defined(__WXWINCE__)
116 register char c1, c2;
117 do {
118 c1 = tolower(*psz1++);
119 c2 = tolower(*psz2++);
120 } while ( c1 && (c1 == c2) );
121
122 return c1 - c2;
123 #elif defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) )
124 return _stricmp(psz1, psz2);
125 #elif defined(__SC__)
126 return _stricmp(psz1, psz2);
127 #elif defined(__SALFORDC__)
128 return stricmp(psz1, psz2);
129 #elif defined(__BORLANDC__)
130 return stricmp(psz1, psz2);
131 #elif defined(__WATCOMC__)
132 return stricmp(psz1, psz2);
133 #elif defined(__DJGPP__)
134 return stricmp(psz1, psz2);
135 #elif defined(__EMX__)
136 return stricmp(psz1, psz2);
137 #elif defined(__WXPM__)
138 return stricmp(psz1, psz2);
139 #elif defined(__WXPALMOS__) || \
140 defined(HAVE_STRCASECMP_IN_STRING_H) || \
141 defined(HAVE_STRCASECMP_IN_STRINGS_H) || \
142 defined(__GNUWIN32__)
143 return strcasecmp(psz1, psz2);
144 #elif defined(__MWERKS__) && !defined(__INTEL__)
145 register char c1, c2;
146 do {
147 c1 = tolower(*psz1++);
148 c2 = tolower(*psz2++);
149 } while ( c1 && (c1 == c2) );
150
151 return c1 - c2;
152 #else
153 // almost all compilers/libraries provide this function (unfortunately under
154 // different names), that's why we don't implement our own which will surely
155 // be more efficient than this code (uncomment to use):
156 /*
157 register char c1, c2;
158 do {
159 c1 = tolower(*psz1++);
160 c2 = tolower(*psz2++);
161 } while ( c1 && (c1 == c2) );
162
163 return c1 - c2;
164 */
165
166 #error "Please define string case-insensitive compare for your OS/compiler"
167 #endif // OS/compiler
168 }
169
170 // ----------------------------------------------------------------------------
171 // deal with STL/non-STL/non-STL-but-wxUSE_STD_STRING
172 // ----------------------------------------------------------------------------
173
174 // in both cases we need to define wxStdString
175 #if wxUSE_STL || wxUSE_STD_STRING
176
177 #include "wx/beforestd.h"
178 #include <string>
179 #include "wx/afterstd.h"
180
181 #if wxUSE_UNICODE
182 #ifdef HAVE_STD_WSTRING
183 typedef std::wstring wxStdString;
184 #else
185 typedef std::basic_string<wxChar> wxStdString;
186 #endif
187 #else
188 typedef std::string wxStdString;
189 #endif
190
191 #endif // need <string>
192
193 #if wxUSE_STL
194
195 // we don't need an extra ctor from std::string when copy ctor already does
196 // the work
197 #undef wxUSE_STD_STRING
198 #define wxUSE_STD_STRING 0
199
200 #if (defined(__GNUG__) && (__GNUG__ < 3)) || \
201 (defined(_MSC_VER) && (_MSC_VER <= 1200))
202 #define wxSTRING_BASE_HASNT_CLEAR
203 #endif
204
205 typedef wxStdString wxStringBase;
206 #else // if !wxUSE_STL
207
208 #if !defined(HAVE_STD_STRING_COMPARE) && \
209 (!defined(__WX_SETUP_H__) || wxUSE_STL == 0)
210 #define HAVE_STD_STRING_COMPARE
211 #endif
212
213 // ---------------------------------------------------------------------------
214 // string data prepended with some housekeeping info (used by wxString class),
215 // is never used directly (but had to be put here to allow inlining)
216 // ---------------------------------------------------------------------------
217
218 struct WXDLLIMPEXP_BASE wxStringData
219 {
220 int nRefs; // reference count
221 size_t nDataLength, // actual string length
222 nAllocLength; // allocated memory size
223
224 // mimics declaration 'wxChar data[nAllocLength]'
225 wxChar* data() const { return (wxChar*)(this + 1); }
226
227 // empty string has a special ref count so it's never deleted
228 bool IsEmpty() const { return (nRefs == -1); }
229 bool IsShared() const { return (nRefs > 1); }
230
231 // lock/unlock
232 void Lock() { if ( !IsEmpty() ) nRefs++; }
233
234 // VC++ will refuse to inline Unlock but profiling shows that it is wrong
235 #if defined(__VISUALC__) && (__VISUALC__ >= 1200)
236 __forceinline
237 #endif
238 // VC++ free must take place in same DLL as allocation when using non dll
239 // run-time library (e.g. Multithreaded instead of Multithreaded DLL)
240 #if defined(__VISUALC__) && defined(_MT) && !defined(_DLL)
241 void Unlock() { if ( !IsEmpty() && --nRefs == 0) Free(); }
242 // we must not inline deallocation since allocation is not inlined
243 void Free();
244 #else
245 void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
246 #endif
247
248 // if we had taken control over string memory (GetWriteBuf), it's
249 // intentionally put in invalid state
250 void Validate(bool b) { nRefs = (b ? 1 : 0); }
251 bool IsValid() const { return (nRefs != 0); }
252 };
253
254 class WXDLLIMPEXP_BASE wxStringBase
255 {
256 public :
257 // an 'invalid' value for string index, moved to this place due to a CW bug
258 static const size_t npos;
259 protected:
260 // points to data preceded by wxStringData structure with ref count info
261 wxChar *m_pchData;
262
263 // accessor to string data
264 wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
265
266 // string (re)initialization functions
267 // initializes the string to the empty value (must be called only from
268 // ctors, use Reinit() otherwise)
269 void Init() { m_pchData = (wxChar *)wxEmptyString; }
270 // initializes the string with (a part of) C-string
271 void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = npos);
272 // as Init, but also frees old data
273 void Reinit() { GetStringData()->Unlock(); Init(); }
274
275 // memory allocation
276 // allocates memory for string of length nLen
277 bool AllocBuffer(size_t nLen);
278 // copies data to another string
279 bool AllocCopy(wxString&, int, int) const;
280 // effectively copies data to string
281 bool AssignCopy(size_t, const wxChar *);
282
283 // append a (sub)string
284 bool ConcatSelf(size_t nLen, const wxChar *src, size_t nMaxLen);
285 bool ConcatSelf(size_t nLen, const wxChar *src)
286 { return ConcatSelf(nLen, src, nLen); }
287
288 // functions called before writing to the string: they copy it if there
289 // are other references to our data (should be the only owner when writing)
290 bool CopyBeforeWrite();
291 bool AllocBeforeWrite(size_t);
292
293 // compatibility with wxString
294 bool Alloc(size_t nLen);
295 public:
296 // standard types
297 typedef wxUniChar value_type;
298 typedef wxUniChar char_type;
299 typedef wxUniCharRef reference;
300 typedef wxChar* pointer;
301 typedef const wxChar* const_pointer;
302
303 typedef size_t size_type;
304 typedef wxUniChar const_reference;
305
306 #define WX_STR_ITERATOR_IMPL(iterator_name, pointer_type, \
307 reference_type, reference_ctor) \
308 public: \
309 typedef wxUniChar value_type; \
310 typedef reference_type reference; \
311 typedef pointer_type pointer; \
312 \
313 iterator_name(const iterator_name& i) : m_cur(i.m_cur) {} \
314 \
315 reference operator*() const { return reference_ctor; } \
316 \
317 iterator_name& operator++() \
318 { ++m_cur; return *this; } \
319 iterator_name operator++(int) \
320 { iterator_name tmp = *this; ++m_cur; return tmp; } \
321 iterator_name& operator--() \
322 { --m_cur; return *this; } \
323 iterator_name operator--(int) \
324 { iterator_name tmp = *this; --m_cur; return tmp; } \
325 \
326 iterator_name operator+(int n) const \
327 { return iterator_name(m_cur + n); } \
328 iterator_name operator+(size_t n) const \
329 { return iterator_name(m_cur + n); } \
330 iterator_name operator-(int n) const \
331 { return iterator_name(m_cur - n); } \
332 iterator_name operator-(size_t n) const \
333 { return iterator_name(m_cur - n); } \
334 iterator_name operator+=(int n) \
335 { m_cur += n; return *this; } \
336 iterator_name operator+=(size_t n) \
337 { m_cur += n; return *this; } \
338 iterator_name operator-=(int n) \
339 { m_cur -= n; return *this; } \
340 iterator_name operator-=(size_t n) \
341 { m_cur -= n; return *this; } \
342 \
343 unsigned operator-(const iterator_name& i) const \
344 { return m_cur - i.m_cur; } \
345 \
346 bool operator==(const iterator_name&i) const \
347 { return m_cur == i.m_cur; } \
348 bool operator!=(const iterator_name& i) const \
349 { return m_cur != i.m_cur; } \
350 \
351 bool operator<(const iterator_name& i) const \
352 { return m_cur < i.m_cur; } \
353 bool operator>(const iterator_name& i) const \
354 { return m_cur > i.m_cur; } \
355 bool operator<=(const iterator_name& i) const \
356 { return m_cur <= i.m_cur; } \
357 bool operator>=(const iterator_name& i) const \
358 { return m_cur >= i.m_cur; } \
359 \
360 protected: \
361 /* for internal wxString use only: */ \
362 iterator_name(pointer ptr) : m_cur(ptr) {} \
363 operator pointer() const { return m_cur; } \
364 \
365 friend class WXDLLIMPEXP_BASE wxString; \
366 friend class WXDLLIMPEXP_BASE wxStringBase; \
367 friend class WXDLLIMPEXP_BASE wxCStrData; \
368 \
369 protected: \
370 pointer m_cur;
371
372 class const_iterator;
373
374 class iterator
375 {
376 WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef,
377 wxUniCharRef::CreateForString(m_cur))
378
379 friend class const_iterator;
380 };
381
382 class const_iterator
383 {
384 // NB: reference_type is intentionally value, not reference, the character
385 // may be encoded differently in wxString data:
386 WX_STR_ITERATOR_IMPL(const_iterator, const wxChar*, wxUniChar,
387 wxUniChar(*m_cur))
388
389 public:
390 const_iterator(const iterator& i) : m_cur(i.m_cur) {}
391 };
392
393 #undef WX_STR_ITERATOR
394
395 template <typename T>
396 class reverse_iterator_impl
397 {
398 public:
399 typedef T iterator_type;
400 typedef typename T::value_type value_type;
401 typedef typename T::reference reference;
402 typedef typename T::pointer *pointer;
403
404 reverse_iterator_impl(iterator_type i) : m_cur(i) {}
405 reverse_iterator_impl(const reverse_iterator_impl& ri)
406 : m_cur(ri.m_cur) {}
407
408 iterator_type base() const { return m_cur; }
409
410 reference operator*() const { return *(m_cur-1); }
411
412 reverse_iterator_impl& operator++()
413 { --m_cur; return *this; }
414 reverse_iterator_impl operator++(int)
415 { reverse_iterator_impl tmp = *this; --m_cur; return tmp; }
416 reverse_iterator_impl& operator--()
417 { ++m_cur; return *this; }
418 reverse_iterator_impl operator--(int)
419 { reverse_iterator_impl tmp = *this; ++m_cur; return tmp; }
420
421 bool operator==(const reverse_iterator_impl& ri) const
422 { return m_cur == ri.m_cur; }
423 bool operator!=(const reverse_iterator_impl& ri) const
424 { return !(*this == ri); }
425
426 private:
427 iterator_type m_cur;
428 };
429
430 typedef reverse_iterator_impl<iterator> reverse_iterator;
431 typedef reverse_iterator_impl<const_iterator> const_reverse_iterator;
432
433
434 // constructors and destructor
435 // ctor for an empty string
436 wxStringBase() { Init(); }
437 // copy ctor
438 wxStringBase(const wxStringBase& stringSrc)
439 {
440 wxASSERT_MSG( stringSrc.GetStringData()->IsValid(),
441 _T("did you forget to call UngetWriteBuf()?") );
442
443 if ( stringSrc.empty() ) {
444 // nothing to do for an empty string
445 Init();
446 }
447 else {
448 m_pchData = stringSrc.m_pchData; // share same data
449 GetStringData()->Lock(); // => one more copy
450 }
451 }
452 // string containing nRepeat copies of ch
453 wxStringBase(size_type nRepeat, wxUniChar ch);
454 // ctor takes first nLength characters from C string
455 // (default value of npos means take all the string)
456 wxStringBase(const wxChar *psz)
457 { InitWith(psz, 0, npos); }
458 wxStringBase(const wxChar *psz, size_t nLength)
459 { InitWith(psz, 0, nLength); }
460 wxStringBase(const wxChar *psz,
461 const wxMBConv& WXUNUSED(conv),
462 size_t nLength = npos)
463 { InitWith(psz, 0, nLength); }
464 // take nLen chars starting at nPos
465 wxStringBase(const wxStringBase& str, size_t nPos, size_t nLen)
466 {
467 wxASSERT_MSG( str.GetStringData()->IsValid(),
468 _T("did you forget to call UngetWriteBuf()?") );
469 Init();
470 size_t strLen = str.length() - nPos; nLen = strLen < nLen ? strLen : nLen;
471 InitWith(str.c_str(), nPos, nLen);
472 }
473 // take all characters from pStart to pEnd
474 wxStringBase(const void *pStart, const void *pEnd);
475
476 // dtor is not virtual, this class must not be inherited from!
477 ~wxStringBase()
478 {
479 #if defined(__VISUALC__) && (__VISUALC__ >= 1200)
480 //RN - according to the above VC++ does indeed inline this,
481 //even though it spits out two warnings
482 #pragma warning (disable:4714)
483 #endif
484
485 GetStringData()->Unlock();
486 }
487
488 #if defined(__VISUALC__) && (__VISUALC__ >= 1200)
489 //re-enable inlining warning
490 #pragma warning (default:4714)
491 #endif
492 // overloaded assignment
493 // from another wxString
494 wxStringBase& operator=(const wxStringBase& stringSrc);
495 // from a character
496 wxStringBase& operator=(wxUniChar ch);
497 // from a C string
498 wxStringBase& operator=(const wxChar *psz);
499
500 // return the length of the string
501 size_type length() const { return GetStringData()->nDataLength; }
502 // return the length of the string
503 size_type size() const { return length(); }
504 // return the maximum size of the string
505 size_type max_size() const { return npos; }
506 // resize the string, filling the space with c if c != 0
507 void resize(size_t nSize, wxUniChar ch = wxT('\0'));
508 // delete the contents of the string
509 void clear() { erase(0, npos); }
510 // returns true if the string is empty
511 bool empty() const { return length() == 0; }
512 // inform string about planned change in size
513 void reserve(size_t sz) { Alloc(sz); }
514 size_type capacity() const { return GetStringData()->nAllocLength; }
515
516 // lib.string.access
517 // return the character at position n
518 value_type at(size_type n) const
519 { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
520 // returns the writable character at position n
521 reference at(size_type n)
522 {
523 wxASSERT_VALID_INDEX( n );
524 CopyBeforeWrite();
525 return wxUniCharRef::CreateForString(&m_pchData[n]);
526 }
527
528 // lib.string.modifiers
529 // append elements str[pos], ..., str[pos+n]
530 wxStringBase& append(const wxStringBase& str, size_t pos, size_t n)
531 {
532 wxASSERT(pos <= str.length());
533 ConcatSelf(n, str.c_str() + pos, str.length() - pos);
534 return *this;
535 }
536 // append a string
537 wxStringBase& append(const wxStringBase& str)
538 { ConcatSelf(str.length(), str.c_str()); return *this; }
539 // append first n (or all if n == npos) characters of sz
540 wxStringBase& append(const wxChar *sz)
541 { ConcatSelf(wxStrlen(sz), sz); return *this; }
542 wxStringBase& append(const wxChar *sz, size_t n)
543 { ConcatSelf(n, sz); return *this; }
544 // append n copies of ch
545 wxStringBase& append(size_t n, wxUniChar ch);
546 // append from first to last
547 wxStringBase& append(const_iterator first, const_iterator last)
548 { ConcatSelf(last - first, first); return *this; }
549
550 // same as `this_string = str'
551 wxStringBase& assign(const wxStringBase& str)
552 { return *this = str; }
553 // same as ` = str[pos..pos + n]
554 wxStringBase& assign(const wxStringBase& str, size_t pos, size_t n)
555 { clear(); return append(str, pos, n); }
556 // same as `= first n (or all if n == npos) characters of sz'
557 wxStringBase& assign(const wxChar *sz)
558 { clear(); return append(sz, wxStrlen(sz)); }
559 wxStringBase& assign(const wxChar *sz, size_t n)
560 { clear(); return append(sz, n); }
561 // same as `= n copies of ch'
562 wxStringBase& assign(size_t n, wxUniChar ch)
563 { clear(); return append(n, ch); }
564 // assign from first to last
565 wxStringBase& assign(const_iterator first, const_iterator last)
566 { clear(); return append(first, last); }
567
568 // first valid index position
569 const_iterator begin() const { return m_pchData; }
570 iterator begin();
571 // position one after the last valid one
572 const_iterator end() const { return m_pchData + length(); }
573 iterator end();
574
575 // first element of the reversed string
576 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
577 reverse_iterator rbegin() { return reverse_iterator(end()); }
578 // one beyond the end of the reversed string
579 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
580 reverse_iterator rend() { return reverse_iterator(begin()); }
581
582 // insert another string
583 wxStringBase& insert(size_t nPos, const wxStringBase& str)
584 {
585 wxASSERT( str.GetStringData()->IsValid() );
586 return insert(nPos, str.c_str(), str.length());
587 }
588 // insert n chars of str starting at nStart (in str)
589 wxStringBase& insert(size_t nPos, const wxStringBase& str, size_t nStart, size_t n)
590 {
591 wxASSERT( str.GetStringData()->IsValid() );
592 wxASSERT( nStart < str.length() );
593 size_t strLen = str.length() - nStart;
594 n = strLen < n ? strLen : n;
595 return insert(nPos, str.c_str() + nStart, n);
596 }
597 // insert first n (or all if n == npos) characters of sz
598 wxStringBase& insert(size_t nPos, const wxChar *sz, size_t n = npos);
599 // insert n copies of ch
600 wxStringBase& insert(size_t nPos, size_t n, wxUniChar ch)
601 { return insert(nPos, wxStringBase(n, ch)); }
602 iterator insert(iterator it, wxUniChar ch)
603 { size_t idx = it - begin(); insert(idx, 1, ch); return begin() + idx; }
604 void insert(iterator it, const_iterator first, const_iterator last)
605 { insert(it - begin(), first, last - first); }
606 void insert(iterator it, size_type n, wxUniChar ch)
607 { insert(it - begin(), n, ch); }
608
609 // delete characters from nStart to nStart + nLen
610 wxStringBase& erase(size_type pos = 0, size_type n = npos);
611 iterator erase(iterator first, iterator last)
612 {
613 size_t idx = first - begin();
614 erase(idx, last - first);
615 return begin() + idx;
616 }
617 iterator erase(iterator first);
618
619 // explicit conversion to C string (use this with printf()!)
620 const wxChar* c_str() const { return m_pchData; }
621 const wxChar* data() const { return m_pchData; }
622
623 // replaces the substring of length nLen starting at nStart
624 wxStringBase& replace(size_t nStart, size_t nLen, const wxChar* sz);
625 // replaces the substring of length nLen starting at nStart
626 wxStringBase& replace(size_t nStart, size_t nLen, const wxStringBase& str)
627 { return replace(nStart, nLen, str.c_str()); }
628 // replaces the substring with nCount copies of ch
629 wxStringBase& replace(size_t nStart, size_t nLen, size_t nCount, wxUniChar ch);
630 // replaces a substring with another substring
631 wxStringBase& replace(size_t nStart, size_t nLen,
632 const wxStringBase& str, size_t nStart2, size_t nLen2);
633 // replaces the substring with first nCount chars of sz
634 wxStringBase& replace(size_t nStart, size_t nLen,
635 const wxChar* sz, size_t nCount);
636 wxStringBase& replace(iterator first, iterator last, const_pointer s)
637 { return replace(first - begin(), last - first, s); }
638 wxStringBase& replace(iterator first, iterator last, const_pointer s,
639 size_type n)
640 { return replace(first - begin(), last - first, s, n); }
641 wxStringBase& replace(iterator first, iterator last, const wxStringBase& s)
642 { return replace(first - begin(), last - first, s); }
643 wxStringBase& replace(iterator first, iterator last, size_type n, wxUniChar c)
644 { return replace(first - begin(), last - first, n, c); }
645 wxStringBase& replace(iterator first, iterator last,
646 const_iterator first1, const_iterator last1)
647 { return replace(first - begin(), last - first, first1, last1 - first1); }
648
649 // swap two strings
650 void swap(wxStringBase& str);
651
652 // All find() functions take the nStart argument which specifies the
653 // position to start the search on, the default value is 0. All functions
654 // return npos if there were no match.
655
656 // find a substring
657 size_t find(const wxStringBase& str, size_t nStart = 0) const;
658
659 // find first n characters of sz
660 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
661
662 // find the first occurence of character ch after nStart
663 size_t find(wxUniChar ch, size_t nStart = 0) const;
664
665 // rfind() family is exactly like find() but works right to left
666
667 // as find, but from the end
668 size_t rfind(const wxStringBase& str, size_t nStart = npos) const;
669
670 // as find, but from the end
671 size_t rfind(const wxChar* sz, size_t nStart = npos,
672 size_t n = npos) const;
673 // as find, but from the end
674 size_t rfind(wxUniChar ch, size_t nStart = npos) const;
675
676 // find first/last occurence of any character in the set
677
678 // as strpbrk() but starts at nStart, returns npos if not found
679 size_t find_first_of(const wxStringBase& str, size_t nStart = 0) const
680 { return find_first_of(str.c_str(), nStart); }
681 // same as above
682 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
683 size_t find_first_of(const wxChar* sz, size_t nStart, size_t n) const;
684 // same as find(char, size_t)
685 size_t find_first_of(wxUniChar c, size_t nStart = 0) const
686 { return find(c, nStart); }
687 // find the last (starting from nStart) char from str in this string
688 size_t find_last_of (const wxStringBase& str, size_t nStart = npos) const
689 { return find_last_of(str.c_str(), nStart); }
690 // same as above
691 size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
692 size_t find_last_of(const wxChar* sz, size_t nStart, size_t n) const;
693 // same as above
694 size_t find_last_of(wxUniChar c, size_t nStart = npos) const
695 { return rfind(c, nStart); }
696
697 // find first/last occurence of any character not in the set
698
699 // as strspn() (starting from nStart), returns npos on failure
700 size_t find_first_not_of(const wxStringBase& str, size_t nStart = 0) const
701 { return find_first_not_of(str.c_str(), nStart); }
702 // same as above
703 size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
704 size_t find_first_not_of(const wxChar* sz, size_t nStart, size_t n) const;
705 // same as above
706 size_t find_first_not_of(wxUniChar ch, size_t nStart = 0) const;
707 // as strcspn()
708 size_t find_last_not_of(const wxStringBase& str, size_t nStart = npos) const
709 { return find_last_not_of(str.c_str(), nStart); }
710 // same as above
711 size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
712 size_t find_last_not_of(const wxChar* sz, size_t nStart, size_t n) const;
713 // same as above
714 size_t find_last_not_of(wxUniChar ch, size_t nStart = npos) const;
715
716 // All compare functions return -1, 0 or 1 if the [sub]string is less,
717 // equal or greater than the compare() argument.
718
719 // comparison with another string
720 int compare(const wxStringBase& str) const;
721 // comparison with a substring
722 int compare(size_t nStart, size_t nLen, const wxStringBase& str) const;
723 // comparison of 2 substrings
724 int compare(size_t nStart, size_t nLen,
725 const wxStringBase& str, size_t nStart2, size_t nLen2) const;
726 // comparison with a c string
727 int compare(const wxChar* sz) const;
728 // substring comparison with first nCount characters of sz
729 int compare(size_t nStart, size_t nLen,
730 const wxChar* sz, size_t nCount = npos) const;
731
732 size_type copy(wxChar* s, size_type n, size_type pos = 0);
733
734 // substring extraction
735 wxStringBase substr(size_t nStart = 0, size_t nLen = npos) const;
736
737 // string += string
738 wxStringBase& operator+=(const wxStringBase& s) { return append(s); }
739 // string += C string
740 wxStringBase& operator+=(const wxChar *psz) { return append(psz); }
741 // string += char
742 wxStringBase& operator+=(wxUniChar ch) { return append(1, ch); }
743 wxStringBase& operator+=(wxUniCharRef ch) { return append(1, ch); }
744 wxStringBase& operator+=(char ch) { return append(1, ch); }
745 wxStringBase& operator+=(wchar_t ch) { return append(1, ch); }
746 };
747
748 #endif // !wxUSE_STL
749
750 // ----------------------------------------------------------------------------
751 // wxCStrData
752 // ----------------------------------------------------------------------------
753
754 // Lightweight object returned by wxString::c_str() and implicitly convertible
755 // to either const char* or const wchar_t*.
756 class WXDLLIMPEXP_BASE wxCStrData
757 {
758 private:
759 // Ctors; for internal use by wxString and wxCStrData only
760 wxCStrData(const wxString *str, size_t offset = 0, bool owned = false)
761 : m_str(str), m_offset(offset), m_owned(owned) {}
762
763 public:
764 // Ctor constructs the object from char literal; they are needed to make
765 // operator?: compile and they intentionally take char*, not const char*
766 wxCStrData(char *buf);
767 wxCStrData(wchar_t *buf);
768
769 ~wxCStrData();
770
771 // FIXME: we'll need convertors for both char* and wchar_t* and NONE
772 // for wxChar*, but that's after completing the transition to
773 // "smart" wxUniChar class. For now, just have conversion to
774 // char* in ANSI build and wchar_t in Unicode build.
775 #if wxUSE_UNICODE
776 const wchar_t* AsWChar() const;
777 operator const wchar_t*() const { return AsWChar(); }
778 #else
779 const char* AsChar() const;
780 operator const char*() const { return AsChar(); }
781 #endif
782
783 wxString AsString() const;
784 operator wxString() const;
785
786 // allow expressions like "c_str()[0]":
787 wxUniChar operator[](int n) const { return operator[](size_t(n)); }
788 wxUniChar operator[](size_t n) const;
789 wxUniChar operator[](long n) const { return operator[](size_t(n)); }
790 #ifndef wxSIZE_T_IS_UINT
791 wxUniChar operator[](unsigned int n) const { return operator[](size_t(n)); }
792 #endif // size_t != unsigned int
793
794 // these operators are needed to emulate the pointer semantics of c_str():
795 // expressions like "wxChar *p = str.c_str() + 1;" should continue to work
796 // (we need both versions to resolve ambiguities):
797 wxCStrData operator+(int n) const
798 { return wxCStrData(m_str, m_offset + n, m_owned); }
799 wxCStrData operator+(long n) const
800 { return wxCStrData(m_str, m_offset + n, m_owned); }
801 wxCStrData operator+(size_t n) const
802 { return wxCStrData(m_str, m_offset + n, m_owned); }
803
804 // this operator is need to make expressions like "*c_str()" or
805 // "*(c_str() + 2)" work
806 wxUniChar operator*() const;
807
808 private:
809 const wxString *m_str;
810 size_t m_offset;
811 bool m_owned;
812
813 friend class WXDLLIMPEXP_BASE wxString;
814 };
815
816 // ----------------------------------------------------------------------------
817 // wxStringPrintfMixin
818 // ---------------------------------------------------------------------------
819
820 // NB: VC6 has a bug that causes linker errors if you have template methods
821 // in a class using __declspec(dllimport). The solution is to split such
822 // class into two classes, one that contains the template methods and does
823 // *not* use WXDLLIMPEXP_BASE and another class that contains the rest
824 // (with DLL linkage).
825 //
826 // We only do this for VC6 here, because the code is less efficient
827 // (Printf() has to use dynamic_cast<>) and because OpenWatcom compiler
828 // cannot compile this code.
829
830 #if defined(__VISUALC__) && __VISUALC__ < 1300
831 #define wxNEEDS_WXSTRING_PRINTF_MIXIN
832 #endif
833
834 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
835 // this class contains implementation of wxString's vararg methods, it's
836 // exported from wxBase DLL
837 class WXDLLIMPEXP_BASE wxStringPrintfMixinBase
838 {
839 protected:
840 wxStringPrintfMixinBase() {}
841
842 int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
843 static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
844 };
845
846 // this class contains template wrappers for wxString's vararg methods, it's
847 // intentionally *not* exported from the DLL in order to fix the VC6 bug
848 // described above
849 class wxStringPrintfMixin : public wxStringPrintfMixinBase
850 {
851 private:
852 // to further complicate things, we can't return wxString from
853 // wxStringPrintfMixin::Format() because wxString is not yet declared at
854 // this point; the solution is to use this fake type trait template - this
855 // way the compiler won't know the return type until Format() is used
856 // (this doesn't compile with Watcom, but VC6 compiles it just fine):
857 template<typename T> struct StringReturnType
858 {
859 typedef wxString type;
860 };
861
862 public:
863 // these are duplicated wxString methods, they're also declared below
864 // if !wxNEEDS_WXSTRING_PRINTF_MIXIN:
865
866 // int Printf(const wxChar *pszFormat, ...);
867 WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
868 // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
869 WX_DEFINE_VARARG_FUNC(static typename StringReturnType<T1>::type,
870 Format, DoFormat)
871 // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
872 WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
873
874 protected:
875 wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
876 };
877 #endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
878
879
880 // ----------------------------------------------------------------------------
881 // wxString: string class trying to be compatible with std::string, MFC
882 // CString and wxWindows 1.x wxString all at once
883 // ---------------------------------------------------------------------------
884
885 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
886 // "non dll-interface class 'wxStringPrintfMixin' used as base interface
887 // for dll-interface class 'wxString'" -- this is OK in our case
888 #pragma warning (disable:4275)
889 #endif
890
891 class WXDLLIMPEXP_BASE wxString : public wxStringBase
892 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
893 ,public wxStringPrintfMixin
894 #endif
895 {
896 // NB: special care was taken in arranging the member functions in such order
897 // that all inline functions can be effectively inlined, verify that all
898 // performance critical functions are still inlined if you change order!
899 private:
900 // if we hadn't made these operators private, it would be possible to
901 // compile "wxString s; s = 17;" without any warnings as 17 is implicitly
902 // converted to char in C and we do have operator=(char)
903 //
904 // NB: we don't need other versions (short/long and unsigned) as attempt
905 // to assign another numeric type to wxString will now result in
906 // ambiguity between operator=(char) and operator=(int)
907 wxString& operator=(int);
908
909 // these methods are not implemented - there is _no_ conversion from int to
910 // string, you're doing something wrong if the compiler wants to call it!
911 //
912 // try `s << i' or `s.Printf("%d", i)' instead
913 wxString(int);
914
915 public:
916 // constructors and destructor
917 // ctor for an empty string
918 wxString() : wxStringBase() { }
919 // copy ctor
920 wxString(const wxStringBase& stringSrc) : wxStringBase(stringSrc) { }
921 wxString(const wxString& stringSrc) : wxStringBase(stringSrc) { }
922 // string containing nRepeat copies of ch
923 wxString(wxUniChar ch, size_t nRepeat = 1)
924 : wxStringBase(nRepeat, ch) { }
925 wxString(size_t nRepeat, wxUniChar ch)
926 : wxStringBase(nRepeat, ch) { }
927 wxString(wxUniCharRef ch, size_t nRepeat = 1)
928 : wxStringBase(nRepeat, ch) { }
929 wxString(size_t nRepeat, wxUniCharRef ch)
930 : wxStringBase(nRepeat, ch) { }
931 wxString(char ch, size_t nRepeat = 1)
932 : wxStringBase(nRepeat, ch) { }
933 wxString(size_t nRepeat, char ch)
934 : wxStringBase(nRepeat, ch) { }
935 wxString(wchar_t ch, size_t nRepeat = 1)
936 : wxStringBase(nRepeat, ch) { }
937 wxString(size_t nRepeat, wchar_t ch)
938 : wxStringBase(nRepeat, ch) { }
939 // ctor takes first nLength characters from C string
940 // (default value of npos means take all the string)
941 wxString(const wxChar *psz)
942 : wxStringBase(psz ? psz : wxT("")) { }
943 wxString(const wxChar *psz, size_t nLength)
944 : wxStringBase(psz, nLength) { }
945 wxString(const wxChar *psz,
946 const wxMBConv& WXUNUSED(conv),
947 size_t nLength = npos)
948 : wxStringBase(psz, nLength == npos ? wxStrlen(psz) : nLength) { }
949
950 // even if we're not built with wxUSE_STL == 1 it is very convenient to allow
951 // implicit conversions from std::string to wxString as this allows to use
952 // the same strings in non-GUI and GUI code, however we don't want to
953 // unconditionally add this ctor as it would make wx lib dependent on
954 // libstdc++ on some Linux versions which is bad, so instead we ask the
955 // client code to define this wxUSE_STD_STRING symbol if they need it
956 #if wxUSE_STD_STRING
957 wxString(const wxStdString& s)
958 : wxStringBase(s.c_str()) { }
959 #endif // wxUSE_STD_STRING
960
961 #if wxUSE_UNICODE
962 // from multibyte string
963 wxString(const char *psz,
964 const wxMBConv& conv = wxConvLibc,
965 size_t nLength = npos);
966 // from wxWCharBuffer (i.e. return from wxGetString)
967 wxString(const wxWCharBuffer& psz) : wxStringBase(psz.data()) { }
968 #else // ANSI
969 // from C string (for compilers using unsigned char)
970 wxString(const unsigned char* psz)
971 : wxStringBase((const char*)psz) { }
972 // from part of C string (for compilers using unsigned char)
973 wxString(const unsigned char* psz, size_t nLength)
974 : wxStringBase((const char*)psz, nLength) { }
975
976 #if wxUSE_WCHAR_T
977 // from wide (Unicode) string
978 wxString(const wchar_t *pwz,
979 const wxMBConv& conv = wxConvLibc,
980 size_t nLength = npos);
981 #endif // !wxUSE_WCHAR_T
982
983 // from wxCharBuffer
984 wxString(const wxCharBuffer& psz)
985 : wxStringBase(psz) { }
986 #endif // Unicode/ANSI
987
988 // generic attributes & operations
989 // as standard strlen()
990 size_t Len() const { return length(); }
991 // string contains any characters?
992 bool IsEmpty() const { return empty(); }
993 // empty string is "false", so !str will return true
994 bool operator!() const { return empty(); }
995 // truncate the string to given length
996 wxString& Truncate(size_t uiLen);
997 // empty string contents
998 void Empty()
999 {
1000 Truncate(0);
1001
1002 wxASSERT_MSG( empty(), _T("string not empty after call to Empty()?") );
1003 }
1004 // empty the string and free memory
1005 void Clear()
1006 {
1007 wxString tmp(wxEmptyString);
1008 swap(tmp);
1009 }
1010
1011 // contents test
1012 // Is an ascii value
1013 bool IsAscii() const;
1014 // Is a number
1015 bool IsNumber() const;
1016 // Is a word
1017 bool IsWord() const;
1018
1019 // data access (all indexes are 0 based)
1020 // read access
1021 wxUniChar GetChar(size_t n) const
1022 { return at(n); }
1023 // read/write access
1024 wxUniCharRef GetWritableChar(size_t n)
1025 { return at(n); }
1026 // write access
1027 void SetChar(size_t n, wxUniChar ch)
1028 { at(n) = ch; }
1029
1030 // get last character
1031 wxUniChar Last() const
1032 {
1033 wxASSERT_MSG( !empty(), _T("wxString: index out of bounds") );
1034
1035 return at(length() - 1);
1036 }
1037
1038 // get writable last character
1039 wxUniCharRef Last()
1040 {
1041 wxASSERT_MSG( !empty(), _T("wxString: index out of bounds") );
1042 return at(length() - 1);
1043 }
1044
1045 /*
1046 Note that we we must define all of the overloads below to avoid
1047 ambiguity when using str[0].
1048 */
1049 wxUniChar operator[](int n) const
1050 { return wxStringBase::at(n); }
1051 wxUniChar operator[](long n) const
1052 { return wxStringBase::at(n); }
1053 wxUniChar operator[](size_t n) const
1054 { return wxStringBase::at(n); }
1055 #ifndef wxSIZE_T_IS_UINT
1056 wxUniChar operator[](unsigned int n) const
1057 { return wxStringBase::at(n); }
1058 #endif // size_t != unsigned int
1059
1060 // operator versions of GetWriteableChar()
1061 wxUniCharRef operator[](int n)
1062 { return wxStringBase::at(n); }
1063 wxUniCharRef operator[](long n)
1064 { return wxStringBase::at(n); }
1065 wxUniCharRef operator[](size_t n)
1066 { return wxStringBase::at(n); }
1067 #ifndef wxSIZE_T_IS_UINT
1068 wxUniCharRef operator[](unsigned int n)
1069 { return wxStringBase::at(n); }
1070 #endif // size_t != unsigned int
1071
1072 // explicit conversion to C string (use this with printf()!)
1073 wxCStrData c_str() const { return wxCStrData(this); }
1074
1075 // implicit conversion to C string
1076 operator wxCStrData() const { return c_str(); }
1077 operator const wxChar*() const { return c_str(); }
1078
1079 // identical to c_str(), for MFC compatibility
1080 const wxCStrData GetData() const { return c_str(); }
1081
1082 // explicit conversion to C string in internal representation (char*,
1083 // wchar_t*, UTF-8-encoded char*, depending on the build):
1084 const_pointer wx_str() const { return data(); }
1085
1086 // conversion to/from plain (i.e. 7 bit) ASCII: this is useful for
1087 // converting numbers or strings which are certain not to contain special
1088 // chars (typically system functions, X atoms, environment variables etc.)
1089 //
1090 // the behaviour of these functions with the strings containing anything
1091 // else than 7 bit ASCII characters is undefined, use at your own risk.
1092 #if wxUSE_UNICODE
1093 static wxString FromAscii(const char *ascii); // string
1094 static wxString FromAscii(const char ascii); // char
1095 const wxCharBuffer ToAscii() const;
1096 #else // ANSI
1097 static wxString FromAscii(const char *ascii) { return wxString( ascii ); }
1098 static wxString FromAscii(const char ascii) { return wxString( ascii ); }
1099 const char *ToAscii() const { return c_str(); }
1100 #endif // Unicode/!Unicode
1101
1102 // conversions with (possible) format conversions: have to return a
1103 // buffer with temporary data
1104 //
1105 // the functions defined (in either Unicode or ANSI) mode are mb_str() to
1106 // return an ANSI (multibyte) string, wc_str() to return a wide string and
1107 // fn_str() to return a string which should be used with the OS APIs
1108 // accepting the file names. The return value is always the same, but the
1109 // type differs because a function may either return pointer to the buffer
1110 // directly or have to use intermediate buffer for translation.
1111 #if wxUSE_UNICODE
1112 const wxCharBuffer mb_str(const wxMBConv& conv = wxConvLibc) const;
1113
1114 const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
1115
1116 const wxChar* wc_str() const { return c_str(); }
1117
1118 // for compatibility with !wxUSE_UNICODE version
1119 const wxChar* wc_str(const wxMBConv& WXUNUSED(conv)) const { return c_str(); }
1120
1121 #if wxMBFILES
1122 const wxCharBuffer fn_str() const { return mb_str(wxConvFile); }
1123 #else // !wxMBFILES
1124 const wxChar* fn_str() const { return c_str(); }
1125 #endif // wxMBFILES/!wxMBFILES
1126 #else // ANSI
1127 const wxChar* mb_str() const { return c_str(); }
1128
1129 // for compatibility with wxUSE_UNICODE version
1130 const wxChar* mb_str(const wxMBConv& WXUNUSED(conv)) const { return c_str(); }
1131
1132 const wxWX2MBbuf mbc_str() const { return mb_str(); }
1133
1134 #if wxUSE_WCHAR_T
1135 const wxWCharBuffer wc_str(const wxMBConv& conv) const;
1136 #endif // wxUSE_WCHAR_T
1137 #ifdef __WXOSX__
1138 const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); }
1139 #else
1140 const wxChar* fn_str() const { return c_str(); }
1141 #endif
1142 #endif // Unicode/ANSI
1143
1144 // overloaded assignment
1145 // from another wxString
1146 wxString& operator=(const wxStringBase& stringSrc)
1147 { return (wxString&)wxStringBase::operator=(stringSrc); }
1148 wxString& operator=(const wxCStrData& cstr);
1149 // from a character
1150 wxString& operator=(wxUniChar ch)
1151 { return (wxString&)wxStringBase::operator=(ch); }
1152 wxString& operator=(wxUniCharRef ch)
1153 { return (wxString&)wxStringBase::operator=((wxUniChar)ch); }
1154 wxString& operator=(char ch)
1155 { return (wxString&)wxStringBase::operator=(wxUniChar(ch)); }
1156 wxString& operator=(wchar_t ch)
1157 { return (wxString&)wxStringBase::operator=(wxUniChar(ch)); }
1158 // from a C string - STL probably will crash on NULL,
1159 // so we need to compensate in that case
1160 #if wxUSE_STL
1161 wxString& operator=(const wxChar *psz)
1162 { if(psz) wxStringBase::operator=(psz); else Clear(); return *this; }
1163 #else
1164 wxString& operator=(const wxChar *psz)
1165 { return (wxString&)wxStringBase::operator=(psz); }
1166 #endif
1167
1168 #if wxUSE_UNICODE
1169 // from wxWCharBuffer
1170 wxString& operator=(const wxWCharBuffer& psz)
1171 { (void) operator=((const wchar_t *)psz); return *this; }
1172 // from C string
1173 wxString& operator=(const char* psz)
1174 { return operator=(wxString(psz)); }
1175 #else // ANSI
1176 // from another kind of C string
1177 wxString& operator=(const unsigned char* psz);
1178 #if wxUSE_WCHAR_T
1179 // from a wide string
1180 wxString& operator=(const wchar_t *pwz);
1181 #endif
1182 // from wxCharBuffer
1183 wxString& operator=(const wxCharBuffer& psz)
1184 { (void) operator=((const char *)psz); return *this; }
1185 #endif // Unicode/ANSI
1186
1187 // string concatenation
1188 // in place concatenation
1189 /*
1190 Concatenate and return the result. Note that the left to right
1191 associativity of << allows to write things like "str << str1 << str2
1192 << ..." (unlike with +=)
1193 */
1194 // string += string
1195 wxString& operator<<(const wxString& s)
1196 {
1197 #if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL
1198 wxASSERT_MSG( s.GetStringData()->IsValid(),
1199 _T("did you forget to call UngetWriteBuf()?") );
1200 #endif
1201
1202 append(s);
1203 return *this;
1204 }
1205 // string += C string
1206 wxString& operator<<(const wxChar *psz)
1207 { append(psz); return *this; }
1208 wxString& operator<<(const wxCStrData& psz)
1209 { append(psz); return *this; }
1210 // string += char
1211 wxString& operator<<(wxUniChar ch) { append(1, ch); return *this; }
1212 wxString& operator<<(wxUniCharRef ch) { append(1, ch); return *this; }
1213 wxString& operator<<(char ch) { append(1, ch); return *this; }
1214 wxString& operator<<(wchar_t ch) { append(1, ch); return *this; }
1215
1216 // string += buffer (i.e. from wxGetString)
1217 #if wxUSE_UNICODE
1218 wxString& operator<<(const wxWCharBuffer& s)
1219 { return operator<<((const wchar_t *)s); }
1220 wxString& operator+=(const wxWCharBuffer& s)
1221 { return operator<<((const wchar_t *)s); }
1222 #else // !wxUSE_UNICODE
1223 wxString& operator<<(const wxCharBuffer& s)
1224 { return operator<<((const char *)s); }
1225 wxString& operator+=(const wxCharBuffer& s)
1226 { return operator<<((const char *)s); }
1227 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
1228
1229 #if wxUSE_UNICODE
1230 // string += C string in Unicode build (with conversion)
1231 wxString& operator<<(const char *s)
1232 { return operator<<(wxString(s)); }
1233 wxString& operator+=(const char *s)
1234 { return operator+=(wxString(s)); }
1235 #endif // wxUSE_UNICODE
1236
1237 // string += C string
1238 wxString& Append(const wxString& s)
1239 {
1240 // test for empty() to share the string if possible
1241 if ( empty() )
1242 *this = s;
1243 else
1244 append(s);
1245 return *this;
1246 }
1247 wxString& Append(const wxCStrData& psz)
1248 { append(psz); return *this; }
1249 wxString& Append(const wxChar* psz)
1250 { append(psz); return *this; }
1251 // append count copies of given character
1252 wxString& Append(wxUniChar ch, size_t count = 1u)
1253 { append(count, ch); return *this; }
1254 wxString& Append(wxUniCharRef ch, size_t count = 1u)
1255 { append(count, ch); return *this; }
1256 wxString& Append(char ch, size_t count = 1u)
1257 { append(count, ch); return *this; }
1258 wxString& Append(wchar_t ch, size_t count = 1u)
1259 { append(count, ch); return *this; }
1260 wxString& Append(const wxChar* psz, size_t nLen)
1261 { append(psz, nLen); return *this; }
1262
1263 // prepend a string, return the string itself
1264 wxString& Prepend(const wxString& str)
1265 { *this = str + *this; return *this; }
1266
1267 // non-destructive concatenation
1268 // two strings
1269 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string1,
1270 const wxString& string2);
1271 // string with a single char
1272 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxUniChar ch);
1273 // char with a string
1274 friend wxString WXDLLIMPEXP_BASE operator+(wxUniChar ch, const wxString& string);
1275 // string with C string
1276 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string,
1277 const wxChar *psz);
1278 // C string with string
1279 friend wxString WXDLLIMPEXP_BASE operator+(const wxChar *psz,
1280 const wxString& string);
1281
1282 // stream-like functions
1283 // insert an int into string
1284 wxString& operator<<(int i)
1285 { return (*this) << Format(_T("%d"), i); }
1286 // insert an unsigned int into string
1287 wxString& operator<<(unsigned int ui)
1288 { return (*this) << Format(_T("%u"), ui); }
1289 // insert a long into string
1290 wxString& operator<<(long l)
1291 { return (*this) << Format(_T("%ld"), l); }
1292 // insert an unsigned long into string
1293 wxString& operator<<(unsigned long ul)
1294 { return (*this) << Format(_T("%lu"), ul); }
1295 #if defined wxLongLong_t && !defined wxLongLongIsLong
1296 // insert a long long if they exist and aren't longs
1297 wxString& operator<<(wxLongLong_t ll)
1298 {
1299 const wxChar *fmt = _T("%") wxLongLongFmtSpec _T("d");
1300 return (*this) << Format(fmt, ll);
1301 }
1302 // insert an unsigned long long
1303 wxString& operator<<(wxULongLong_t ull)
1304 {
1305 const wxChar *fmt = _T("%") wxLongLongFmtSpec _T("u");
1306 return (*this) << Format(fmt , ull);
1307 }
1308 #endif
1309 // insert a float into string
1310 wxString& operator<<(float f)
1311 { return (*this) << Format(_T("%f"), f); }
1312 // insert a double into string
1313 wxString& operator<<(double d)
1314 { return (*this) << Format(_T("%g"), d); }
1315
1316 // string comparison
1317 // case-sensitive comparison (returns a value < 0, = 0 or > 0)
1318 int Cmp(const wxChar *psz) const;
1319 int Cmp(const wxString& s) const;
1320 // same as Cmp() but not case-sensitive
1321 int CmpNoCase(const wxChar *psz) const;
1322 int CmpNoCase(const wxString& s) const;
1323 // test for the string equality, either considering case or not
1324 // (if compareWithCase then the case matters)
1325 bool IsSameAs(const wxChar *psz, bool compareWithCase = true) const
1326 { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
1327 // comparison with a single character: returns true if equal
1328 bool IsSameAs(wxUniChar c, bool compareWithCase = true) const
1329 {
1330 return (length() == 1) && (compareWithCase ? GetChar(0u) == c
1331 : wxToupper(GetChar(0u)) == wxToupper(c));
1332 }
1333
1334 // simple sub-string extraction
1335 // return substring starting at nFirst of length nCount (or till the end
1336 // if nCount = default value)
1337 wxString Mid(size_t nFirst, size_t nCount = npos) const;
1338
1339 // operator version of Mid()
1340 wxString operator()(size_t start, size_t len) const
1341 { return Mid(start, len); }
1342
1343 // check if the string starts with the given prefix and return the rest
1344 // of the string in the provided pointer if it is not NULL; otherwise
1345 // return false
1346 bool StartsWith(const wxChar *prefix, wxString *rest = NULL) const;
1347 // check if the string ends with the given suffix and return the
1348 // beginning of the string before the suffix in the provided pointer if
1349 // it is not NULL; otherwise return false
1350 bool EndsWith(const wxChar *suffix, wxString *rest = NULL) const;
1351
1352 // get first nCount characters
1353 wxString Left(size_t nCount) const;
1354 // get last nCount characters
1355 wxString Right(size_t nCount) const;
1356 // get all characters before the first occurance of ch
1357 // (returns the whole string if ch not found)
1358 wxString BeforeFirst(wxUniChar ch) const;
1359 // get all characters before the last occurence of ch
1360 // (returns empty string if ch not found)
1361 wxString BeforeLast(wxUniChar ch) const;
1362 // get all characters after the first occurence of ch
1363 // (returns empty string if ch not found)
1364 wxString AfterFirst(wxUniChar ch) const;
1365 // get all characters after the last occurence of ch
1366 // (returns the whole string if ch not found)
1367 wxString AfterLast(wxUniChar ch) const;
1368
1369 // for compatibility only, use more explicitly named functions above
1370 wxString Before(wxUniChar ch) const { return BeforeLast(ch); }
1371 wxString After(wxUniChar ch) const { return AfterFirst(ch); }
1372
1373 // case conversion
1374 // convert to upper case in place, return the string itself
1375 wxString& MakeUpper();
1376 // convert to upper case, return the copy of the string
1377 // Here's something to remember: BC++ doesn't like returns in inlines.
1378 wxString Upper() const ;
1379 // convert to lower case in place, return the string itself
1380 wxString& MakeLower();
1381 // convert to lower case, return the copy of the string
1382 wxString Lower() const ;
1383
1384 // trimming/padding whitespace (either side) and truncating
1385 // remove spaces from left or from right (default) side
1386 wxString& Trim(bool bFromRight = true);
1387 // add nCount copies chPad in the beginning or at the end (default)
1388 wxString& Pad(size_t nCount, wxUniChar chPad = wxT(' '), bool bFromRight = true);
1389
1390 // searching and replacing
1391 // searching (return starting index, or -1 if not found)
1392 int Find(wxUniChar ch, bool bFromEnd = false) const; // like strchr/strrchr
1393 // searching (return starting index, or -1 if not found)
1394 int Find(const wxChar *pszSub) const; // like strstr
1395 // replace first (or all of bReplaceAll) occurences of substring with
1396 // another string, returns the number of replacements made
1397 size_t Replace(const wxChar *szOld,
1398 const wxChar *szNew,
1399 bool bReplaceAll = true);
1400
1401 // check if the string contents matches a mask containing '*' and '?'
1402 bool Matches(const wxChar *szMask) const;
1403
1404 // conversion to numbers: all functions return true only if the whole
1405 // string is a number and put the value of this number into the pointer
1406 // provided, the base is the numeric base in which the conversion should be
1407 // done and must be comprised between 2 and 36 or be 0 in which case the
1408 // standard C rules apply (leading '0' => octal, "0x" => hex)
1409 // convert to a signed integer
1410 bool ToLong(long *val, int base = 10) const;
1411 // convert to an unsigned integer
1412 bool ToULong(unsigned long *val, int base = 10) const;
1413 // convert to wxLongLong
1414 #if defined(wxLongLong_t)
1415 bool ToLongLong(wxLongLong_t *val, int base = 10) const;
1416 // convert to wxULongLong
1417 bool ToULongLong(wxULongLong_t *val, int base = 10) const;
1418 #endif // wxLongLong_t
1419 // convert to a double
1420 bool ToDouble(double *val) const;
1421
1422
1423 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
1424 // formatted input/output
1425 // as sprintf(), returns the number of characters written or < 0 on error
1426 // (take 'this' into account in attribute parameter count)
1427 // int Printf(const wxChar *pszFormat, ...);
1428 WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
1429 #endif // !wxNEEDS_WXSTRING_PRINTF_MIXIN
1430 // as vprintf(), returns the number of characters written or < 0 on error
1431 int PrintfV(const wxString& format, va_list argptr);
1432
1433 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
1434 // returns the string containing the result of Printf() to it
1435 // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
1436 WX_DEFINE_VARARG_FUNC(static wxString, Format, DoFormat)
1437 #endif
1438 // the same as above, but takes a va_list
1439 static wxString FormatV(const wxString& format, va_list argptr);
1440
1441 // raw access to string memory
1442 // ensure that string has space for at least nLen characters
1443 // only works if the data of this string is not shared
1444 bool Alloc(size_t nLen) { reserve(nLen); /*return capacity() >= nLen;*/ return true; }
1445 // minimize the string's memory
1446 // only works if the data of this string is not shared
1447 bool Shrink();
1448 #if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL
1449 // These are deprecated, use wxStringBuffer or wxStringBufferLength instead
1450 //
1451 // get writable buffer of at least nLen bytes. Unget() *must* be called
1452 // a.s.a.p. to put string back in a reasonable state!
1453 wxDEPRECATED( wxChar *GetWriteBuf(size_t nLen) );
1454 // call this immediately after GetWriteBuf() has been used
1455 wxDEPRECATED( void UngetWriteBuf() );
1456 wxDEPRECATED( void UngetWriteBuf(size_t nLen) );
1457 #endif // WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL
1458
1459 // wxWidgets version 1 compatibility functions
1460
1461 // use Mid()
1462 wxString SubString(size_t from, size_t to) const
1463 { return Mid(from, (to - from + 1)); }
1464 // values for second parameter of CompareTo function
1465 enum caseCompare {exact, ignoreCase};
1466 // values for first parameter of Strip function
1467 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
1468
1469 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
1470 // use Printf()
1471 // (take 'this' into account in attribute parameter count)
1472 // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
1473 WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
1474 #endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
1475
1476 // use Cmp()
1477 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
1478 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
1479
1480 // use Len
1481 size_t Length() const { return length(); }
1482 // Count the number of characters
1483 int Freq(wxUniChar ch) const;
1484 // use MakeLower
1485 void LowerCase() { MakeLower(); }
1486 // use MakeUpper
1487 void UpperCase() { MakeUpper(); }
1488 // use Trim except that it doesn't change this string
1489 wxString Strip(stripType w = trailing) const;
1490
1491 // use Find (more general variants not yet supported)
1492 size_t Index(const wxChar* psz) const { return Find(psz); }
1493 size_t Index(wxUniChar ch) const { return Find(ch); }
1494 // use Truncate
1495 wxString& Remove(size_t pos) { return Truncate(pos); }
1496 wxString& RemoveLast(size_t n = 1) { return Truncate(length() - n); }
1497
1498 wxString& Remove(size_t nStart, size_t nLen)
1499 { return (wxString&)erase( nStart, nLen ); }
1500
1501 // use Find()
1502 int First( const wxUniChar ch ) const { return Find(ch); }
1503 int First( char ch ) const { return Find(ch); }
1504 int First( wchar_t ch ) const { return Find(ch); }
1505 int First( const wxChar* psz ) const { return Find(psz); }
1506 int First( const wxString &str ) const { return Find(str); }
1507 int Last( const wxUniChar ch ) const { return Find(ch, true); }
1508 bool Contains(const wxString& str) const { return Find(str) != wxNOT_FOUND; }
1509
1510 // use empty()
1511 bool IsNull() const { return empty(); }
1512
1513 // std::string compatibility functions
1514
1515 // take nLen chars starting at nPos
1516 wxString(const wxString& str, size_t nPos, size_t nLen)
1517 : wxStringBase(str, nPos, nLen) { }
1518 // take all characters from pStart to pEnd
1519 wxString(const void *pStart, const void *pEnd)
1520 : wxStringBase((const wxChar*)pStart, (const wxChar*)pEnd) { }
1521 wxString(const_iterator first, const_iterator last)
1522 : wxStringBase(first, last) { }
1523 wxString(iterator first, iterator last)
1524 : wxStringBase(first, last) { }
1525
1526 // lib.string.modifiers
1527 // append elements str[pos], ..., str[pos+n]
1528 wxString& append(const wxString& str, size_t pos, size_t n)
1529 { return (wxString&)wxStringBase::append(str, pos, n); }
1530 // append a string
1531 wxString& append(const wxString& str)
1532 { return (wxString&)wxStringBase::append(str); }
1533 wxString& append(const wxCStrData& str)
1534 { return (wxString&)wxStringBase::append(str.AsString()); }
1535 // append first n (or all if n == npos) characters of sz
1536 wxString& append(const wxChar *sz)
1537 { return (wxString&)wxStringBase::append(sz); }
1538 wxString& append(const wxChar *sz, size_t n)
1539 { return (wxString&)wxStringBase::append(sz, n); }
1540 // append n copies of ch
1541 wxString& append(size_t n, wxUniChar ch)
1542 { return (wxString&)wxStringBase::append(n, ch); }
1543 // append from first to last
1544 wxString& append(const_iterator first, const_iterator last)
1545 { return (wxString&)wxStringBase::append(first, last); }
1546
1547 // same as `this_string = str'
1548 wxString& assign(const wxString& str)
1549 { return (wxString&)wxStringBase::assign(str); }
1550 // same as ` = str[pos..pos + n]
1551 wxString& assign(const wxString& str, size_t pos, size_t n)
1552 { return (wxString&)wxStringBase::assign(str, pos, n); }
1553 // same as `= first n (or all if n == npos) characters of sz'
1554 wxString& assign(const wxChar *sz)
1555 { return (wxString&)wxStringBase::assign(sz); }
1556 wxString& assign(const wxChar *sz, size_t n)
1557 { return (wxString&)wxStringBase::assign(sz, n); }
1558 // same as `= n copies of ch'
1559 wxString& assign(size_t n, wxUniChar ch)
1560 { return (wxString&)wxStringBase::assign(n, ch); }
1561 // assign from first to last
1562 wxString& assign(const_iterator first, const_iterator last)
1563 { return (wxString&)wxStringBase::assign(first, last); }
1564
1565 // string comparison
1566 #if !defined(HAVE_STD_STRING_COMPARE)
1567 int compare(const wxStringBase& str) const;
1568 // comparison with a substring
1569 int compare(size_t nStart, size_t nLen, const wxStringBase& str) const;
1570 // comparison of 2 substrings
1571 int compare(size_t nStart, size_t nLen,
1572 const wxStringBase& str, size_t nStart2, size_t nLen2) const;
1573 // just like strcmp()
1574 int compare(const wxChar* sz) const;
1575 // substring comparison with first nCount characters of sz
1576 int compare(size_t nStart, size_t nLen,
1577 const wxChar* sz, size_t nCount = npos) const;
1578 #endif // !defined HAVE_STD_STRING_COMPARE
1579
1580 // insert another string
1581 wxString& insert(size_t nPos, const wxString& str)
1582 { return (wxString&)wxStringBase::insert(nPos, str); }
1583 // insert n chars of str starting at nStart (in str)
1584 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
1585 { return (wxString&)wxStringBase::insert(nPos, str, nStart, n); }
1586 // insert first n (or all if n == npos) characters of sz
1587 wxString& insert(size_t nPos, const wxChar *sz)
1588 { return (wxString&)wxStringBase::insert(nPos, sz); }
1589 wxString& insert(size_t nPos, const wxChar *sz, size_t n)
1590 { return (wxString&)wxStringBase::insert(nPos, sz, n); }
1591 // insert n copies of ch
1592 wxString& insert(size_t nPos, size_t n, wxUniChar ch)
1593 { return (wxString&)wxStringBase::insert(nPos, n, ch); }
1594 iterator insert(iterator it, wxUniChar ch)
1595 { return wxStringBase::insert(it, ch); }
1596 void insert(iterator it, const_iterator first, const_iterator last)
1597 { wxStringBase::insert(it, first, last); }
1598 void insert(iterator it, size_type n, wxUniChar ch)
1599 { wxStringBase::insert(it, n, ch); }
1600
1601 // delete characters from nStart to nStart + nLen
1602 wxString& erase(size_type pos = 0, size_type n = npos)
1603 { return (wxString&)wxStringBase::erase(pos, n); }
1604 iterator erase(iterator first, iterator last)
1605 { return wxStringBase::erase(first, last); }
1606 iterator erase(iterator first)
1607 { return wxStringBase::erase(first); }
1608
1609 #ifdef wxSTRING_BASE_HASNT_CLEAR
1610 void clear() { erase(); }
1611 #endif
1612
1613 // replaces the substring of length nLen starting at nStart
1614 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz)
1615 { return (wxString&)wxStringBase::replace(nStart, nLen, sz); }
1616 // replaces the substring of length nLen starting at nStart
1617 wxString& replace(size_t nStart, size_t nLen, const wxString& str)
1618 { return (wxString&)wxStringBase::replace(nStart, nLen, str); }
1619 // replaces the substring with nCount copies of ch
1620 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxUniChar ch)
1621 { return (wxString&)wxStringBase::replace(nStart, nLen, nCount, ch); }
1622 // replaces a substring with another substring
1623 wxString& replace(size_t nStart, size_t nLen,
1624 const wxString& str, size_t nStart2, size_t nLen2)
1625 { return (wxString&)wxStringBase::replace(nStart, nLen, str,
1626 nStart2, nLen2); }
1627 // replaces the substring with first nCount chars of sz
1628 wxString& replace(size_t nStart, size_t nLen,
1629 const wxChar* sz, size_t nCount)
1630 { return (wxString&)wxStringBase::replace(nStart, nLen, sz, nCount); }
1631 wxString& replace(iterator first, iterator last, const_pointer s)
1632 { return (wxString&)wxStringBase::replace(first, last, s); }
1633 wxString& replace(iterator first, iterator last, const_pointer s,
1634 size_type n)
1635 { return (wxString&)wxStringBase::replace(first, last, s, n); }
1636 wxString& replace(iterator first, iterator last, const wxString& s)
1637 { return (wxString&)wxStringBase::replace(first, last, s); }
1638 wxString& replace(iterator first, iterator last, size_type n, wxUniChar c)
1639 { return (wxString&)wxStringBase::replace(first, last, n, c); }
1640 wxString& replace(iterator first, iterator last,
1641 const_iterator first1, const_iterator last1)
1642 { return (wxString&)wxStringBase::replace(first, last, first1, last1); }
1643
1644 // string += string
1645 wxString& operator+=(const wxString& s)
1646 { return (wxString&)wxStringBase::operator+=(s); }
1647 // string += C string
1648 wxString& operator+=(const wxChar *psz)
1649 { return (wxString&)wxStringBase::operator+=(psz); }
1650 wxString& operator+=(const wxCStrData& s)
1651 { return (wxString&)wxStringBase::operator+=(s.AsString()); }
1652 // string += char
1653 wxString& operator+=(wxUniChar ch)
1654 { return (wxString&)wxStringBase::operator+=(ch); }
1655 wxString& operator+=(wxUniCharRef ch) { return *this += wxUniChar(ch); }
1656 wxString& operator+=(char ch) { return *this += wxUniChar(ch); }
1657 wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); }
1658
1659 private:
1660 #if !wxUSE_STL
1661 // helpers for wxStringBuffer and wxStringBufferLength
1662 wxChar *DoGetWriteBuf(size_t nLen);
1663 void DoUngetWriteBuf();
1664 void DoUngetWriteBuf(size_t nLen);
1665
1666 friend class WXDLLIMPEXP_BASE wxStringBuffer;
1667 friend class WXDLLIMPEXP_BASE wxStringBufferLength;
1668 #endif
1669
1670 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
1671 int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
1672 static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
1673 #endif
1674 };
1675
1676 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
1677 #pragma warning (default:4275)
1678 #endif
1679
1680 // notice that even though for many compilers the friend declarations above are
1681 // enough, from the point of view of C++ standard we must have the declarations
1682 // here as friend ones are not injected in the enclosing namespace and without
1683 // them the code fails to compile with conforming compilers such as xlC or g++4
1684 wxString WXDLLIMPEXP_BASE operator+(const wxString& string1, const wxString& string2);
1685 wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const wxChar *psz);
1686 wxString WXDLLIMPEXP_BASE operator+(const wxChar *psz, const wxString& string);
1687
1688 wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxUniChar ch);
1689 wxString WXDLLIMPEXP_BASE operator+(wxUniChar ch, const wxString& string);
1690
1691 inline wxString operator+(const wxString& string, wxUniCharRef ch)
1692 { return string + (wxUniChar)ch; }
1693 inline wxString operator+(const wxString& string, char ch)
1694 { return string + wxUniChar(ch); }
1695 inline wxString operator+(const wxString& string, wchar_t ch)
1696 { return string + wxUniChar(ch); }
1697 inline wxString operator+(wxUniCharRef ch, const wxString& string)
1698 { return (wxUniChar)ch + string; }
1699 inline wxString operator+(char ch, const wxString& string)
1700 { return wxUniChar(ch) + string; }
1701 inline wxString operator+(wchar_t ch, const wxString& string)
1702 { return wxUniChar(ch) + string; }
1703
1704
1705 #if wxUSE_STL
1706 // return an empty wxString (not very useful with wxUSE_STL == 1)
1707 inline const wxString wxGetEmptyString() { return wxString(); }
1708 #else // !wxUSE_STL
1709 // return an empty wxString (more efficient than wxString() here)
1710 inline const wxString& wxGetEmptyString()
1711 {
1712 return *(wxString *)&wxEmptyString;
1713 }
1714 #endif // wxUSE_STL/!wxUSE_STL
1715
1716 // ----------------------------------------------------------------------------
1717 // wxStringBuffer: a tiny class allowing to get a writable pointer into string
1718 // ----------------------------------------------------------------------------
1719
1720 #if wxUSE_STL
1721
1722 class WXDLLIMPEXP_BASE wxStringBuffer
1723 {
1724 public:
1725 wxStringBuffer(wxString& str, size_t lenWanted = 1024)
1726 : m_str(str), m_buf(lenWanted)
1727 { }
1728
1729 ~wxStringBuffer() { m_str.assign(m_buf.data(), wxStrlen(m_buf.data())); }
1730
1731 operator wxChar*() { return m_buf.data(); }
1732
1733 private:
1734 wxString& m_str;
1735 #if wxUSE_UNICODE
1736 wxWCharBuffer m_buf;
1737 #else
1738 wxCharBuffer m_buf;
1739 #endif
1740
1741 DECLARE_NO_COPY_CLASS(wxStringBuffer)
1742 };
1743
1744 class WXDLLIMPEXP_BASE wxStringBufferLength
1745 {
1746 public:
1747 wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
1748 : m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
1749 { }
1750
1751 ~wxStringBufferLength()
1752 {
1753 wxASSERT(m_lenSet);
1754 m_str.assign(m_buf.data(), m_len);
1755 }
1756
1757 operator wxChar*() { return m_buf.data(); }
1758 void SetLength(size_t length) { m_len = length; m_lenSet = true; }
1759
1760 private:
1761 wxString& m_str;
1762 #if wxUSE_UNICODE
1763 wxWCharBuffer m_buf;
1764 #else
1765 wxCharBuffer m_buf;
1766 #endif
1767 size_t m_len;
1768 bool m_lenSet;
1769
1770 DECLARE_NO_COPY_CLASS(wxStringBufferLength)
1771 };
1772
1773 #else // if !wxUSE_STL
1774
1775 class WXDLLIMPEXP_BASE wxStringBuffer
1776 {
1777 public:
1778 wxStringBuffer(wxString& str, size_t lenWanted = 1024)
1779 : m_str(str), m_buf(NULL)
1780 { m_buf = m_str.DoGetWriteBuf(lenWanted); }
1781
1782 ~wxStringBuffer() { m_str.DoUngetWriteBuf(); }
1783
1784 operator wxChar*() const { return m_buf; }
1785
1786 private:
1787 wxString& m_str;
1788 wxChar *m_buf;
1789
1790 DECLARE_NO_COPY_CLASS(wxStringBuffer)
1791 };
1792
1793 class WXDLLIMPEXP_BASE wxStringBufferLength
1794 {
1795 public:
1796 wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
1797 : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
1798 {
1799 m_buf = m_str.DoGetWriteBuf(lenWanted);
1800 wxASSERT(m_buf != NULL);
1801 }
1802
1803 ~wxStringBufferLength()
1804 {
1805 wxASSERT(m_lenSet);
1806 m_str.DoUngetWriteBuf(m_len);
1807 }
1808
1809 operator wxChar*() const { return m_buf; }
1810 void SetLength(size_t length) { m_len = length; m_lenSet = true; }
1811
1812 private:
1813 wxString& m_str;
1814 wxChar *m_buf;
1815 size_t m_len;
1816 bool m_lenSet;
1817
1818 DECLARE_NO_COPY_CLASS(wxStringBufferLength)
1819 };
1820
1821 #endif // !wxUSE_STL
1822
1823 // ---------------------------------------------------------------------------
1824 // wxString comparison functions: operator versions are always case sensitive
1825 // ---------------------------------------------------------------------------
1826
1827 // note that when wxUSE_STL == 1 the comparison operators taking std::string
1828 // are used and defining them also for wxString would only result in
1829 // compilation ambiguities when comparing std::string and wxString
1830 #if !wxUSE_STL
1831
1832 inline bool operator==(const wxString& s1, const wxString& s2)
1833 { return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); }
1834 inline bool operator==(const wxString& s1, const wxChar * s2)
1835 { return s1.Cmp(s2) == 0; }
1836 inline bool operator==(const wxChar * s1, const wxString& s2)
1837 { return s2.Cmp(s1) == 0; }
1838 inline bool operator!=(const wxString& s1, const wxString& s2)
1839 { return (s1.Len() != s2.Len()) || (s1.Cmp(s2) != 0); }
1840 inline bool operator!=(const wxString& s1, const wxChar * s2)
1841 { return s1.Cmp(s2) != 0; }
1842 inline bool operator!=(const wxChar * s1, const wxString& s2)
1843 { return s2.Cmp(s1) != 0; }
1844 inline bool operator< (const wxString& s1, const wxString& s2)
1845 { return s1.Cmp(s2) < 0; }
1846 inline bool operator< (const wxString& s1, const wxChar * s2)
1847 { return s1.Cmp(s2) < 0; }
1848 inline bool operator< (const wxChar * s1, const wxString& s2)
1849 { return s2.Cmp(s1) > 0; }
1850 inline bool operator> (const wxString& s1, const wxString& s2)
1851 { return s1.Cmp(s2) > 0; }
1852 inline bool operator> (const wxString& s1, const wxChar * s2)
1853 { return s1.Cmp(s2) > 0; }
1854 inline bool operator> (const wxChar * s1, const wxString& s2)
1855 { return s2.Cmp(s1) < 0; }
1856 inline bool operator<=(const wxString& s1, const wxString& s2)
1857 { return s1.Cmp(s2) <= 0; }
1858 inline bool operator<=(const wxString& s1, const wxChar * s2)
1859 { return s1.Cmp(s2) <= 0; }
1860 inline bool operator<=(const wxChar * s1, const wxString& s2)
1861 { return s2.Cmp(s1) >= 0; }
1862 inline bool operator>=(const wxString& s1, const wxString& s2)
1863 { return s1.Cmp(s2) >= 0; }
1864 inline bool operator>=(const wxString& s1, const wxChar * s2)
1865 { return s1.Cmp(s2) >= 0; }
1866 inline bool operator>=(const wxChar * s1, const wxString& s2)
1867 { return s2.Cmp(s1) <= 0; }
1868
1869 #if wxUSE_UNICODE
1870 inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
1871 { return (s1.Cmp((const wchar_t *)s2) == 0); }
1872 inline bool operator==(const wxWCharBuffer& s1, const wxString& s2)
1873 { return (s2.Cmp((const wchar_t *)s1) == 0); }
1874 inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2)
1875 { return (s1.Cmp((const wchar_t *)s2) != 0); }
1876 inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2)
1877 { return (s2.Cmp((const wchar_t *)s1) != 0); }
1878 #else // !wxUSE_UNICODE
1879 inline bool operator==(const wxString& s1, const wxCharBuffer& s2)
1880 { return (s1.Cmp((const char *)s2) == 0); }
1881 inline bool operator==(const wxCharBuffer& s1, const wxString& s2)
1882 { return (s2.Cmp((const char *)s1) == 0); }
1883 inline bool operator!=(const wxString& s1, const wxCharBuffer& s2)
1884 { return (s1.Cmp((const char *)s2) != 0); }
1885 inline bool operator!=(const wxCharBuffer& s1, const wxString& s2)
1886 { return (s2.Cmp((const char *)s1) != 0); }
1887 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
1888
1889 #if wxUSE_UNICODE
1890 inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
1891 { return string + (const wchar_t *)buf; }
1892 inline wxString operator+(const wxWCharBuffer& buf, const wxString& string)
1893 { return (const wchar_t *)buf + string; }
1894 #else // !wxUSE_UNICODE
1895 inline wxString operator+(const wxString& string, const wxCharBuffer& buf)
1896 { return string + (const char *)buf; }
1897 inline wxString operator+(const wxCharBuffer& buf, const wxString& string)
1898 { return (const char *)buf + string; }
1899 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
1900
1901 #endif // !wxUSE_STL
1902
1903 // comparison with char (those are not defined by std::[w]string and so should
1904 // be always available)
1905 inline bool operator==(const wxUniChar& c, const wxString& s) { return s.IsSameAs(c); }
1906 inline bool operator==(const wxUniCharRef& c, const wxString& s) { return s.IsSameAs(c); }
1907 inline bool operator==(char c, const wxString& s) { return s.IsSameAs(c); }
1908 inline bool operator==(wchar_t c, const wxString& s) { return s.IsSameAs(c); }
1909 inline bool operator==(int c, const wxString& s) { return s.IsSameAs(c); }
1910 inline bool operator==(const wxString& s, const wxUniChar& c) { return s.IsSameAs(c); }
1911 inline bool operator==(const wxString& s, const wxUniCharRef& c) { return s.IsSameAs(c); }
1912 inline bool operator==(const wxString& s, char c) { return s.IsSameAs(c); }
1913 inline bool operator==(const wxString& s, wchar_t c) { return s.IsSameAs(c); }
1914 inline bool operator!=(const wxUniChar& c, const wxString& s) { return !s.IsSameAs(c); }
1915 inline bool operator!=(const wxUniCharRef& c, const wxString& s) { return !s.IsSameAs(c); }
1916 inline bool operator!=(char c, const wxString& s) { return !s.IsSameAs(c); }
1917 inline bool operator!=(wchar_t c, const wxString& s) { return !s.IsSameAs(c); }
1918 inline bool operator!=(int c, const wxString& s) { return !s.IsSameAs(c); }
1919 inline bool operator!=(const wxString& s, const wxUniChar& c) { return !s.IsSameAs(c); }
1920 inline bool operator!=(const wxString& s, const wxUniCharRef& c) { return !s.IsSameAs(c); }
1921 inline bool operator!=(const wxString& s, char c) { return !s.IsSameAs(c); }
1922 inline bool operator!=(const wxString& s, wchar_t c) { return !s.IsSameAs(c); }
1923
1924 // comparison with C string in Unicode build
1925 #if wxUSE_UNICODE
1926 inline bool operator==(const wxString& s1, const char* s2)
1927 { return s1 == wxString(s2); }
1928 inline bool operator==(const char* s1, const wxString& s2)
1929 { return wxString(s1) == s2; }
1930 inline bool operator!=(const wxString& s1, const char* s2)
1931 { return s1 != wxString(s2); }
1932 inline bool operator!=(const char* s1, const wxString& s2)
1933 { return wxString(s1) != s2; }
1934 inline bool operator< (const wxString& s1, const char* s2)
1935 { return s1 < wxString(s2); }
1936 inline bool operator< (const char* s1, const wxString& s2)
1937 { return wxString(s1) < s2; }
1938 inline bool operator> (const wxString& s1, const char* s2)
1939 { return s1 > wxString(s2); }
1940 inline bool operator> (const char* s1, const wxString& s2)
1941 { return wxString(s1) > s2; }
1942 inline bool operator<=(const wxString& s1, const char* s2)
1943 { return s1 <= wxString(s2); }
1944 inline bool operator<=(const char* s1, const wxString& s2)
1945 { return wxString(s1) <= s2; }
1946 inline bool operator>=(const wxString& s1, const char* s2)
1947 { return s1 >= wxString(s2); }
1948 inline bool operator>=(const char* s1, const wxString& s2)
1949 { return wxString(s1) >= s2; }
1950 #endif // wxUSE_UNICODE
1951
1952 // ---------------------------------------------------------------------------
1953 // Implementation only from here until the end of file
1954 // ---------------------------------------------------------------------------
1955
1956 // don't pollute the library user's name space
1957 #undef wxASSERT_VALID_INDEX
1958
1959 #if wxUSE_STD_IOSTREAM
1960
1961 #include "wx/iosfwrap.h"
1962
1963 WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxString&);
1964 WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxCStrData&);
1965
1966 #endif // wxSTD_STRING_COMPATIBILITY
1967
1968 // ---------------------------------------------------------------------------
1969 // wxCStrData implementation
1970 // ---------------------------------------------------------------------------
1971
1972 inline wxCStrData::wxCStrData(char *buf)
1973 : m_str(new wxString(buf)), m_offset(0), m_owned(true) {}
1974 inline wxCStrData::wxCStrData(wchar_t *buf)
1975 : m_str(new wxString(buf)), m_offset(0), m_owned(true) {}
1976
1977 inline wxCStrData::~wxCStrData()
1978 {
1979 if ( m_owned )
1980 delete m_str;
1981 }
1982
1983 #if wxUSE_UNICODE
1984 inline const wchar_t* wxCStrData::AsWChar() const
1985 #else
1986 inline const char* wxCStrData::AsChar() const
1987 #endif
1988 {
1989 if ( m_offset == 0 )
1990 return m_str->wx_str(); // FIXME
1991 else
1992 return (const wxChar*)(m_str->begin() + m_offset);
1993 }
1994
1995 inline wxString wxCStrData::AsString() const
1996 {
1997 if ( m_offset == 0 )
1998 return *m_str;
1999 else
2000 return m_str->Mid(m_offset);
2001 }
2002
2003 inline wxCStrData::operator wxString() const { return AsString(); }
2004
2005 inline wxUniChar wxCStrData::operator*() const
2006 {
2007 if ( m_str->empty() )
2008 return wxUniChar(_T('\0'));
2009 else
2010 return (*m_str)[m_offset];
2011 }
2012
2013 inline wxUniChar wxCStrData::operator[](size_t n) const
2014 {
2015 return m_str->at(m_offset + n);
2016 }
2017
2018 // ----------------------------------------------------------------------------
2019 // implementation of wxString inline methods using wxCStrData
2020 // ----------------------------------------------------------------------------
2021
2022 inline wxString& wxString::operator=(const wxCStrData& cstr)
2023 {
2024 return *this = cstr.AsString();
2025 }
2026
2027 // ----------------------------------------------------------------------------
2028 // implementation of wx[W]CharBuffer inline methods using wxCStrData
2029 // ----------------------------------------------------------------------------
2030
2031 #if wxUSE_UNICODE
2032
2033 inline wxWCharBuffer::wxWCharBuffer(const wxCStrData& cstr)
2034 : m_str(wxStrdupW(cstr))
2035 {
2036 }
2037
2038 #else // !wxUSE_UNICODE
2039
2040 inline wxCharBuffer::wxCharBuffer(const wxCStrData& cstr)
2041 : m_str(wxStrdupA(cstr))
2042 {
2043 }
2044
2045 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
2046
2047 #endif // _WX_WXSTRINGH__