X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/326a863afcf9272d00b12bbe4cea7a9d4e937384..9f728f8dba3da31745bb703bf6572df7f8dbb848:/include/wx/string.h diff --git a/include/wx/string.h b/include/wx/string.h index f08d162cad..20dd332550 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -24,6 +24,7 @@ #include "wx/defs.h" // everybody should include this +#ifndef __WXPALMOS5__ #if defined(__WXMAC__) || defined(__VISAGECPP__) #include #endif @@ -46,10 +47,7 @@ #ifdef HAVE_STRCASECMP_IN_STRINGS_H #include // for strcasecmp() #endif // HAVE_STRCASECMP_IN_STRINGS_H - -#ifdef __WXPALMOS__ - #include -#endif +#endif // ! __WXPALMOS5__ #include "wx/wxcrtbase.h" // for wxChar, wxStrlen() etc. #include "wx/strvararg.h" @@ -78,14 +76,6 @@ class WXDLLIMPEXP_FWD_BASE wxString; #define wxMBSTRINGCAST (char *)(const char *) #define wxWCSTRINGCAST (wchar_t *)(const wchar_t *) -// like _T(), but for literals in wxString's internal representation, i.e. -// char* in UTF-8 build and wxChar* otherwise: -#if wxUSE_UNICODE_UTF8 - #define wxSTRING_TEXT(str) str -#else - #define wxSTRING_TEXT(str) _T(str) -#endif - // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -133,8 +123,6 @@ inline int Stricmp(const char *psz1, const char *psz2) return _stricmp(psz1, psz2); #elif defined(__SC__) return _stricmp(psz1, psz2); -#elif defined(__SALFORDC__) - return stricmp(psz1, psz2); #elif defined(__BORLANDC__) return stricmp(psz1, psz2); #elif defined(__WATCOMC__) @@ -247,22 +235,12 @@ public: wxCStrData operator+(size_t n) const { return wxCStrData(m_str, m_offset + n, m_owned); } - // and these for "str.c_str() + n - 2": - wxCStrData operator-(int n) const - { - wxASSERT_MSG( n <= (int)m_offset, - _T("attempt to construct address before the beginning of the string") ); - return wxCStrData(m_str, m_offset - n, m_owned); - } - wxCStrData operator-(long n) const + // and these for "str.c_str() + (p2 - p1)" (it also works for any integer + // expression but it must be ptrdiff_t and not e.g. int to work in this + // example): + wxCStrData operator-(ptrdiff_t n) const { - wxASSERT_MSG( n <= (int)m_offset, - _T("attempt to construct address before the beginning of the string") ); - return wxCStrData(m_str, m_offset - n, m_owned); - } - wxCStrData operator-(size_t n) const - { - wxASSERT_MSG( n <= m_offset, + wxASSERT_MSG( n <= (ptrdiff_t)m_offset, _T("attempt to construct address before the beginning of the string") ); return wxCStrData(m_str, m_offset - n, m_owned); } @@ -453,7 +431,10 @@ private: size_t len; SubstrBufFromType(const T& data_, size_t len_) - : data(data_), len(len_) {} + : data(data_), len(len_) + { + wxASSERT_MSG( len != npos, "must have real length" ); + } }; #if wxUSE_UNICODE_UTF8 @@ -613,25 +594,15 @@ public: return tmp; \ } \ \ - iterator_name& operator+=(int n) \ + iterator_name& operator+=(ptrdiff_t n) \ { \ m_cur = wxStringOperations::AddToIter(m_cur, n); \ return *this; \ } \ - iterator_name& operator+=(size_t n) \ - { \ - m_cur = wxStringOperations::AddToIter(m_cur, (int)n); \ - return *this; \ - } \ - iterator_name& operator-=(int n) \ + iterator_name& operator-=(ptrdiff_t n) \ { \ m_cur = wxStringOperations::AddToIter(m_cur, -n); \ return *this; \ - } \ - iterator_name& operator-=(size_t n) \ - { \ - m_cur = wxStringOperations::AddToIter(m_cur, -(int)n); \ - return *this; \ } \ \ difference_type operator-(const iterator_name& i) const \ @@ -687,19 +658,22 @@ public: iterator(const iterator& i) : m_cur(i.m_cur), m_node(i.str(), &m_cur) {} iterator& operator=(const iterator& i) - { m_cur = i.m_cur; m_node.set(i.str(), &m_cur); return *this; } + { + if (&i != this) + { + m_cur = i.m_cur; + m_node.set(i.str(), &m_cur); + } + return *this; + } reference operator*() { return wxUniCharRef::CreateForString(m_node, m_cur); } - iterator operator+(int n) const + iterator operator+(ptrdiff_t n) const { return iterator(str(), wxStringOperations::AddToIter(m_cur, n)); } - iterator operator+(size_t n) const - { return iterator(str(), wxStringOperations::AddToIter(m_cur, (int)n)); } - iterator operator-(int n) const + iterator operator-(ptrdiff_t n) const { return iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); } - iterator operator-(size_t n) const - { return iterator(str(), wxStringOperations::AddToIter(m_cur, -(int)n)); } private: iterator(wxString *str, underlying_iterator ptr) @@ -726,21 +700,24 @@ public: : m_cur(i.m_cur), m_node(i.str(), &m_cur) {} const_iterator& operator=(const const_iterator& i) - { m_cur = i.m_cur; m_node.set(i.str(), &m_cur); return *this; } + { + if (&i != this) + { + m_cur = i.m_cur; + m_node.set(i.str(), &m_cur); + } + return *this; + } const_iterator& operator=(const iterator& i) { m_cur = i.m_cur; m_node.set(i.str(), &m_cur); return *this; } reference operator*() const { return wxStringOperations::DecodeChar(m_cur); } - const_iterator operator+(int n) const + const_iterator operator+(ptrdiff_t n) const { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, n)); } - const_iterator operator+(size_t n) const - { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, (int)n)); } - const_iterator operator-(int n) const + const_iterator operator-(ptrdiff_t n) const { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); } - const_iterator operator-(size_t n) const - { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, -(int)n)); } private: // for internal wxString use only: @@ -768,14 +745,10 @@ public: reference operator*() { return wxUniCharRef::CreateForString(m_cur); } - iterator operator+(int n) const + iterator operator+(ptrdiff_t n) const { return iterator(wxStringOperations::AddToIter(m_cur, n)); } - iterator operator+(size_t n) const - { return iterator(wxStringOperations::AddToIter(m_cur, (int)n)); } - iterator operator-(int n) const + iterator operator-(ptrdiff_t n) const { return iterator(wxStringOperations::AddToIter(m_cur, -n)); } - iterator operator-(size_t n) const - { return iterator(wxStringOperations::AddToIter(m_cur, -(int)n)); } private: // for internal wxString use only: @@ -799,14 +772,10 @@ public: reference operator*() const { return wxStringOperations::DecodeChar(m_cur); } - const_iterator operator+(int n) const + const_iterator operator+(ptrdiff_t n) const { return const_iterator(wxStringOperations::AddToIter(m_cur, n)); } - const_iterator operator+(size_t n) const - { return const_iterator(wxStringOperations::AddToIter(m_cur, (int)n)); } - const_iterator operator-(int n) const + const_iterator operator-(ptrdiff_t n) const { return const_iterator(wxStringOperations::AddToIter(m_cur, -n)); } - const_iterator operator-(size_t n) const - { return const_iterator(wxStringOperations::AddToIter(m_cur, -(int)n)); } private: // for internal wxString use only: @@ -854,21 +823,13 @@ public: { reverse_iterator_impl tmp = *this; ++m_cur; return tmp; } // NB: explicit in the functions below is to keep BCC 5.5 happy - reverse_iterator_impl operator+(int n) const - { return reverse_iterator_impl(m_cur - n); } - reverse_iterator_impl operator+(size_t n) const + reverse_iterator_impl operator+(ptrdiff_t n) const { return reverse_iterator_impl(m_cur - n); } - reverse_iterator_impl operator-(int n) const + reverse_iterator_impl operator-(ptrdiff_t n) const { return reverse_iterator_impl(m_cur + n); } - reverse_iterator_impl operator-(size_t n) const - { return reverse_iterator_impl(m_cur + n); } - reverse_iterator_impl operator+=(int n) - { m_cur -= n; return *this; } - reverse_iterator_impl operator+=(size_t n) + reverse_iterator_impl operator+=(ptrdiff_t n) { m_cur -= n; return *this; } - reverse_iterator_impl operator-=(int n) - { m_cur += n; return *this; } - reverse_iterator_impl operator-=(size_t n) + reverse_iterator_impl operator-=(ptrdiff_t n) { m_cur += n; return *this; } unsigned operator-(const reverse_iterator_impl& i) const @@ -934,7 +895,7 @@ public: wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { } // string containing nRepeat copies of ch - wxString(wxUniChar ch, size_t nRepeat = 1) + wxString(wxUniChar ch, size_t nRepeat = 1 ) { assign(nRepeat, ch); } wxString(size_t nRepeat, wxUniChar ch) { assign(nRepeat, ch); } @@ -992,8 +953,11 @@ public: wxString(const wxWCharBuffer& buf) { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length + // NB: this version uses m_impl.c_str() to force making a copy of the + // string, so that "wxString(str.c_str())" idiom for passing strings + // between threads works wxString(const wxCStrData& cstr) - : m_impl(cstr.AsString().m_impl) { } + : m_impl(cstr.AsString().m_impl.c_str()) { } // as we provide both ctors with this signature for both char and unsigned // char string, we need to provide one for wxCStrData to resolve ambiguity @@ -1053,6 +1017,13 @@ public: #endif #endif // wxUSE_STL + wxString Clone() const + { + // make a deep copy of the string, i.e. the returned string will have + // ref count = 1 with refcounted implementation + return wxString::FromImpl(wxStringImpl(m_impl.c_str(), m_impl.length())); + } + // first valid index position const_iterator begin() const { return const_iterator(this, m_impl.begin()); } iterator begin() { return iterator(this, m_impl.begin()); } @@ -1372,22 +1343,26 @@ public: #if wxUSE_WCHAR_T const wxWCharBuffer wc_str(const wxMBConv& conv = wxConvLibc) 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 + const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLibc ) ); } #endif // Unicode/ANSI // overloaded assignment // from another wxString wxString& operator=(const wxString& stringSrc) - { m_impl = stringSrc.m_impl; return *this; } + { if (&stringSrc != this) m_impl = stringSrc.m_impl; return *this; } wxString& operator=(const wxCStrData& cstr) { return *this = cstr.AsString(); } // from a character wxString& operator=(wxUniChar ch) - { m_impl = wxStringOperations::EncodeChar(ch); return *this; } + { +#if wxUSE_UNICODE_UTF8 + if ( !ch.IsAscii() ) + m_impl = wxStringOperations::EncodeChar(ch); + else +#endif + m_impl = (wxStringCharType)ch; + return *this; + } wxString& operator=(wxUniCharRef ch) { return operator=((wxUniChar)ch); } wxString& operator=(char ch) @@ -1477,6 +1452,16 @@ public: { append(psz); return *this; } wxString& Append(const wxWCharBuffer& psz) { append(psz); return *this; } + wxString& Append(const char* psz, size_t nLen) + { append(psz, nLen); return *this; } + wxString& Append(const wchar_t* pwz, size_t nLen) + { append(pwz, nLen); return *this; } + wxString& Append(const wxCStrData& psz, size_t nLen) + { append(psz, nLen); return *this; } + wxString& Append(const wxCharBuffer& psz, size_t nLen) + { append(psz, nLen); return *this; } + wxString& Append(const wxWCharBuffer& psz, size_t nLen) + { append(psz, nLen); return *this; } // append count copies of given character wxString& Append(wxUniChar ch, size_t count = 1u) { append(count, ch); return *this; } @@ -1488,10 +1473,6 @@ public: { append(count, ch); return *this; } wxString& Append(wchar_t ch, size_t count = 1u) { append(count, ch); return *this; } - wxString& Append(const char* psz, size_t nLen) - { append(psz, nLen); return *this; } - wxString& Append(const wchar_t* pwz, size_t nLen) - { append(pwz, nLen); return *this; } // prepend a string, return the string itself wxString& Prepend(const wxString& str) @@ -1566,14 +1547,23 @@ public: { return compare(s); } // same as Cmp() but not case-sensitive 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 wxString& str, bool compareWithCase = true) const - { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } + { +#if !wxUSE_UNICODE_UTF8 + // in UTF-8 build, length() is O(n) and doing this would be _slower_ + if ( length() != str.length() ) + return false; +#endif + return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; + } bool IsSameAs(const char *str, bool compareWithCase = true) const { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } bool IsSameAs(const wchar_t *str, bool compareWithCase = true) const { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } + bool IsSameAs(const wxCStrData& str, bool compareWithCase = true) const { return IsSameAs(str.AsString(), compareWithCase); } bool IsSameAs(const wxCharBuffer& str, bool compareWithCase = true) const @@ -1758,7 +1748,7 @@ public: // raw access to string memory // ensure that string has space for at least nLen characters // only works if the data of this string is not shared - bool Alloc(size_t nLen) { reserve(nLen); /*return capacity() >= nLen;*/ return true; } + bool Alloc(size_t nLen) { reserve(nLen); return capacity() >= nLen; } // minimize the string's memory // only works if the data of this string is not shared bool Shrink(); @@ -1876,7 +1866,7 @@ public: wxString& append(const wxString& str, size_t pos, size_t n) { size_t from, len; - PosLenToImpl(pos, n, &from, &len); + str.PosLenToImpl(pos, n, &from, &len); m_impl.append(str.m_impl, from, len); return *this; } @@ -1907,6 +1897,12 @@ public: { return append(str.data()); } wxString& append(const wxWCharBuffer& str) { return append(str.data()); } + wxString& append(const wxCStrData& str, size_t n) + { return append(str.AsString(), 0, n); } + wxString& append(const wxCharBuffer& str, size_t n) + { return append(str.data(), n); } + wxString& append(const wxWCharBuffer& str, size_t n) + { return append(str.data(), n); } // append n copies of ch wxString& append(size_t n, wxUniChar ch) @@ -1919,6 +1915,15 @@ public: m_impl.append(n, (wxStringCharType)ch); return *this; } + wxString& append(size_t n, wxUniCharRef ch) + { return append(n, wxUniChar(ch)); } + wxString& append(size_t n, char ch) + { return append(n, wxUniChar(ch)); } + wxString& append(size_t n, unsigned char ch) + { return append(n, wxUniChar(ch)); } + wxString& append(size_t n, wchar_t ch) + { return append(n, wxUniChar(ch)); } + // append from first to last wxString& append(const_iterator first, const_iterator last) { m_impl.append(first.impl(), last.impl()); return *this; } @@ -1943,7 +1948,7 @@ public: wxString& assign(const wxString& str, size_t pos, size_t n) { size_t from, len; - PosLenToImpl(pos, n, &from, &len); + str.PosLenToImpl(pos, n, &from, &len); m_impl.assign(str.m_impl, from, len); return *this; } @@ -2039,7 +2044,7 @@ public: wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n) { size_t from, len; - PosLenToImpl(nStart, n, &from, &len); + str.PosLenToImpl(nStart, n, &from, &len); m_impl.insert(PosToImpl(nPos), str.m_impl, from, len); return *this; } @@ -2169,7 +2174,7 @@ public: PosLenToImpl(nStart, nLen, &from, &len); size_t from2, len2; - PosLenToImpl(nStart2, nLen2, &from2, &len2); + str.PosLenToImpl(nStart2, nLen2, &from2, &len2); m_impl.replace(from, len, str.m_impl, from2, len2); return *this; @@ -2277,8 +2282,15 @@ public: // find the first occurence of character ch after nStart size_t find(wxUniChar ch, size_t nStart = 0) const { - return PosFromImpl(m_impl.find(wxStringOperations::EncodeChar(ch), - PosToImpl(nStart))); +#if wxUSE_UNICODE_UTF8 + if ( !ch.IsAscii() ) + return PosFromImpl(m_impl.find(wxStringOperations::EncodeChar(ch), + PosToImpl(nStart))); + else +#endif + return PosFromImpl(m_impl.find((wxStringCharType)ch, + PosToImpl(nStart))); + } size_t find(wxUniCharRef ch, size_t nStart = 0) const { return find(wxUniChar(ch), nStart); } @@ -2315,8 +2327,14 @@ public: // as find, but from the end size_t rfind(wxUniChar ch, size_t nStart = npos) const { - return PosFromImpl(m_impl.rfind(wxStringOperations::EncodeChar(ch), - PosToImpl(nStart))); +#if wxUSE_UNICODE_UTF8 + if ( !ch.IsAscii() ) + return PosFromImpl(m_impl.rfind(wxStringOperations::EncodeChar(ch), + PosToImpl(nStart))); + else +#endif + return PosFromImpl(m_impl.rfind((wxStringCharType)ch, + PosToImpl(nStart))); } size_t rfind(wxUniCharRef ch, size_t nStart = npos) const { return rfind(wxUniChar(ch), nStart); } @@ -2554,7 +2572,15 @@ public: { return operator+=(s.data()); } // string += char wxString& operator+=(wxUniChar ch) - { m_impl += wxStringOperations::EncodeChar(ch); return *this; } + { +#if wxUSE_UNICODE_UTF8 + if ( !ch.IsAscii() ) + m_impl += wxStringOperations::EncodeChar(ch); + else +#endif + m_impl += (wxStringCharType)ch; + return *this; + } wxString& operator+=(wxUniCharRef ch) { return *this += wxUniChar(ch); } wxString& operator+=(int ch) { return *this += wxUniChar(ch); } wxString& operator+=(char ch) { return *this += wxUniChar(ch); } @@ -2591,12 +2617,6 @@ private: private: wxStringImpl m_impl; -#ifdef __VISUALC__ - // "struct 'ConvertedBuffer' needs to have dll-interface to be used by - // clients of class 'wxString'" - this is private, we don't care - #pragma warning (disable:4251) -#endif - // buffers for compatibility conversion from (char*)c_str() and // (wchar_t*)c_str(): // FIXME-UTF8: bechmark various approaches to keeping compatibility buffers @@ -2625,10 +2645,6 @@ private: ConvertedBuffer m_convertedToWChar; #endif -#ifdef __VISUALC__ - #pragma warning (default:4251) -#endif - #if wxUSE_UNICODE_UTF8 // FIXME-UTF8: (try to) move this elsewhere (TLS) or solve differently // assigning to character pointer to by wxString::interator may @@ -2661,21 +2677,13 @@ private: // string iterator operators that satisfy STL Random Access Iterator // requirements: -inline wxString::iterator operator+(int n, wxString::iterator i) - { return i + n; } -inline wxString::iterator operator+(size_t n, wxString::iterator i) - { return i + n; } -inline wxString::const_iterator operator+(int n, wxString::const_iterator i) - { return i + n; } -inline wxString::const_iterator operator+(size_t n, wxString::const_iterator i) - { return i + n; } -inline wxString::reverse_iterator operator+(int n, wxString::reverse_iterator i) +inline wxString::iterator operator+(ptrdiff_t n, wxString::iterator i) { return i + n; } -inline wxString::reverse_iterator operator+(size_t n, wxString::reverse_iterator i) +inline wxString::const_iterator operator+(ptrdiff_t n, wxString::const_iterator i) { return i + n; } -inline wxString::const_reverse_iterator operator+(int n, wxString::const_reverse_iterator i) +inline wxString::reverse_iterator operator+(ptrdiff_t n, wxString::reverse_iterator i) { return i + n; } -inline wxString::const_reverse_iterator operator+(size_t n, wxString::const_reverse_iterator i) +inline wxString::const_reverse_iterator operator+(ptrdiff_t n, wxString::const_reverse_iterator i) { return i + n; } // notice that even though for many compilers the friend declarations above are @@ -2920,12 +2928,10 @@ wxDEFINE_ALL_COMPARISONS(const wxChar *, const wxString&, wxCMP_WXCHAR_STRING) #undef wxCMP_WXCHAR_STRING -// note that there is an optimization in operator==() and !=(): we (quickly) -// checks the strings length first, before comparing their data inline bool operator==(const wxString& s1, const wxString& s2) - { return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); } + { return s1.IsSameAs(s2); } inline bool operator!=(const wxString& s1, const wxString& s2) - { return (s1.Len() != s2.Len()) || (s1.Cmp(s2) != 0); } + { return !s1.IsSameAs(s2); } inline bool operator< (const wxString& s1, const wxString& s2) { return s1.Cmp(s2) < 0; } inline bool operator> (const wxString& s1, const wxString& s2)