+ // 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()
+ {
+#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
+ //RN - according to the above VC++ does indeed inline this,
+ //even though it spits out two warnings
+ #pragma warning (disable:4714)
+#endif
+
+ GetStringData()->Unlock();
+ }
+
+#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
+ //re-enable inlining warning
+ #pragma warning (default:4714)
+#endif
+ // 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();
+ // position one after the last valid one
+ iterator end();
+
+ // 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.
+
+ // comparison with another string
+ int compare(const wxStringBase& str) const;
+ // 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;
+ // comparison with a c string
+ int compare(const wxChar* sz) const;
+ // 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
+
+// ---------------------------------------------------------------------------
+// This is (yet another one) String class for C++ programmers. It doesn't use
+// any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
+// thus you should be able to compile it with practicaly any C++ compiler.
+// This class uses copy-on-write technique, i.e. identical strings share the
+// same memory as long as neither of them is changed.
+//
+// This class aims to be as compatible as possible with the new standard
+// std::string class, but adds some additional functions and should be at
+// least as efficient than the standard implementation.
+//
+// Performance note: it's more efficient to write functions which take "const
+// String&" arguments than "const char *" if you assign the argument to
+// another string.
+//
+// It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
+//
+// To do:
+// - ressource support (string tables in ressources)
+// - more wide character (UNICODE) support
+// - regular expressions support
+// ---------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxString : public wxStringBase
+{
+#if !wxUSE_STL
+friend class WXDLLIMPEXP_BASE wxArrayString;
+#endif
+
+ // NB: special care was taken in arranging the member functions in such order
+ // that all inline functions can be effectively inlined, verify that all
+ // performace critical functions are still inlined if you change order!
+private: