+class WXDLLIMPEXP_BASE wxStringBase
+{
+#if !wxUSE_STL
+friend class WXDLLIMPEXP_BASE wxArrayString;
+#endif
+public :
+ // an 'invalid' value for string index, moved to this place due to a CW bug
+ static const size_t npos;
+protected:
+ // points to data preceded by wxStringData structure with ref count info
+ wxChar *m_pchData;
+
+ // accessor to string data
+ wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
+
+ // string (re)initialization functions
+ // initializes the string to the empty value (must be called only from
+ // ctors, use Reinit() otherwise)
+ void Init() { m_pchData = (wxChar *)wxEmptyString; }
+ // initializaes the string with (a part of) C-string
+ void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = npos);
+ // as Init, but also frees old data
+ void Reinit() { GetStringData()->Unlock(); Init(); }
+
+ // memory allocation
+ // allocates memory for string of length nLen
+ bool AllocBuffer(size_t nLen);
+ // copies data to another string
+ bool AllocCopy(wxString&, int, int) const;
+ // effectively copies data to string
+ bool AssignCopy(size_t, const wxChar *);
+
+ // append a (sub)string
+ bool ConcatSelf(size_t nLen, const wxChar *src, size_t nMaxLen);
+ bool ConcatSelf(size_t nLen, const wxChar *src)
+ { return ConcatSelf(nLen, src, nLen); }
+
+ // functions called before writing to the string: they copy it if there
+ // are other references to our data (should be the only owner when writing)
+ bool CopyBeforeWrite();
+ bool AllocBeforeWrite(size_t);
+
+ // compatibility with wxString
+ bool Alloc(size_t nLen);
+public:
+ // standard types
+ typedef wxChar value_type;
+ typedef wxChar char_type;
+ typedef size_t size_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type *iterator;
+ typedef const value_type *const_iterator;
+
+ // constructors and destructor
+ // ctor for an empty string
+ wxStringBase() { Init(); }
+ // copy ctor
+ wxStringBase(const wxStringBase& stringSrc)
+ {
+ wxASSERT_MSG( stringSrc.GetStringData()->IsValid(),
+ _T("did you forget to call UngetWriteBuf()?") );
+
+ if ( stringSrc.empty() ) {
+ // nothing to do for an empty string
+ Init();
+ }
+ else {
+ m_pchData = stringSrc.m_pchData; // share same data
+ GetStringData()->Lock(); // => one more copy
+ }
+ }
+ // string containing nRepeat copies of ch
+ wxStringBase(size_type nRepeat, wxChar ch);
+ // ctor takes first nLength characters from C string
+ // (default value of npos means take all the string)
+ wxStringBase(const wxChar *psz)
+ { InitWith(psz, 0, npos); }
+ wxStringBase(const wxChar *psz, size_t nLength)
+ { InitWith(psz, 0, nLength); }
+ wxStringBase(const wxChar *psz, wxMBConv& WXUNUSED(conv), size_t nLength = npos)
+ { InitWith(psz, 0, nLength); }
+ // take nLen chars starting at nPos
+ wxStringBase(const wxStringBase& str, size_t nPos, size_t nLen)
+ {
+ wxASSERT_MSG( str.GetStringData()->IsValid(),
+ _T("did you forget to call UngetWriteBuf()?") );
+ Init();
+ size_t strLen = str.length() - nPos; nLen = strLen < nLen ? strLen : nLen;
+ InitWith(str.c_str(), nPos, nLen);
+ }
+ // take all characters from pStart to pEnd
+ wxStringBase(const void *pStart, const void *pEnd);
+
+ // dtor is not virtual, this class must not be inherited from!
+ ~wxStringBase() { GetStringData()->Unlock(); }
+
+ // overloaded assignment
+ // from another wxString
+ wxStringBase& operator=(const wxStringBase& stringSrc);
+ // from a character
+ wxStringBase& operator=(wxChar ch);
+ // from a C string
+ wxStringBase& operator=(const wxChar *psz);
+
+ // return the length of the string
+ size_type size() const { return GetStringData()->nDataLength; }
+ // return the length of the string
+ size_type length() const { return size(); }
+ // return the maximum size of the string
+ size_type max_size() const { return wxSTRING_MAXLEN; }
+ // resize the string, filling the space with c if c != 0
+ void resize(size_t nSize, wxChar ch = wxT('\0'));
+ // delete the contents of the string
+ void clear() { erase(0, npos); }
+ // returns true if the string is empty
+ bool empty() const { return size() == 0; }
+ // inform string about planned change in size
+ void reserve(size_t sz) { Alloc(sz); }
+ size_type capacity() const { return GetStringData()->nAllocLength; }
+
+ // lib.string.access
+ // return the character at position n
+ value_type at(size_type n) const
+ { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
+ value_type operator[](size_type n) const { return at(n); }
+ // returns the writable character at position n
+ reference at(size_type n)
+ { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
+ reference operator[](size_type n)
+ { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
+
+ // lib.string.modifiers
+ // append elements str[pos], ..., str[pos+n]
+ wxStringBase& append(const wxStringBase& str, size_t pos, size_t n)
+ {
+ wxASSERT(pos <= str.length());
+ ConcatSelf(n, str.c_str() + pos, str.length() - pos);
+ return *this;
+ }
+ // append a string
+ wxStringBase& append(const wxStringBase& str)
+ { ConcatSelf(str.length(), str.c_str()); return *this; }
+ // append first n (or all if n == npos) characters of sz
+ wxStringBase& append(const wxChar *sz)
+ { ConcatSelf(wxStrlen(sz), sz); return *this; }
+ wxStringBase& append(const wxChar *sz, size_t n)
+ { ConcatSelf(n, sz); return *this; }
+ // append n copies of ch
+ wxStringBase& append(size_t n, wxChar ch);
+ // append from first to last
+ wxStringBase& append(const_iterator first, const_iterator last)
+ { ConcatSelf(last - first, first); return *this; }
+
+ // same as `this_string = str'
+ wxStringBase& assign(const wxStringBase& str)
+ { return *this = str; }
+ // same as ` = str[pos..pos + n]
+ wxStringBase& assign(const wxStringBase& str, size_t pos, size_t n)
+ { clear(); return append(str, pos, n); }
+ // same as `= first n (or all if n == npos) characters of sz'
+ wxStringBase& assign(const wxChar *sz)
+ { clear(); return append(sz, wxStrlen(sz)); }
+ wxStringBase& assign(const wxChar *sz, size_t n)
+ { clear(); return append(sz, n); }
+ // same as `= n copies of ch'
+ wxStringBase& assign(size_t n, wxChar ch)
+ { clear(); return append(n, ch); }
+ // assign from first to last
+ wxStringBase& assign(const_iterator first, const_iterator last)
+ { clear(); return append(first, last); }
+
+ // first valid index position
+ const_iterator begin() const { return m_pchData; }
+ // position one after the last valid one
+ const_iterator end() const { return m_pchData + length(); }
+
+ // first valid index position
+ iterator begin() { CopyBeforeWrite(); return m_pchData; }
+ // position one after the last valid one
+ iterator end() { CopyBeforeWrite(); return m_pchData + length(); }
+
+ // insert another string
+ wxStringBase& insert(size_t nPos, const wxStringBase& str)
+ {
+ wxASSERT( str.GetStringData()->IsValid() );
+ return insert(nPos, str.c_str(), str.length());
+ }
+ // insert n chars of str starting at nStart (in str)
+ wxStringBase& insert(size_t nPos, const wxStringBase& str, size_t nStart, size_t n)
+ {
+ wxASSERT( str.GetStringData()->IsValid() );
+ wxASSERT( nStart < str.length() );
+ size_t strLen = str.length() - nStart;
+ n = strLen < n ? strLen : n;
+ return insert(nPos, str.c_str() + nStart, n);
+ }
+ // insert first n (or all if n == npos) characters of sz
+ wxStringBase& insert(size_t nPos, const wxChar *sz, size_t n = npos);
+ // insert n copies of ch
+ wxStringBase& insert(size_t nPos, size_t n, wxChar ch)
+ { return insert(nPos, wxStringBase(n, ch)); }
+ iterator insert(iterator it, wxChar ch)
+ { size_t idx = it - begin(); insert(idx, 1, ch); return begin() + idx; }
+ void insert(iterator it, const_iterator first, const_iterator last)
+ { insert(it - begin(), first, last - first); }
+ void insert(iterator it, size_type n, wxChar ch)
+ { insert(it - begin(), n, ch); }
+
+ // delete characters from nStart to nStart + nLen
+ wxStringBase& erase(size_type pos = 0, size_type n = npos);
+ iterator erase(iterator first, iterator last)
+ {
+ size_t idx = first - begin();
+ erase(idx, last - first);
+ return begin() + idx;
+ }
+ iterator erase(iterator first);
+
+ // explicit conversion to C string (use this with printf()!)
+ const wxChar* c_str() const { return m_pchData; }
+ const wxChar* data() const { return m_pchData; }
+
+ // replaces the substring of length nLen starting at nStart
+ wxStringBase& replace(size_t nStart, size_t nLen, const wxChar* sz);
+ // replaces the substring of length nLen starting at nStart
+ wxStringBase& replace(size_t nStart, size_t nLen, const wxStringBase& str)
+ { return replace(nStart, nLen, str.c_str()); }
+ // replaces the substring with nCount copies of ch
+ wxStringBase& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
+ // replaces a substring with another substring
+ wxStringBase& replace(size_t nStart, size_t nLen,
+ const wxStringBase& str, size_t nStart2, size_t nLen2);
+ // replaces the substring with first nCount chars of sz
+ wxStringBase& replace(size_t nStart, size_t nLen,
+ const wxChar* sz, size_t nCount);
+ wxStringBase& replace(iterator first, iterator last, const_pointer s)
+ { return replace(first - begin(), last - first, s); }
+ wxStringBase& replace(iterator first, iterator last, const_pointer s,
+ size_type n)
+ { return replace(first - begin(), last - first, s, n); }
+ wxStringBase& replace(iterator first, iterator last, const wxStringBase& s)
+ { return replace(first - begin(), last - first, s); }
+ wxStringBase& replace(iterator first, iterator last, size_type n, wxChar c)
+ { return replace(first - begin(), last - first, n, c); }
+ wxStringBase& replace(iterator first, iterator last,
+ const_iterator first1, const_iterator last1)
+ { return replace(first - begin(), last - first, first1, last1 - first1); }
+
+ // swap two strings
+ void swap(wxStringBase& str);
+
+ // All find() functions take the nStart argument which specifies the
+ // position to start the search on, the default value is 0. All functions
+ // return npos if there were no match.
+
+ // find a substring
+ size_t find(const wxStringBase& str, size_t nStart = 0) const;
+
+ // VC++ 1.5 can't cope with this syntax.
+#if !defined(__VISUALC__) || defined(__WIN32__)
+ // find first n characters of sz
+ size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
+#endif // VC++ 1.5
+
+ // find the first occurence of character ch after nStart
+ size_t find(wxChar ch, size_t nStart = 0) const;
+
+ // rfind() family is exactly like find() but works right to left
+
+ // as find, but from the end
+ size_t rfind(const wxStringBase& str, size_t nStart = npos) const;
+
+ // VC++ 1.5 can't cope with this syntax.
+ // as find, but from the end
+ size_t rfind(const wxChar* sz, size_t nStart = npos,
+ size_t n = npos) const;
+ // as find, but from the end
+ size_t rfind(wxChar ch, size_t nStart = npos) const;
+
+ // find first/last occurence of any character in the set
+
+ // as strpbrk() but starts at nStart, returns npos if not found
+ size_t find_first_of(const wxStringBase& str, size_t nStart = 0) const
+ { return find_first_of(str.c_str(), nStart); }
+ // same as above
+ size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
+ size_t find_first_of(const wxChar* sz, size_t nStart, size_t n) const;
+ // same as find(char, size_t)
+ size_t find_first_of(wxChar c, size_t nStart = 0) const
+ { return find(c, nStart); }
+ // find the last (starting from nStart) char from str in this string
+ size_t find_last_of (const wxStringBase& str, size_t nStart = npos) const
+ { return find_last_of(str.c_str(), nStart); }
+ // same as above
+ size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
+ size_t find_last_of(const wxChar* sz, size_t nStart, size_t n) const;
+ // same as above
+ size_t find_last_of(wxChar c, size_t nStart = npos) const
+ { return rfind(c, nStart); }
+
+ // find first/last occurence of any character not in the set
+
+ // as strspn() (starting from nStart), returns npos on failure
+ size_t find_first_not_of(const wxStringBase& str, size_t nStart = 0) const
+ { return find_first_not_of(str.c_str(), nStart); }
+ // same as above
+ size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
+ size_t find_first_not_of(const wxChar* sz, size_t nStart, size_t n) const;
+ // same as above
+ size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
+ // as strcspn()
+ size_t find_last_not_of(const wxStringBase& str, size_t nStart = npos) const
+ { return find_last_not_of(str.c_str(), nStart); }
+ // same as above
+ size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
+ size_t find_last_not_of(const wxChar* sz, size_t nStart, size_t n) const;
+ // same as above
+ size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
+
+ // All compare functions return -1, 0 or 1 if the [sub]string is less,
+ // equal or greater than the compare() argument.
+
+ // just like strcmp()
+ int compare(const wxStringBase& str) const
+ { return wxStrcmp(c_str(), str.c_str()); }
+ // comparison with a substring
+ int compare(size_t nStart, size_t nLen, const wxStringBase& str) const;
+ // comparison of 2 substrings
+ int compare(size_t nStart, size_t nLen,
+ const wxStringBase& str, size_t nStart2, size_t nLen2) const;
+ // just like strcmp()
+ int compare(const wxChar* sz) const
+ { return wxStrcmp(c_str(), sz); }
+ // substring comparison with first nCount characters of sz
+ int compare(size_t nStart, size_t nLen,
+ const wxChar* sz, size_t nCount = npos) const;
+
+ size_type copy(wxChar* s, size_type n, size_type pos = 0);
+
+ // substring extraction
+ wxStringBase substr(size_t nStart = 0, size_t nLen = npos) const;
+
+ // string += string
+ wxStringBase& operator+=(const wxStringBase& s) { return append(s); }
+ // string += C string
+ wxStringBase& operator+=(const wxChar *psz) { return append(psz); }
+ // string += char
+ wxStringBase& operator+=(wxChar ch) { return append(1, ch); }
+};
+
+#endif // !wxUSE_STL
+