| 1 | /////////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: wx/stringimpl.h |
| 3 | // Purpose: wxStringImpl class, implementation of wxString |
| 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 | This header implements std::string-like string class, wxStringImpl, that is |
| 14 | used by wxString to store the data. Alternatively, if wxUSE_STL=1, |
| 15 | wxStringImpl is just a typedef to std:: string class. |
| 16 | */ |
| 17 | |
| 18 | #ifndef _WX_WXSTRINGIMPL_H__ |
| 19 | #define _WX_WXSTRINGIMPL_H__ |
| 20 | |
| 21 | // ---------------------------------------------------------------------------- |
| 22 | // headers |
| 23 | // ---------------------------------------------------------------------------- |
| 24 | |
| 25 | #include "wx/defs.h" // everybody should include this |
| 26 | #include "wx/chartype.h" // for wxChar |
| 27 | #include "wx/wxcrtbase.h" // for wxStrlen() etc. |
| 28 | |
| 29 | #include <stdlib.h> |
| 30 | |
| 31 | // --------------------------------------------------------------------------- |
| 32 | // macros |
| 33 | // --------------------------------------------------------------------------- |
| 34 | |
| 35 | // implementation only |
| 36 | #define wxASSERT_VALID_INDEX(i) \ |
| 37 | wxASSERT_MSG( (size_t)(i) <= length(), _T("invalid index in wxString") ) |
| 38 | |
| 39 | |
| 40 | // ---------------------------------------------------------------------------- |
| 41 | // global data |
| 42 | // ---------------------------------------------------------------------------- |
| 43 | |
| 44 | // global pointer to empty string |
| 45 | extern WXDLLIMPEXP_DATA_BASE(const wxChar*) wxEmptyString; |
| 46 | #if wxUSE_UNICODE_UTF8 |
| 47 | // FIXME-UTF8: we should have only one wxEmptyString |
| 48 | extern WXDLLIMPEXP_DATA_BASE(const wxStringCharType*) wxEmptyStringImpl; |
| 49 | #endif |
| 50 | |
| 51 | |
| 52 | // ---------------------------------------------------------------------------- |
| 53 | // deal with STL/non-STL/non-STL-but-wxUSE_STD_STRING |
| 54 | // ---------------------------------------------------------------------------- |
| 55 | |
| 56 | // using STL implies using std::string |
| 57 | #if wxUSE_STL |
| 58 | #undef wxUSE_STD_STRING |
| 59 | #define wxUSE_STD_STRING 1 |
| 60 | #endif |
| 61 | |
| 62 | // we use STL-based string internally if we use std::string at all now, there |
| 63 | // should be no reason to prefer our internal implement but if you really need |
| 64 | // it you can predefine wxUSE_STL_BASED_WXSTRING as 0 when building the library |
| 65 | #ifndef wxUSE_STL_BASED_WXSTRING |
| 66 | #define wxUSE_STL_BASED_WXSTRING wxUSE_STD_STRING |
| 67 | #endif |
| 68 | |
| 69 | // in both cases we need to define wxStdString |
| 70 | #if wxUSE_STL_BASED_WXSTRING || wxUSE_STD_STRING |
| 71 | |
| 72 | #include "wx/beforestd.h" |
| 73 | #include <string> |
| 74 | #include "wx/afterstd.h" |
| 75 | |
| 76 | #ifdef HAVE_STD_WSTRING |
| 77 | typedef std::wstring wxStdWideString; |
| 78 | #else |
| 79 | typedef std::basic_string<wchar_t> wxStdWideString; |
| 80 | #endif |
| 81 | |
| 82 | #if wxUSE_UNICODE_WCHAR |
| 83 | typedef wxStdWideString wxStdString; |
| 84 | #else |
| 85 | typedef std::string wxStdString; |
| 86 | #endif |
| 87 | |
| 88 | #endif // wxUSE_STL_BASED_WXSTRING || wxUSE_STD_STRING |
| 89 | |
| 90 | |
| 91 | #if wxUSE_STL_BASED_WXSTRING |
| 92 | |
| 93 | // we always want ctor from std::string when using std::string internally |
| 94 | #undef wxUSE_STD_STRING |
| 95 | #define wxUSE_STD_STRING 1 |
| 96 | |
| 97 | #if (defined(__GNUG__) && (__GNUG__ < 3)) || \ |
| 98 | (defined(_MSC_VER) && (_MSC_VER <= 1200)) |
| 99 | #define wxSTRING_BASE_HASNT_CLEAR |
| 100 | #endif |
| 101 | |
| 102 | typedef wxStdString wxStringImpl; |
| 103 | #else // if !wxUSE_STL_BASED_WXSTRING |
| 104 | |
| 105 | // in non-STL mode, compare() is implemented in wxString and not wxStringImpl |
| 106 | #undef HAVE_STD_STRING_COMPARE |
| 107 | |
| 108 | // --------------------------------------------------------------------------- |
| 109 | // string data prepended with some housekeeping info (used by wxString class), |
| 110 | // is never used directly (but had to be put here to allow inlining) |
| 111 | // --------------------------------------------------------------------------- |
| 112 | |
| 113 | struct WXDLLIMPEXP_BASE wxStringData |
| 114 | { |
| 115 | int nRefs; // reference count |
| 116 | size_t nDataLength, // actual string length |
| 117 | nAllocLength; // allocated memory size |
| 118 | |
| 119 | // mimics declaration 'wxStringCharType data[nAllocLength]' |
| 120 | wxStringCharType* data() const { return (wxStringCharType*)(this + 1); } |
| 121 | |
| 122 | // empty string has a special ref count so it's never deleted |
| 123 | bool IsEmpty() const { return (nRefs == -1); } |
| 124 | bool IsShared() const { return (nRefs > 1); } |
| 125 | |
| 126 | // lock/unlock |
| 127 | void Lock() { if ( !IsEmpty() ) nRefs++; } |
| 128 | |
| 129 | // VC++ will refuse to inline Unlock but profiling shows that it is wrong |
| 130 | #if defined(__VISUALC__) && (__VISUALC__ >= 1200) |
| 131 | __forceinline |
| 132 | #endif |
| 133 | // VC++ free must take place in same DLL as allocation when using non dll |
| 134 | // run-time library (e.g. Multithreaded instead of Multithreaded DLL) |
| 135 | #if defined(__VISUALC__) && defined(_MT) && !defined(_DLL) |
| 136 | void Unlock() { if ( !IsEmpty() && --nRefs == 0) Free(); } |
| 137 | // we must not inline deallocation since allocation is not inlined |
| 138 | void Free(); |
| 139 | #else |
| 140 | void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); } |
| 141 | #endif |
| 142 | |
| 143 | // if we had taken control over string memory (GetWriteBuf), it's |
| 144 | // intentionally put in invalid state |
| 145 | void Validate(bool b) { nRefs = (b ? 1 : 0); } |
| 146 | bool IsValid() const { return (nRefs != 0); } |
| 147 | }; |
| 148 | |
| 149 | class WXDLLIMPEXP_BASE wxStringImpl |
| 150 | { |
| 151 | public: |
| 152 | // an 'invalid' value for string index, moved to this place due to a CW bug |
| 153 | static const size_t npos; |
| 154 | |
| 155 | protected: |
| 156 | // points to data preceded by wxStringData structure with ref count info |
| 157 | wxStringCharType *m_pchData; |
| 158 | |
| 159 | // accessor to string data |
| 160 | wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; } |
| 161 | |
| 162 | // string (re)initialization functions |
| 163 | // initializes the string to the empty value (must be called only from |
| 164 | // ctors, use Reinit() otherwise) |
| 165 | #if wxUSE_UNICODE_UTF8 |
| 166 | void Init() { m_pchData = (wxStringCharType *)wxEmptyStringImpl; } // FIXME-UTF8 |
| 167 | #else |
| 168 | void Init() { m_pchData = (wxStringCharType *)wxEmptyString; } |
| 169 | #endif |
| 170 | // initializes the string with (a part of) C-string |
| 171 | void InitWith(const wxStringCharType *psz, size_t nPos = 0, size_t nLen = npos); |
| 172 | // as Init, but also frees old data |
| 173 | void Reinit() { GetStringData()->Unlock(); Init(); } |
| 174 | |
| 175 | // memory allocation |
| 176 | // allocates memory for string of length nLen |
| 177 | bool AllocBuffer(size_t nLen); |
| 178 | // effectively copies data to string |
| 179 | bool AssignCopy(size_t, const wxStringCharType *); |
| 180 | |
| 181 | // append a (sub)string |
| 182 | bool ConcatSelf(size_t nLen, const wxStringCharType *src, size_t nMaxLen); |
| 183 | bool ConcatSelf(size_t nLen, const wxStringCharType *src) |
| 184 | { return ConcatSelf(nLen, src, nLen); } |
| 185 | |
| 186 | // functions called before writing to the string: they copy it if there |
| 187 | // are other references to our data (should be the only owner when writing) |
| 188 | bool CopyBeforeWrite(); |
| 189 | bool AllocBeforeWrite(size_t); |
| 190 | |
| 191 | // compatibility with wxString |
| 192 | bool Alloc(size_t nLen); |
| 193 | |
| 194 | public: |
| 195 | // standard types |
| 196 | typedef wxStringCharType value_type; |
| 197 | typedef wxStringCharType char_type; |
| 198 | typedef size_t size_type; |
| 199 | typedef value_type& reference; |
| 200 | typedef const value_type& const_reference; |
| 201 | typedef value_type* pointer; |
| 202 | typedef const value_type* const_pointer; |
| 203 | |
| 204 | // macro to define the bulk of iterator and const_iterator classes |
| 205 | #define WX_DEFINE_STRINGIMPL_ITERATOR(iterator_name, ref_type, ptr_type) \ |
| 206 | public: \ |
| 207 | typedef wxStringCharType value_type; \ |
| 208 | typedef ref_type reference; \ |
| 209 | typedef ptr_type pointer; \ |
| 210 | typedef int difference_type; \ |
| 211 | \ |
| 212 | iterator_name() : m_ptr(NULL) { } \ |
| 213 | iterator_name(pointer ptr) : m_ptr(ptr) { } \ |
| 214 | \ |
| 215 | reference operator*() const { return *m_ptr; } \ |
| 216 | \ |
| 217 | iterator_name& operator++() { m_ptr++; return *this; } \ |
| 218 | iterator_name operator++(int) \ |
| 219 | { \ |
| 220 | const iterator_name tmp(*this); \ |
| 221 | m_ptr++; \ |
| 222 | return tmp; \ |
| 223 | } \ |
| 224 | \ |
| 225 | iterator_name& operator--() { m_ptr--; return *this; } \ |
| 226 | iterator_name operator--(int) \ |
| 227 | { \ |
| 228 | const iterator_name tmp(*this); \ |
| 229 | m_ptr--; \ |
| 230 | return tmp; \ |
| 231 | } \ |
| 232 | \ |
| 233 | iterator_name operator+(ptrdiff_t n) const \ |
| 234 | { return iterator_name(m_ptr + n); } \ |
| 235 | iterator_name operator-(ptrdiff_t n) const \ |
| 236 | { return iterator_name(m_ptr - n); } \ |
| 237 | iterator_name& operator+=(ptrdiff_t n) \ |
| 238 | { m_ptr += n; return *this; } \ |
| 239 | iterator_name& operator-=(ptrdiff_t n) \ |
| 240 | { m_ptr -= n; return *this; } \ |
| 241 | \ |
| 242 | difference_type operator-(const iterator_name& i) const \ |
| 243 | { return m_ptr - i.m_ptr; } \ |
| 244 | \ |
| 245 | bool operator==(const iterator_name& i) const \ |
| 246 | { return m_ptr == i.m_ptr; } \ |
| 247 | bool operator!=(const iterator_name& i) const \ |
| 248 | { return m_ptr != i.m_ptr; } \ |
| 249 | \ |
| 250 | bool operator<(const iterator_name& i) const \ |
| 251 | { return m_ptr < i.m_ptr; } \ |
| 252 | bool operator>(const iterator_name& i) const \ |
| 253 | { return m_ptr > i.m_ptr; } \ |
| 254 | bool operator<=(const iterator_name& i) const \ |
| 255 | { return m_ptr <= i.m_ptr; } \ |
| 256 | bool operator>=(const iterator_name& i) const \ |
| 257 | { return m_ptr >= i.m_ptr; } \ |
| 258 | \ |
| 259 | private: \ |
| 260 | /* for wxStringImpl use only */ \ |
| 261 | pointer GetPtr() const { return m_ptr; } \ |
| 262 | \ |
| 263 | friend class wxStringImpl; \ |
| 264 | \ |
| 265 | pointer m_ptr |
| 266 | |
| 267 | // we need to declare const_iterator in wxStringImpl scope, the friend |
| 268 | // declaration inside iterator class itself is not enough, or at least not |
| 269 | // for g++ 3.4 (g++ 4 is ok) |
| 270 | class WXDLLIMPEXP_FWD_BASE const_iterator; |
| 271 | |
| 272 | class WXDLLIMPEXP_BASE iterator |
| 273 | { |
| 274 | WX_DEFINE_STRINGIMPL_ITERATOR(iterator, |
| 275 | wxStringCharType&, |
| 276 | wxStringCharType*); |
| 277 | |
| 278 | friend class const_iterator; |
| 279 | }; |
| 280 | |
| 281 | class WXDLLIMPEXP_BASE const_iterator |
| 282 | { |
| 283 | public: |
| 284 | const_iterator(iterator i) : m_ptr(i.m_ptr) { } |
| 285 | |
| 286 | WX_DEFINE_STRINGIMPL_ITERATOR(const_iterator, |
| 287 | const wxStringCharType&, |
| 288 | const wxStringCharType*); |
| 289 | }; |
| 290 | |
| 291 | #undef WX_DEFINE_STRINGIMPL_ITERATOR |
| 292 | |
| 293 | |
| 294 | // constructors and destructor |
| 295 | // ctor for an empty string |
| 296 | wxStringImpl() { Init(); } |
| 297 | // copy ctor |
| 298 | wxStringImpl(const wxStringImpl& stringSrc) |
| 299 | { |
| 300 | wxASSERT_MSG( stringSrc.GetStringData()->IsValid(), |
| 301 | _T("did you forget to call UngetWriteBuf()?") ); |
| 302 | |
| 303 | if ( stringSrc.empty() ) { |
| 304 | // nothing to do for an empty string |
| 305 | Init(); |
| 306 | } |
| 307 | else { |
| 308 | m_pchData = stringSrc.m_pchData; // share same data |
| 309 | GetStringData()->Lock(); // => one more copy |
| 310 | } |
| 311 | } |
| 312 | // string containing nRepeat copies of ch |
| 313 | wxStringImpl(size_type nRepeat, wxStringCharType ch); |
| 314 | // ctor takes first nLength characters from C string |
| 315 | // (default value of npos means take all the string) |
| 316 | wxStringImpl(const wxStringCharType *psz) |
| 317 | { InitWith(psz, 0, npos); } |
| 318 | wxStringImpl(const wxStringCharType *psz, size_t nLength) |
| 319 | { InitWith(psz, 0, nLength); } |
| 320 | // take nLen chars starting at nPos |
| 321 | wxStringImpl(const wxStringImpl& str, size_t nPos, size_t nLen) |
| 322 | { |
| 323 | wxASSERT_MSG( str.GetStringData()->IsValid(), |
| 324 | _T("did you forget to call UngetWriteBuf()?") ); |
| 325 | Init(); |
| 326 | size_t strLen = str.length() - nPos; nLen = strLen < nLen ? strLen : nLen; |
| 327 | InitWith(str.c_str(), nPos, nLen); |
| 328 | } |
| 329 | // take everything between start and end |
| 330 | wxStringImpl(const_iterator start, const_iterator end); |
| 331 | |
| 332 | |
| 333 | // ctor from and conversion to std::string |
| 334 | #if wxUSE_STD_STRING |
| 335 | wxStringImpl(const wxStdString& impl) |
| 336 | { InitWith(impl.c_str(), 0, impl.length()); } |
| 337 | |
| 338 | operator wxStdString() const |
| 339 | { return wxStdString(c_str(), length()); } |
| 340 | #endif |
| 341 | |
| 342 | |
| 343 | // dtor is not virtual, this class must not be inherited from! |
| 344 | ~wxStringImpl() |
| 345 | { |
| 346 | #if defined(__VISUALC__) && (__VISUALC__ >= 1200) |
| 347 | //RN - according to the above VC++ does indeed inline this, |
| 348 | //even though it spits out two warnings |
| 349 | #pragma warning (disable:4714) |
| 350 | #endif |
| 351 | |
| 352 | GetStringData()->Unlock(); |
| 353 | } |
| 354 | |
| 355 | #if defined(__VISUALC__) && (__VISUALC__ >= 1200) |
| 356 | //re-enable inlining warning |
| 357 | #pragma warning (default:4714) |
| 358 | #endif |
| 359 | // overloaded assignment |
| 360 | // from another wxString |
| 361 | wxStringImpl& operator=(const wxStringImpl& stringSrc); |
| 362 | // from a character |
| 363 | wxStringImpl& operator=(wxStringCharType ch); |
| 364 | // from a C string |
| 365 | wxStringImpl& operator=(const wxStringCharType *psz); |
| 366 | |
| 367 | // return the length of the string |
| 368 | size_type length() const { return GetStringData()->nDataLength; } |
| 369 | // return the length of the string |
| 370 | size_type size() const { return length(); } |
| 371 | // return the maximum size of the string |
| 372 | size_type max_size() const { return npos; } |
| 373 | // resize the string, filling the space with c if c != 0 |
| 374 | void resize(size_t nSize, wxStringCharType ch = '\0'); |
| 375 | // delete the contents of the string |
| 376 | void clear() { erase(0, npos); } |
| 377 | // returns true if the string is empty |
| 378 | bool empty() const { return length() == 0; } |
| 379 | // inform string about planned change in size |
| 380 | void reserve(size_t sz) { Alloc(sz); } |
| 381 | size_type capacity() const { return GetStringData()->nAllocLength; } |
| 382 | |
| 383 | // lib.string.access |
| 384 | // return the character at position n |
| 385 | value_type operator[](size_type n) const { return m_pchData[n]; } |
| 386 | value_type at(size_type n) const |
| 387 | { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; } |
| 388 | // returns the writable character at position n |
| 389 | reference operator[](size_type n) { CopyBeforeWrite(); return m_pchData[n]; } |
| 390 | reference at(size_type n) |
| 391 | { |
| 392 | wxASSERT_VALID_INDEX( n ); |
| 393 | CopyBeforeWrite(); |
| 394 | return m_pchData[n]; |
| 395 | } // FIXME-UTF8: not useful for us...? |
| 396 | |
| 397 | // lib.string.modifiers |
| 398 | // append elements str[pos], ..., str[pos+n] |
| 399 | wxStringImpl& append(const wxStringImpl& str, size_t pos, size_t n) |
| 400 | { |
| 401 | wxASSERT(pos <= str.length()); |
| 402 | ConcatSelf(n, str.c_str() + pos, str.length() - pos); |
| 403 | return *this; |
| 404 | } |
| 405 | // append a string |
| 406 | wxStringImpl& append(const wxStringImpl& str) |
| 407 | { ConcatSelf(str.length(), str.c_str()); return *this; } |
| 408 | // append first n (or all if n == npos) characters of sz |
| 409 | wxStringImpl& append(const wxStringCharType *sz) |
| 410 | { ConcatSelf(wxStrlen(sz), sz); return *this; } |
| 411 | wxStringImpl& append(const wxStringCharType *sz, size_t n) |
| 412 | { ConcatSelf(n, sz); return *this; } |
| 413 | // append n copies of ch |
| 414 | wxStringImpl& append(size_t n, wxStringCharType ch); |
| 415 | // append from first to last |
| 416 | wxStringImpl& append(const_iterator first, const_iterator last) |
| 417 | { ConcatSelf(last - first, first.GetPtr()); return *this; } |
| 418 | |
| 419 | // same as `this_string = str' |
| 420 | wxStringImpl& assign(const wxStringImpl& str) |
| 421 | { return *this = str; } |
| 422 | // same as ` = str[pos..pos + n] |
| 423 | wxStringImpl& assign(const wxStringImpl& str, size_t pos, size_t n) |
| 424 | { return replace(0, npos, str, pos, n); } |
| 425 | // same as `= first n (or all if n == npos) characters of sz' |
| 426 | wxStringImpl& assign(const wxStringCharType *sz) |
| 427 | { return replace(0, npos, sz, wxStrlen(sz)); } |
| 428 | wxStringImpl& assign(const wxStringCharType *sz, size_t n) |
| 429 | { return replace(0, npos, sz, n); } |
| 430 | // same as `= n copies of ch' |
| 431 | wxStringImpl& assign(size_t n, wxStringCharType ch) |
| 432 | { return replace(0, npos, n, ch); } |
| 433 | // assign from first to last |
| 434 | wxStringImpl& assign(const_iterator first, const_iterator last) |
| 435 | { return replace(begin(), end(), first, last); } |
| 436 | |
| 437 | // first valid index position |
| 438 | const_iterator begin() const { return m_pchData; } |
| 439 | iterator begin(); |
| 440 | // position one after the last valid one |
| 441 | const_iterator end() const { return m_pchData + length(); } |
| 442 | iterator end(); |
| 443 | |
| 444 | // insert another string |
| 445 | wxStringImpl& insert(size_t nPos, const wxStringImpl& str) |
| 446 | { |
| 447 | wxASSERT( str.GetStringData()->IsValid() ); |
| 448 | return insert(nPos, str.c_str(), str.length()); |
| 449 | } |
| 450 | // insert n chars of str starting at nStart (in str) |
| 451 | wxStringImpl& insert(size_t nPos, const wxStringImpl& str, size_t nStart, size_t n) |
| 452 | { |
| 453 | wxASSERT( str.GetStringData()->IsValid() ); |
| 454 | wxASSERT( nStart < str.length() ); |
| 455 | size_t strLen = str.length() - nStart; |
| 456 | n = strLen < n ? strLen : n; |
| 457 | return insert(nPos, str.c_str() + nStart, n); |
| 458 | } |
| 459 | // insert first n (or all if n == npos) characters of sz |
| 460 | wxStringImpl& insert(size_t nPos, const wxStringCharType *sz, size_t n = npos); |
| 461 | // insert n copies of ch |
| 462 | wxStringImpl& insert(size_t nPos, size_t n, wxStringCharType ch) |
| 463 | { return insert(nPos, wxStringImpl(n, ch)); } |
| 464 | iterator insert(iterator it, wxStringCharType ch) |
| 465 | { size_t idx = it - begin(); insert(idx, 1, ch); return begin() + idx; } |
| 466 | void insert(iterator it, const_iterator first, const_iterator last) |
| 467 | { insert(it - begin(), first.GetPtr(), last - first); } |
| 468 | void insert(iterator it, size_type n, wxStringCharType ch) |
| 469 | { insert(it - begin(), n, ch); } |
| 470 | |
| 471 | // delete characters from nStart to nStart + nLen |
| 472 | wxStringImpl& erase(size_type pos = 0, size_type n = npos); |
| 473 | iterator erase(iterator first, iterator last) |
| 474 | { |
| 475 | size_t idx = first - begin(); |
| 476 | erase(idx, last - first); |
| 477 | return begin() + idx; |
| 478 | } |
| 479 | iterator erase(iterator first); |
| 480 | |
| 481 | // explicit conversion to C string (use this with printf()!) |
| 482 | const wxStringCharType* c_str() const { return m_pchData; } |
| 483 | const wxStringCharType* data() const { return m_pchData; } |
| 484 | |
| 485 | // replaces the substring of length nLen starting at nStart |
| 486 | wxStringImpl& replace(size_t nStart, size_t nLen, const wxStringCharType* sz) |
| 487 | { return replace(nStart, nLen, sz, npos); } |
| 488 | // replaces the substring of length nLen starting at nStart |
| 489 | wxStringImpl& replace(size_t nStart, size_t nLen, const wxStringImpl& str) |
| 490 | { return replace(nStart, nLen, str.c_str(), str.length()); } |
| 491 | // replaces the substring with nCount copies of ch |
| 492 | wxStringImpl& replace(size_t nStart, size_t nLen, |
| 493 | size_t nCount, wxStringCharType ch) |
| 494 | { return replace(nStart, nLen, wxStringImpl(nCount, ch)); } |
| 495 | // replaces a substring with another substring |
| 496 | wxStringImpl& replace(size_t nStart, size_t nLen, |
| 497 | const wxStringImpl& str, size_t nStart2, size_t nLen2) |
| 498 | { return replace(nStart, nLen, str.substr(nStart2, nLen2)); } |
| 499 | // replaces the substring with first nCount chars of sz |
| 500 | wxStringImpl& replace(size_t nStart, size_t nLen, |
| 501 | const wxStringCharType* sz, size_t nCount); |
| 502 | |
| 503 | wxStringImpl& replace(iterator first, iterator last, const_pointer s) |
| 504 | { return replace(first - begin(), last - first, s); } |
| 505 | wxStringImpl& replace(iterator first, iterator last, const_pointer s, |
| 506 | size_type n) |
| 507 | { return replace(first - begin(), last - first, s, n); } |
| 508 | wxStringImpl& replace(iterator first, iterator last, const wxStringImpl& s) |
| 509 | { return replace(first - begin(), last - first, s); } |
| 510 | wxStringImpl& replace(iterator first, iterator last, size_type n, wxStringCharType c) |
| 511 | { return replace(first - begin(), last - first, n, c); } |
| 512 | wxStringImpl& replace(iterator first, iterator last, |
| 513 | const_iterator first1, const_iterator last1) |
| 514 | { return replace(first - begin(), last - first, first1.GetPtr(), last1 - first1); } |
| 515 | |
| 516 | // swap two strings |
| 517 | void swap(wxStringImpl& str); |
| 518 | |
| 519 | // All find() functions take the nStart argument which specifies the |
| 520 | // position to start the search on, the default value is 0. All functions |
| 521 | // return npos if there were no match. |
| 522 | |
| 523 | // find a substring |
| 524 | size_t find(const wxStringImpl& str, size_t nStart = 0) const; |
| 525 | |
| 526 | // find first n characters of sz |
| 527 | size_t find(const wxStringCharType* sz, size_t nStart = 0, size_t n = npos) const; |
| 528 | |
| 529 | // find the first occurrence of character ch after nStart |
| 530 | size_t find(wxStringCharType ch, size_t nStart = 0) const; |
| 531 | |
| 532 | // rfind() family is exactly like find() but works right to left |
| 533 | |
| 534 | // as find, but from the end |
| 535 | size_t rfind(const wxStringImpl& str, size_t nStart = npos) const; |
| 536 | |
| 537 | // as find, but from the end |
| 538 | size_t rfind(const wxStringCharType* sz, size_t nStart = npos, |
| 539 | size_t n = npos) const; |
| 540 | // as find, but from the end |
| 541 | size_t rfind(wxStringCharType ch, size_t nStart = npos) const; |
| 542 | |
| 543 | size_type copy(wxStringCharType* s, size_type n, size_type pos = 0); |
| 544 | |
| 545 | // substring extraction |
| 546 | wxStringImpl substr(size_t nStart = 0, size_t nLen = npos) const; |
| 547 | |
| 548 | // string += string |
| 549 | wxStringImpl& operator+=(const wxStringImpl& s) { return append(s); } |
| 550 | // string += C string |
| 551 | wxStringImpl& operator+=(const wxStringCharType *psz) { return append(psz); } |
| 552 | // string += char |
| 553 | wxStringImpl& operator+=(wxStringCharType ch) { return append(1, ch); } |
| 554 | |
| 555 | // helpers for wxStringBuffer and wxStringBufferLength |
| 556 | wxStringCharType *DoGetWriteBuf(size_t nLen); |
| 557 | void DoUngetWriteBuf(); |
| 558 | void DoUngetWriteBuf(size_t nLen); |
| 559 | |
| 560 | friend class WXDLLIMPEXP_FWD_BASE wxString; |
| 561 | }; |
| 562 | |
| 563 | #endif // !wxUSE_STL_BASED_WXSTRING |
| 564 | |
| 565 | // don't pollute the library user's name space |
| 566 | #undef wxASSERT_VALID_INDEX |
| 567 | |
| 568 | #endif // _WX_WXSTRINGIMPL_H__ |