#pragma warning (disable:4275)
#endif
-#if wxUSE_UNICODE_UTF8
-// see the comment near wxString::iterator for why we need this
-struct WXDLLIMPEXP_BASE wxStringIteratorNode
-{
- inline wxStringIteratorNode(const wxString *str,
- wxStringImpl::const_iterator *citer);
- inline wxStringIteratorNode(const wxString *str,
- wxStringImpl::iterator *iter);
- inline ~wxStringIteratorNode();
-
- const wxString *m_str;
- wxStringImpl::const_iterator *m_citer;
- wxStringImpl::iterator *m_iter;
- wxStringIteratorNode *m_prev, *m_next;
-};
-#endif // wxUSE_UNICODE_UTF8
-
class WXDLLIMPEXP_BASE wxString
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
: public wxStringPrintfMixin
if ( pos == 0 || pos == npos )
return pos;
else
- return const_iterator(this, m_impl.begin() + pos) - begin();
+ return const_iterator(m_impl.begin() + pos) - begin();
}
#endif // !wxUSE_UNICODE_UTF8/wxUSE_UNICODE_UTF8
#define WX_STR_ITERATOR_TAG void /* dummy type */
#endif
- #define WX_STR_ITERATOR_IMPL(iterator_name, pointer_type, reference_type) \
+ #define WX_STR_ITERATOR_IMPL(iterator_name, pointer_type, \
+ reference_type, reference_ctor) \
private: \
typedef wxStringImpl::iterator_name underlying_iterator; \
public: \
typedef reference_type reference; \
typedef pointer_type pointer; \
\
+ reference operator*() const { return reference_ctor; } \
reference operator[](size_t n) const { return *(*this + n); } \
\
iterator_name& operator++() \
class const_iterator;
#if wxUSE_UNICODE_UTF8
- // NB: In UTF-8 build, (non-const) iterator needs to keep reference
- // to the underlying wxStringImpl, because UTF-8 is variable-length
- // encoding and changing the value pointer to by an iterator (using
- // its operator*) requires calling wxStringImpl::replace() if the old
- // and new values differ in their encoding's length.
- //
- // Furthermore, the replace() call may invalid all iterators for the
- // string, so we have to keep track of outstanding iterators and update
- // them if it happens.
-
class iterator
{
- WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef);
+ // NB: In UTF-8 build, (non-const) iterator needs to keep reference
+ // to the underlying wxStringImpl, because UTF-8 is variable-length
+ // encoding and changing the value pointer to by an iterator using
+ // its operator* requires calling wxStringImpl::replace() if the old
+ // and new values differ in their encoding's length.
- public:
- iterator(const iterator& i)
- : m_cur(i.m_cur), m_node(i.str(), &m_cur) {}
+ WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef,
+ wxUniCharRef::CreateForString(m_str, m_cur));
- reference operator*()
- { return wxUniCharRef::CreateForString(m_node, m_cur); }
+ public:
+ iterator(const iterator& i) : m_cur(i.m_cur), m_str(i.m_str) {}
iterator operator+(int n) const
- { return iterator(str(), wxStringOperations::AddToIter(m_cur, n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, n)); }
iterator operator+(size_t n) const
- { return iterator(str(), wxStringOperations::AddToIter(m_cur, (int)n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, (int)n)); }
iterator operator-(int n) const
- { return iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, -n)); }
iterator operator-(size_t n) const
- { return iterator(str(), wxStringOperations::AddToIter(m_cur, -(int)n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, -(int)n)); }
private:
iterator(wxString *str, underlying_iterator ptr)
- : m_cur(ptr), m_node(str, &m_cur) {}
- iterator(wxString& str, underlying_iterator ptr)
- : m_cur(ptr), m_node(&str, &m_cur) {}
-
- wxString* str() const { return wx_const_cast(wxString*, m_node.m_str); }
+ : m_cur(ptr), m_str(str->m_impl) {}
+ iterator(wxStringImpl& str, underlying_iterator ptr)
+ : m_cur(ptr), m_str(str) {}
- wxStringIteratorNode m_node;
+ wxStringImpl& m_str;
friend class const_iterator;
};
- class const_iterator
- {
- // NB: reference_type is intentionally value, not reference, the character
- // may be encoded differently in wxString data:
- WX_STR_ITERATOR_IMPL(const_iterator, const wxChar*, wxUniChar);
-
- public:
- const_iterator(const const_iterator& i)
- : m_cur(i.m_cur), m_node(i.str(), &m_cur) {}
- const_iterator(const iterator& i)
- : m_cur(i.m_cur), m_node(i.str(), &m_cur) {}
-
- reference operator*() const
- { return wxStringOperations::DecodeChar(m_cur); }
-
- const_iterator operator+(int 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
- { 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:
- const_iterator(const wxString *str, underlying_iterator ptr)
- : m_cur(ptr), m_node(str, &m_cur) {}
- const_iterator(const wxString& str, underlying_iterator ptr)
- : m_cur(ptr), m_node(&str, &m_cur) {}
-
- const wxString* str() const { return m_node.m_str; }
-
- wxStringIteratorNode m_node;
- };
-
size_t IterToImplPos(wxString::iterator i) const
{ return wxStringImpl::const_iterator(i.impl()) - m_impl.begin(); }
class iterator
{
- WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef);
+ WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef,
+ wxUniCharRef::CreateForString(m_cur));
public:
iterator(const iterator& i) : m_cur(i.m_cur) {}
- reference operator*()
- { return wxUniCharRef::CreateForString(m_cur); }
-
iterator operator+(int n) const
{ return iterator(wxStringOperations::AddToIter(m_cur, n)); }
iterator operator+(size_t n) const
friend class const_iterator;
};
+#endif // wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8
class const_iterator
{
// NB: reference_type is intentionally value, not reference, the character
// may be encoded differently in wxString data:
- WX_STR_ITERATOR_IMPL(const_iterator, const wxChar*, wxUniChar);
+ WX_STR_ITERATOR_IMPL(const_iterator, const wxChar*, wxUniChar,
+ wxStringOperations::DecodeChar(m_cur));
public:
const_iterator(const const_iterator& i) : m_cur(i.m_cur) {}
const_iterator(const iterator& i) : m_cur(i.m_cur) {}
- reference operator*() const
- { return wxStringOperations::DecodeChar(m_cur); }
-
const_iterator operator+(int n) const
{ return const_iterator(wxStringOperations::AddToIter(m_cur, n)); }
const_iterator operator+(size_t n) const
private:
// for internal wxString use only:
const_iterator(underlying_iterator ptr) : m_cur(ptr) {}
- const_iterator(const wxString *WXUNUSED(str), underlying_iterator ptr)
- : m_cur(ptr) {}
};
-#endif // wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8
#undef WX_STR_ITERATOR_TAG
#undef WX_STR_ITERATOR_IMPL
// wxCStrData) to an iterator into the string
static const_iterator CreateConstIterator(const wxCStrData& data)
{
- return const_iterator(data.m_str,
- (data.m_str->begin() + data.m_offset).impl());
+ return const_iterator(data.m_str->begin() + data.m_offset);
}
// in UTF-8 STL build, creation from std::string requires conversion under
wxString(const std::string& str)
{ assign(str.c_str(), str.length()); }
#endif
-#endif // wxUSE_STD_STRING
- // Unlike ctor from std::string, we provide conversion to std::string only
- // if wxUSE_STL and not merely wxUSE_STD_STRING (which is on by default),
- // because it conflicts with operator const char/wchar_t*:
-#if wxUSE_STL
#if wxUSE_UNICODE_WCHAR && wxUSE_STL_BASED_WXSTRING
// wxStringImpl is std::string in the encoding we want
operator const wxStdWideString&() const { return m_impl; }
#endif // wxUSE_STL
// first valid index position
- const_iterator begin() const { return const_iterator(this, m_impl.begin()); }
+ const_iterator begin() const { return const_iterator(m_impl.begin()); }
iterator begin() { return iterator(this, m_impl.begin()); }
// position one after the last valid one
- const_iterator end() const { return const_iterator(this, m_impl.end()); }
+ const_iterator end() const { return const_iterator(m_impl.end()); }
iterator end() { return iterator(this, m_impl.end()); }
// first element of the reversed string
// implicit conversion to C string
operator wxCStrData() const { return c_str(); }
-
- // these operators conflict with operators for conversion to std::string,
- // so they must be disabled in STL build:
-#if !wxUSE_STL
operator const char*() const { return c_str(); }
operator const wchar_t*() const { return c_str(); }
-#endif
// implicit conversion to untyped pointer for compatibility with previous
// wxWidgets versions: this is the same as conversion to const char * so it
const wxStringCharType *wx_str() const { return m_impl.c_str(); }
// conversion to *non-const* multibyte or widestring buffer; modifying
- // returned buffer may or may not affect the string, these methods are only
- // useful for passing values to const-incorrect functions
+ // returned buffer won't affect the string, these methods are only useful
+ // for passing values to const-incorrect functions
wxWritableCharBuffer char_str(const wxMBConv& conv = wxConvLibc) const
- {
-#if wxUSE_UNICODE
- return mb_str(conv);
-#else
- return wxWritableCharBuffer::CreateNonOwned(mb_str(conv));
-#endif
- }
- wxWritableWCharBuffer wchar_str() const
- {
-#if wxUSE_UNICODE_WCHAR
- return wxWritableWCharBuffer::CreateNonOwned(wc_str());
-#else
- return wc_str();
-#endif
- }
+ { return mb_str(conv); }
+ wxWritableWCharBuffer wchar_str() const { return wc_str(); }
// conversion to/from plain (i.e. 7 bit) ASCII: this is useful for
// converting numbers or strings which are certain not to contain special
ConvertedBuffer<wchar_t> m_convertedToWChar;
#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
- // change the underlying wxStringImpl iterator, so we have to
- // keep track of all iterators and update them as necessary:
- struct wxStringIteratorNodeHead
- {
- wxStringIteratorNodeHead() : ptr(NULL) {}
- wxStringIteratorNode *ptr;
- };
-
- wxStringIteratorNodeHead m_iterators;
-
- friend class WXDLLIMPEXP_BASE wxStringIteratorNode;
- friend class WXDLLIMPEXP_BASE wxUniCharRef;
-#endif // wxUSE_UNICODE_UTF8
-
friend class WXDLLIMPEXP_BASE wxCStrData;
friend class wxImplStringBuffer;
friend class wxImplStringBufferLength;
{
}
-#if wxUSE_UNICODE_UTF8
-// ----------------------------------------------------------------------------
-// implementation of wxStringIteratorNode inline methods
-// ----------------------------------------------------------------------------
-
-wxStringIteratorNode::wxStringIteratorNode(const wxString *str,
- wxStringImpl::const_iterator *citer)
- : m_str(str),
- m_citer(citer),
- m_iter(NULL),
- m_prev(NULL),
- m_next(str->m_iterators.ptr)
-{
- wx_const_cast(wxString*, m_str)->m_iterators.ptr = this;
- if ( m_next )
- m_next->m_prev = this;
-}
-
-wxStringIteratorNode::wxStringIteratorNode(const wxString *str,
- wxStringImpl::iterator *iter)
- : m_str(str),
- m_citer(NULL),
- m_iter(iter),
- m_prev(NULL),
- m_next(str->m_iterators.ptr)
-{
- wx_const_cast(wxString*, m_str)->m_iterators.ptr = this;
- if ( m_next)
- m_next->m_prev = this;
-}
-
-wxStringIteratorNode::~wxStringIteratorNode()
-{
- if ( m_next )
- m_next->m_prev = m_prev;
- if ( m_prev )
- m_prev->m_next = m_next;
- else // first in the list
- wx_const_cast(wxString*, m_str)->m_iterators.ptr = m_next;
-}
-#endif // wxUSE_UNICODE_UTF8
-
#if WXWIN_COMPATIBILITY_2_8
// lot of code out there doesn't explicitly include wx/wxchar.h, but uses
// CRT wrappers that are now declared in wx/wxcrt.h and wx/wxcrtvararg.h,