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); }
: 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; }
// 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)
{ 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
// 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); }
// 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); }
{ 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); }
#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)