+ // Furthermore, the replace() call may invalid all iterators for the
+ // string, so we have to keep track of outstanding iterators and update
+ // them if replace() happens.
+ //
+ // This is implemented by maintaining linked list of iterators for every
+ // string and traversing it in wxUniCharRef::operator=(). Head of the
+ // list is stored in wxString. (FIXME-UTF8)
+
+ class WXDLLIMPEXP_BASE iterator
+ {
+ WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef);
+
+ public:
+ iterator() {}
+ 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; }
+
+ reference operator*()
+ { return wxUniCharRef::CreateForString(m_node, m_cur); }
+
+ iterator operator+(int 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
+ { 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)
+ : m_cur(ptr), m_node(str, &m_cur) {}
+
+ wxString* str() const { return wx_const_cast(wxString*, m_node.m_str); }
+
+ wxStringIteratorNode m_node;
+
+ friend class const_iterator;
+ };
+
+ class WXDLLIMPEXP_BASE 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_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) {}
+
+ const_iterator& operator=(const const_iterator& i)
+ { 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
+ { 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 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(); }
+
+#else // !wxUSE_UNICODE_UTF8
+
+ class WXDLLIMPEXP_BASE iterator
+ {
+ WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef);
+
+ public:
+ iterator() {}
+ 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
+ { return iterator(wxStringOperations::AddToIter(m_cur, (int)n)); }
+ iterator operator-(int 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:
+ iterator(underlying_iterator ptr) : m_cur(ptr) {}
+ iterator(wxString *WXUNUSED(str), underlying_iterator ptr) : m_cur(ptr) {}
+
+ friend class const_iterator;
+ };
+
+ class WXDLLIMPEXP_BASE 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_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
+ { return const_iterator(wxStringOperations::AddToIter(m_cur, (int)n)); }
+ const_iterator operator-(int 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:
+ 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
+
+ friend class iterator;
+ friend class const_iterator;
+
+ template <typename T>
+ class reverse_iterator_impl
+ {
+ public:
+ typedef T iterator_type;
+
+ typedef typename T::iterator_category iterator_category;
+ typedef typename T::value_type value_type;
+ typedef typename T::difference_type difference_type;
+ typedef typename T::reference reference;
+ typedef typename T::pointer *pointer;
+
+ reverse_iterator_impl() {}
+ reverse_iterator_impl(iterator_type i) : m_cur(i) {}
+ reverse_iterator_impl(const reverse_iterator_impl& ri)
+ : m_cur(ri.m_cur) {}
+
+ iterator_type base() const { return m_cur; }
+
+ reference operator*() const { return *(m_cur-1); }
+ reference operator[](size_t n) const { return *(*this + n); }
+
+ reverse_iterator_impl& operator++()
+ { --m_cur; return *this; }
+ reverse_iterator_impl operator++(int)
+ { reverse_iterator_impl tmp = *this; --m_cur; return tmp; }
+ reverse_iterator_impl& operator--()
+ { ++m_cur; return *this; }
+ reverse_iterator_impl operator--(int)
+ { reverse_iterator_impl tmp = *this; ++m_cur; return tmp; }
+
+ // NB: explicit <T> in the functions below is to keep BCC 5.5 happy
+ reverse_iterator_impl operator+(int n) const
+ { return reverse_iterator_impl<T>(m_cur - n); }
+ reverse_iterator_impl operator+(size_t n) const
+ { return reverse_iterator_impl<T>(m_cur - n); }
+ reverse_iterator_impl operator-(int n) const
+ { return reverse_iterator_impl<T>(m_cur + n); }
+ reverse_iterator_impl operator-(size_t n) const
+ { return reverse_iterator_impl<T>(m_cur + n); }
+ reverse_iterator_impl operator+=(int n)
+ { m_cur -= n; return *this; }
+ reverse_iterator_impl operator+=(size_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)
+ { m_cur += n; return *this; }
+
+ unsigned operator-(const reverse_iterator_impl& i) const
+ { return i.m_cur - m_cur; }
+
+ bool operator==(const reverse_iterator_impl& ri) const
+ { return m_cur == ri.m_cur; }
+ bool operator!=(const reverse_iterator_impl& ri) const
+ { return !(*this == ri); }
+
+ bool operator<(const reverse_iterator_impl& i) const
+ { return m_cur > i.m_cur; }
+ bool operator>(const reverse_iterator_impl& i) const
+ { return m_cur < i.m_cur; }
+ bool operator<=(const reverse_iterator_impl& i) const
+ { return m_cur >= i.m_cur; }
+ bool operator>=(const reverse_iterator_impl& i) const
+ { return m_cur <= i.m_cur; }
+
+ private:
+ iterator_type m_cur;
+ };
+
+ typedef reverse_iterator_impl<iterator> reverse_iterator;
+ typedef reverse_iterator_impl<const_iterator> const_reverse_iterator;
+
+private:
+ // used to transform an expression built using c_str() (and hence of type
+ // 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());
+ }
+
+ // in UTF-8 STL build, creation from std::string requires conversion under
+ // non-UTF8 locales, so we can't have and use wxString(wxStringImpl) ctor;
+ // instead we define dummy type that lets us have wxString ctor for creation
+ // from wxStringImpl that couldn't be used by user code (in all other builds,
+ // "standard" ctors can be used):
+#if wxUSE_UNICODE_UTF8 && wxUSE_STL_BASED_WXSTRING
+ struct CtorFromStringImplTag {};
+
+ wxString(CtorFromStringImplTag* WXUNUSED(dummy), const wxStringImpl& src)
+ : m_impl(src) {}
+
+ static wxString FromImpl(const wxStringImpl& src)
+ { return wxString((CtorFromStringImplTag*)NULL, src); }
+#else
+ #if !wxUSE_STL_BASED_WXSTRING
+ wxString(const wxStringImpl& src) : m_impl(src) { }
+ // else: already defined as wxString(wxStdString) below
+ #endif
+ static wxString FromImpl(const wxStringImpl& src) { return wxString(src); }
+#endif