///////////////////////////////////////////////////////////////////////////////
-// Name: string.h
+// Name: wx/string.h
// Purpose: wxString and wxArrayString classes
// Author: Vadim Zeitlin
// Modified by:
/*
Efficient string class [more or less] compatible with MFC CString,
- wxWindows version 1 wxString and std::string and some handy functions
+ wxWidgets version 1 wxString and std::string and some handy functions
missing from string.h.
*/
#ifndef _WX_WXSTRINGH__
#define _WX_WXSTRINGH__
-#if defined(__GNUG__) && !defined(__APPLE__)
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "string.h"
#endif
#include <ctype.h>
#endif
-#ifdef __EMX__
- #include <std.h>
-#endif
-
#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
// problem in VACPP V4 with including stdlib.h multiple times
// strconv includes it anyway
# include <stdlib.h>
#endif
-#ifdef HAVE_STRINGS_H
+#ifdef HAVE_STRCASECMP_IN_STRINGS_H
#include <strings.h> // for strcasecmp()
-#endif // HAVE_STRINGS_H
+#endif // HAVE_STRCASECMP_IN_STRINGS_H
+
+#ifdef __PALMOS__
+ #include <StringMgr.h>
+#endif
#include "wx/wxchar.h" // for wxChar
#include "wx/buffer.h" // for wxCharBuffer
#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
+class WXDLLIMPEXP_BASE wxString;
+
// ---------------------------------------------------------------------------
// macros
// ---------------------------------------------------------------------------
#else
// maximum possible length for a string means "take all string" everywhere
-// (as sizeof(StringData) is unknown here, we substract 100)
+// (as sizeof(StringData) is unknown here, we subtract 100)
const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
#endif
return stricmp(psz1, psz2);
#elif defined(__WXPM__)
return stricmp(psz1, psz2);
-#elif defined(__UNIX__) || defined(__GNUWIN32__)
+#elif defined(HAVE_STRCASECMP_IN_STRING_H) || \
+ defined(HAVE_STRCASECMP_IN_STRINGS_H) || \
+ defined(__GNUWIN32__)
return strcasecmp(psz1, psz2);
#elif defined(__MWERKS__) && !defined(__INTEL__)
register char c1, c2;
#endif // OS/compiler
}
-// return an empty wxString
-class WXDLLIMPEXP_BASE wxString; // not yet defined
-inline const wxString& wxGetEmptyString() { return *(wxString *)&wxEmptyString; }
-
#if wxUSE_STL
#include "wx/beforestd.h"
#include "wx/afterstd.h"
#if wxUSE_UNICODE
- #if HAVE_STD_WSTRING
+ #ifdef HAVE_STD_WSTRING
typedef std::wstring wxStringBase;
#else
typedef std::basic_string<wxChar> wxStringBase;
#endif
#if (defined(__GNUG__) && (__GNUG__ < 3)) || \
- (defined(_MSC_VER) && (_MSC_VER <= 1100))
+ (defined(_MSC_VER) && (_MSC_VER <= 1200))
#define wxSTRING_BASE_HASNT_CLEAR
#endif
#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;
typedef value_type *iterator;
typedef const value_type *const_iterator;
- // an 'invalid' value for string index
- static const size_t npos;
-
// constructors and destructor
// ctor for an empty string
wxStringBase() { Init(); }
wxStringBase(const void *pStart, const void *pEnd);
// dtor is not virtual, this class must not be inherited from!
- ~wxStringBase() { GetStringData()->Unlock(); }
+ ~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);
const_iterator end() const { return m_pchData + length(); }
// first valid index position
- iterator begin() { CopyBeforeWrite(); return m_pchData; }
+ iterator begin();
// position one after the last valid one
- iterator end() { CopyBeforeWrite(); return m_pchData + length(); }
+ iterator end();
// insert another string
wxStringBase& insert(size_t nPos, const wxStringBase& str)
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; }
+ { 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)
size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
#endif // VC++ 1.5
- // Gives a duplicate symbol (presumably a case-insensitivity problem)
-#if !defined(__BORLANDC__)
// find the first occurence of character ch after nStart
size_t find(wxChar ch, size_t nStart = 0) const;
-#endif
+
// rfind() family is exactly like find() but works right to left
// as find, but from the end
{ 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); }
{ 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); }
{ 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_first_not_of(str.c_str(), nStart); }
+ { 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 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;
- // just like strcmp()
- int compare(const wxChar* sz) const
- { return wxStrcmp(c_str(), sz); }
+ // 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;
#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
+// ----------------------------------------------------------------------------
+// wxString: string class trying to be compatible with std::string, MFC
+// CString and wxWindows 1.x wxString all at once
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxString : public wxStringBase
#if wxUSE_UNICODE
// from multibyte string
- // (NB: nLength is right now number of Unicode characters, not
- // characters in psz! So try not to use it yet!)
wxString(const char *psz, wxMBConv& conv, size_t nLength = npos);
// from wxWCharBuffer (i.e. return from wxGetString)
wxString(const wxWCharBuffer& psz) : wxStringBase(psz.data()) { }
// from wxCharBuffer
wxString(const wxCharBuffer& psz)
- : wxStringBase(psz, npos) { }
+ : wxStringBase(psz) { }
#endif // Unicode/ANSI
// generic attributes & operations
size_t Len() const { return length(); }
// string contains any characters?
bool IsEmpty() const { return empty(); }
- // empty string is "FALSE", so !str will return TRUE
+ // empty string is "false", so !str will return true
bool operator!() const { return IsEmpty(); }
// truncate the string to given length
wxString& Truncate(size_t uiLen);
// type differs because a function may either return pointer to the buffer
// directly or have to use intermediate buffer for translation.
#if wxUSE_UNICODE
- const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const
- { return conv.cWC2MB(c_str()); }
+ const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const;
const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
const wxWX2MBbuf mbc_str() const { return mb_str(); }
#if wxUSE_WCHAR_T
- const wxWCharBuffer wc_str(wxMBConv& conv) const
- { return conv.cMB2WC(c_str()); }
+ const wxWCharBuffer wc_str(wxMBConv& conv) const;
#endif // wxUSE_WCHAR_T
-
+#ifdef __WXOSX__
+ const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); }
+#else
const wxChar* fn_str() const { return c_str(); }
+#endif
#endif // Unicode/ANSI
// overloaded assignment
// string comparison
// case-sensitive comparison (returns a value < 0, = 0 or > 0)
- int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); }
+ int Cmp(const wxChar *psz) const;
+ int Cmp(const wxString& s) const;
// same as Cmp() but not case-sensitive
- int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); }
+ int CmpNoCase(const wxChar *psz) const;
+ int CmpNoCase(const wxString& s) const;
// test for the string equality, either considering case or not
// (if compareWithCase then the case matters)
- bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const
+ bool IsSameAs(const wxChar *psz, bool compareWithCase = true) const
{ return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
- // comparison with a signle character: returns TRUE if equal
- bool IsSameAs(wxChar c, bool compareWithCase = TRUE) const
+ // comparison with a signle character: returns true if equal
+ bool IsSameAs(wxChar c, bool compareWithCase = true) const
{
return (length() == 1) && (compareWithCase ? GetChar(0u) == c
: wxToupper(GetChar(0u)) == wxToupper(c));
// check that the string starts with prefix and return the rest of the
// string in the provided pointer if it is not NULL, otherwise return
- // FALSE
+ // false
bool StartsWith(const wxChar *prefix, wxString *rest = NULL) const;
// get first nCount characters
// trimming/padding whitespace (either side) and truncating
// remove spaces from left or from right (default) side
- wxString& Trim(bool bFromRight = TRUE);
+ wxString& Trim(bool bFromRight = true);
// add nCount copies chPad in the beginning or at the end (default)
- wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = TRUE);
+ wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = true);
// searching and replacing
// searching (return starting index, or -1 if not found)
- int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
+ int Find(wxChar ch, bool bFromEnd = false) const; // like strchr/strrchr
// searching (return starting index, or -1 if not found)
int Find(const wxChar *pszSub) const; // like strstr
// replace first (or all of bReplaceAll) occurences of substring with
// another string, returns the number of replacements made
size_t Replace(const wxChar *szOld,
const wxChar *szNew,
- bool bReplaceAll = TRUE);
+ bool bReplaceAll = true);
// check if the string contents matches a mask containing '*' and '?'
bool Matches(const wxChar *szMask) const;
- // conversion to numbers: all functions return TRUE only if the whole
+ // conversion to numbers: all functions return true only if the whole
// string is a number and put the value of this number into the pointer
// provided, the base is the numeric base in which the conversion should be
// done and must be comprised between 2 and 36 or be 0 in which case the
void UngetWriteBuf(size_t nLen);
#endif
- // wxWindows version 1 compatibility functions
+ // wxWidgets version 1 compatibility functions
// use Mid()
wxString SubString(size_t from, size_t to) const
int First( const wxChar ch ) const { return Find(ch); }
int First( const wxChar* psz ) const { return Find(psz); }
int First( const wxString &str ) const { return Find(str); }
- int Last( const wxChar ch ) const { return Find(ch, TRUE); }
- bool Contains(const wxString& str) const { return Find(str) != -1; }
+ int Last( const wxChar ch ) const { return Find(ch, true); }
+ bool Contains(const wxString& str) const { return Find(str) != wxNOT_FOUND; }
// use IsEmpty()
bool IsNull() const { return IsEmpty(); }
: wxStringBase(str, nPos, nLen) { }
// take all characters from pStart to pEnd
wxString(const void *pStart, const void *pEnd)
- : wxStringBase((const char*)pStart, (const char*)pEnd) { }
+ : wxStringBase((const wxChar*)pStart, (const wxChar*)pEnd) { }
#if wxUSE_STL
wxString(const_iterator first, const_iterator last)
: wxStringBase(first, last) { }
wxString& insert(size_t nPos, size_t n, wxChar ch)
{ return (wxString&)wxStringBase::insert(nPos, n, ch); }
iterator insert(iterator it, wxChar ch)
- { return wxStringBase::insert(it, ch); }
+ { return wxStringBase::insert(it, ch); }
void insert(iterator it, const_iterator first, const_iterator last)
{ wxStringBase::insert(it, first, last); }
void insert(iterator it, size_type n, wxChar ch)
#include "wx/arrstr.h"
#endif
+#if wxUSE_STL
+ // return an empty wxString (not very useful with wxUSE_STL == 1)
+ inline const wxString wxGetEmptyString() { return wxString(); }
+#else // !wxUSE_STL
+ // return an empty wxString (more efficient than wxString() here)
+ inline const wxString& wxGetEmptyString()
+ {
+ return *(wxString *)&wxEmptyString;
+ }
+#endif // wxUSE_STL/!wxUSE_STL
+
// ----------------------------------------------------------------------------
// wxStringBuffer: a tiny class allowing to get a writable pointer into string
// ----------------------------------------------------------------------------
public:
wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
- { m_buf = m_str.GetWriteBuf(lenWanted); }
+ {
+ m_buf = m_str.GetWriteBuf(lenWanted);
+ wxASSERT(m_buf != NULL);
+ }
~wxStringBufferLength()
{
// wxString comparison functions: operator versions are always case sensitive
// ---------------------------------------------------------------------------
-#if wxUSE_STL
-
-inline bool operator==(const wxString& s1, const wxString& s2)
- { return s1.compare(s2) == 0; }
-inline bool operator==(const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) == 0; }
-inline bool operator==(const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) == 0; }
-inline bool operator!=(const wxString& s1, const wxString& s2)
- { return s1.compare(s2) != 0; }
-inline bool operator!=(const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) != 0; }
-inline bool operator!=(const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) != 0; }
-inline bool operator< (const wxString& s1, const wxString& s2)
- { return s1.compare(s2) < 0; }
-inline bool operator< (const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) < 0; }
-inline bool operator< (const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) > 0; }
-inline bool operator> (const wxString& s1, const wxString& s2)
- { return s1.compare(s2) > 0; }
-inline bool operator> (const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) > 0; }
-inline bool operator> (const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) < 0; }
-inline bool operator<=(const wxString& s1, const wxString& s2)
- { return s1.compare(s2) <= 0; }
-inline bool operator<=(const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) <= 0; }
-inline bool operator<=(const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) >= 0; }
-inline bool operator>=(const wxString& s1, const wxString& s2)
- { return s1.compare(s2) >= 0; }
-inline bool operator>=(const wxString& s1, const wxChar * s2)
- { return s1.compare(s2) >= 0; }
-inline bool operator>=(const wxChar * s1, const wxString& s2)
- { return s2.compare(s1) <= 0; }
-
-#else // if !wxUSE_STL
+// note that when wxUSE_STL == 1 the comparison operators taking std::string
+// are used and defining them also for wxString would only result in
+// compilation ambiguities when comparing std::string and wxString
+#if !wxUSE_STL
inline bool operator==(const wxString& s1, const wxString& s2)
{ return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); }
inline bool operator>=(const wxChar * s1, const wxString& s2)
{ return s2.Cmp(s1) <= 0; }
-#endif // !wxUSE_STL
-
-// comparison with char
-inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
-inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
-inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
-inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
-
#if wxUSE_UNICODE
inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
{ return (s1.Cmp((const wchar_t *)s2) == 0); }
{ return (s2.Cmp((const char *)s1) != 0); }
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
-#if !wxUSE_STL
-
wxString WXDLLIMPEXP_BASE operator+(const wxString& string1, const wxString& string2);
wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxChar ch);
wxString WXDLLIMPEXP_BASE operator+(wxChar ch, const wxString& string);
wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const wxChar *psz);
wxString WXDLLIMPEXP_BASE operator+(const wxChar *psz, const wxString& string);
-#endif // !wxUSE_STL
-
#if wxUSE_UNICODE
inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
{ return string + (const wchar_t *)buf; }
{ return (const char *)buf + string; }
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
+#endif // !wxUSE_STL
+
+// comparison with char (those are not defined by std::[w]string and so should
+// be always available)
+inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
+inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
+inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
+inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
+
// ---------------------------------------------------------------------------
// Implementation only from here until the end of file
// ---------------------------------------------------------------------------