+ // these methods are not implemented - there is _no_ conversion from int to
+ // string, you're doing something wrong if the compiler wants to call it!
+ //
+ // try `s << i' or `s.Printf("%d", i)' instead
+ wxString(int);
+
+
+ // buffer for holding temporary substring when using any of the methods
+ // that take (char*,size_t) or (wchar_t*,size_t) arguments:
+ // FIXME-UTF8: This will need changes when UTF8 build is introduced
+ template<typename T>
+ struct SubstrBufFromType
+ {
+ T data;
+ size_t len;
+
+ SubstrBufFromType() {}
+ SubstrBufFromType(const T& data_, size_t len_)
+ : data(data_), len(len_) {}
+ };
+
+#if wxUSE_UNICODE_UTF8
+ // FIXME-UTF8: this will have to use slightly different type
+#elif wxUSE_UNICODE_WCHAR
+ typedef SubstrBufFromType<const wchar_t*> SubstrBufFromWC;
+ typedef SubstrBufFromType<wxWCharBuffer> SubstrBufFromMB;
+ typedef SubstrBufFromWC SubstrBufFrom;
+#else
+ typedef SubstrBufFromType<const char*> SubstrBufFromMB;
+ typedef SubstrBufFromType<wxCharBuffer> SubstrBufFromWC;
+ typedef SubstrBufFromMB SubstrBufFrom;
+#endif
+
+
+ // Functions implementing primitive operations on string data; wxString
+ // methods and iterators are implemented in terms of it. The differences
+ // between UTF-8 and wchar_t* representations of the string are mostly
+ // contained here.
+
+#if wxUSE_UNICODE
+ // FIXME-UTF8: This will need changes when UTF8 build is introduced
+ static SubstrBufFromMB ConvertStr(const char *psz, size_t nLength,
+ const wxMBConv& conv);
+#else
+ static SubstrBufFromWC ConvertStr(const wchar_t *pwz, size_t nLength,
+ const wxMBConv& conv);
+#endif
+
+#if !wxUSE_UNICODE_UTF8 // wxUSE_UNICODE_WCHAR or !wxUSE_UNICODE
+ // returns C string encoded as the implementation expects (version for
+ // the same char type as used internally)
+ static const wxStringCharType* ImplStr(const wxStringCharType* str)
+ { return str; }
+ static const SubstrBufFrom ImplStr(const wxStringCharType* str, size_t n)
+ { return SubstrBufFrom(str, n); }
+ #if wxUSE_UNICODE
+ // returns C string encoded as the implementation expects (version for
+ // the other char type than the one used internally)
+ static wxWCharBuffer ImplStr(const char* str)
+ { return ConvertStr(str, npos, wxConvLibc).data; }
+ static SubstrBufFromMB ImplStr(const char* str, size_t n)
+ { return ConvertStr(str, n, wxConvLibc); }
+ #else
+ static wxCharBuffer ImplStr(const wchar_t* str)
+ { return ConvertStr(str, npos, wxConvLibc).data; }
+ static SubstrBufFromWC ImplStr(const wchar_t* str, size_t n)
+ { return ConvertStr(str, n, wxConvLibc); }
+ #endif
+
+ // moves the iterator to the next Unicode character
+ static void IncIter(wxStringImpl::iterator& i) { ++i; }
+ static void IncIter(wxStringImpl::const_iterator& i) { ++i; }
+ // moves the iterator to the previous Unicode character
+ static void DecIter(wxStringImpl::iterator& i) { --i; }
+ static void DecIter(wxStringImpl::const_iterator& i) { --i; }
+ // moves the iterator by n Unicode characters
+ static wxStringImpl::iterator AddToIter(wxStringImpl::iterator i, int n)
+ { return i + n; }
+ static wxStringImpl::const_iterator AddToIter(wxStringImpl::const_iterator i, int n)
+ { return i + n; }
+ // returns distance of the two iterators in Unicode characters
+ static int DiffIters(wxStringImpl::iterator i1, wxStringImpl::iterator i2)
+ { return i1 - i2; }
+ static int DiffIters(wxStringImpl::const_iterator i1, wxStringImpl::const_iterator i2)
+ { return i1 - i2; }
+
+ // encodes the character to a form used to represent it in internal
+ // representation (returns a string in UTF8 version)
+ static wxChar EncodeChar(wxUniChar ch) { return (wxChar)ch; }
+
+ // translates position index in wxString to/from index in underlying
+ // wxStringImpl:
+ static size_t PosToImpl(size_t pos) { return pos; }
+ static void PosLenToImpl(size_t pos, size_t len,
+ size_t *implPos, size_t *implLen)
+ { *implPos = pos; *implLen = len; }
+ static size_t PosFromImpl(size_t pos) { return pos; }
+
+#else // wxUSE_UNICODE_UTF8
+
+ typedef char Utf8CharBuffer[5];
+ static Utf8CharBuffer EncodeChar(wxUniChar ch);
+ // returns n copies of ch encoded in UTF-8 string
+ static wxCharBuffer EncodeNChars(size_t n, wxUniChar ch);
+
+ size_t PosToImpl(size_t pos) const
+ {
+ if ( pos == 0 || pos == npos )
+ return pos;
+ else
+ return wxStringImpl::const_iterator(begin() + pos) - m_impl.begin();
+ }
+
+ size_t PosFromImpl(size_t pos) const
+ {
+ if ( pos == 0 || pos == npos )
+ return pos;
+ else
+ return const_iterator(m_impl.begin() + pos) - begin();
+ }
+
+ // FIXME: return as-is without copying under UTF8 locale, return
+ // converted string under other locales - needs wxCharBuffer
+ // changes
+ static wxCharBuffer ImplStr(const char* str);
+
+ static wxCharBuffer ImplStr(const wchar_t* str)
+ { return wxConvUTF8.cWC2MB(str); }
+#endif // !wxUSE_UNICODE_UTF8/wxUSE_UNICODE_UTF8
+
+
+public:
+ // constructors and destructor
+ // ctor for an empty string
+ wxString() {}
+ // copy ctor
+ wxString(const wxStringImpl& stringSrc) : m_impl(stringSrc) { }
+ wxString(const wxString& stringSrc) : m_impl(stringSrc) { }
+ // string containing nRepeat copies of ch
+ wxString(wxUniChar ch, size_t nRepeat = 1)
+ : m_impl(nRepeat, ch) { }
+ wxString(size_t nRepeat, wxUniChar ch)
+ : m_impl(nRepeat, ch) { }
+ wxString(wxUniCharRef ch, size_t nRepeat = 1)
+ : m_impl(nRepeat, ch) { }
+ wxString(size_t nRepeat, wxUniCharRef ch)
+ : m_impl(nRepeat, ch) { }
+ wxString(char ch, size_t nRepeat = 1)
+ : m_impl(nRepeat, ch) { }
+ wxString(size_t nRepeat, char ch)
+ : m_impl(nRepeat, ch) { }
+ wxString(wchar_t ch, size_t nRepeat = 1)
+ : m_impl(nRepeat, ch) { }
+ wxString(size_t nRepeat, wchar_t ch)
+ : m_impl(nRepeat, ch) { }
+ // ctor takes first nLength characters from C string
+ // (default value of npos means take all the string)
+ wxString(const wxChar *psz)
+ : m_impl(psz ? psz : wxT("")) { }
+ wxString(const wxChar *psz, size_t nLength)
+ : m_impl(psz, nLength) { }
+ wxString(const wxChar *psz,
+ const wxMBConv& WXUNUSED(conv),
+ size_t nLength = npos)
+ : m_impl(psz, nLength == npos ? wxStrlen(psz) : nLength) { }
+
+ // even if we're not built with wxUSE_STL == 1 it is very convenient to allow
+ // implicit conversions from std::string to wxString as this allows to use
+ // the same strings in non-GUI and GUI code, however we don't want to
+ // unconditionally add this ctor as it would make wx lib dependent on
+ // libstdc++ on some Linux versions which is bad, so instead we ask the
+ // client code to define this wxUSE_STD_STRING symbol if they need it
+#if wxUSE_STD_STRING
+ wxString(const wxStdString& s)
+ : m_impl(s.c_str()) { }
+#endif // wxUSE_STD_STRING
+
+#if wxUSE_UNICODE
+ // from multibyte string
+ wxString(const char *psz,
+ const wxMBConv& conv = wxConvLibc,
+ size_t nLength = npos);
+ // from multibyte string for ANSI compatibility, with wxConvLibc
+ wxString(const char *psz, size_t nLength);
+ // from wxWCharBuffer (i.e. return from wxGetString)
+ wxString(const wxWCharBuffer& psz) : m_impl(psz.data()) { }
+#else // ANSI
+ // from C string (for compilers using unsigned char)
+ wxString(const unsigned char* psz)
+ : m_impl((const char*)psz) { }
+ // from part of C string (for compilers using unsigned char)
+ wxString(const unsigned char* psz, size_t nLength)
+ : m_impl((const char*)psz, nLength) { }
+
+#if wxUSE_WCHAR_T
+ // from wide (Unicode) string
+ wxString(const wchar_t *pwz,
+ const wxMBConv& conv = wxConvLibc,
+ size_t nLength = npos);
+ // from wide string for Unicode compatibility, with wxConvLibc
+ wxString(const wchar_t *pwz, size_t nLength);
+#endif // !wxUSE_WCHAR_T
+
+ // from wxCharBuffer
+ wxString(const wxCharBuffer& psz)
+ : m_impl(psz) { }
+#endif // Unicode/ANSI
+
+ // 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
+ wxString(const wxCStrData& cstr, size_t nLength)
+ { assign(cstr.AsString(), nLength); }
+
+ // and because wxString is convertible to wxCStrData and const wxChar *
+ // we also need to provide this one
+ wxString(const wxString& str, size_t nLength)
+ { assign(str, nLength); }
+
+public:
+ // standard types
+ typedef wxUniChar value_type;
+ typedef wxUniChar char_type;
+ typedef wxUniCharRef reference;
+ typedef wxChar* pointer;
+ typedef const wxChar* const_pointer;
+
+ typedef size_t size_type;
+ typedef wxUniChar const_reference;
+
+ #define WX_STR_ITERATOR_IMPL(iterator_name, pointer_type, \
+ reference_type, reference_ctor) \
+ private: \
+ typedef wxStringImpl::iterator_name underlying_iterator; \
+ public: \
+ typedef wxUniChar value_type; \
+ typedef reference_type reference; \
+ typedef pointer_type pointer; \
+ \
+ iterator_name(const iterator_name& i) : m_cur(i.m_cur) {} \
+ \
+ reference operator*() const { return reference_ctor; } \
+ \
+ iterator_name& operator++() \
+ { wxString::IncIter(m_cur); return *this; } \
+ iterator_name& operator--() \
+ { wxString::DecIter(m_cur); return *this; } \
+ iterator_name operator++(int) \
+ { \
+ iterator_name tmp = *this; \
+ wxString::IncIter(m_cur); \
+ return tmp; \
+ } \
+ iterator_name operator--(int) \
+ { \
+ iterator_name tmp = *this; \
+ wxString::DecIter(m_cur); \
+ return tmp; \
+ } \
+ \
+ iterator_name operator+(int n) const \
+ { return iterator_name(wxString::AddToIter(m_cur, n)); } \
+ iterator_name operator+(size_t n) const \
+ { return iterator_name(wxString::AddToIter(m_cur, (int)n)); } \
+ iterator_name operator-(int n) const \
+ { return iterator_name(wxString::AddToIter(m_cur, -n)); } \
+ iterator_name operator-(size_t n) const \
+ { return iterator_name(wxString::AddToIter(m_cur, -(int)n)); } \
+ iterator_name operator+=(int n) \
+ { m_cur = wxString::AddToIter(m_cur, n); return *this; } \
+ iterator_name operator+=(size_t n) \
+ { m_cur = wxString::AddToIter(m_cur, (int)n); return *this; } \
+ iterator_name operator-=(int n) \
+ { m_cur = wxString::AddToIter(m_cur, -n); return *this; } \
+ iterator_name operator-=(size_t n) \
+ { m_cur = wxString::AddToIter(m_cur, -(int)n); return *this; } \
+ \
+ unsigned operator-(const iterator_name& i) const \
+ { return wxString::DiffIters(m_cur, i.m_cur); } \
+ \
+ bool operator==(const iterator_name&i) const \
+ { return m_cur == i.m_cur; } \
+ bool operator!=(const iterator_name& i) const \
+ { return m_cur != i.m_cur; } \
+ \
+ bool operator<(const iterator_name& i) const \
+ { return m_cur < i.m_cur; } \
+ bool operator>(const iterator_name& i) const \
+ { return m_cur > i.m_cur; } \
+ bool operator<=(const iterator_name& i) const \
+ { return m_cur <= i.m_cur; } \
+ bool operator>=(const iterator_name& i) const \
+ { return m_cur >= i.m_cur; } \
+ \
+ private: \
+ /* for internal wxString use only: */ \
+ iterator_name(underlying_iterator ptr) : m_cur(ptr) {} \
+ operator underlying_iterator() const { return m_cur; } \
+ \
+ friend class WXDLLIMPEXP_BASE wxString; \
+ friend class WXDLLIMPEXP_BASE wxStringImpl; \
+ friend class WXDLLIMPEXP_BASE wxCStrData; \
+ \
+ private: \
+ underlying_iterator m_cur;
+
+ class const_iterator;
+
+ class iterator
+ {
+ WX_STR_ITERATOR_IMPL(iterator, wxChar*, wxUniCharRef,
+ wxUniCharRef::CreateForString(m_cur))
+
+ 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,
+ wxUniChar(*m_cur))
+
+ public:
+ const_iterator(const iterator& i) : m_cur(i.m_cur) {}
+ };
+
+ #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::value_type value_type;
+ typedef typename T::reference reference;
+ typedef typename T::pointer *pointer;
+
+ 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); }
+
+ 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; }
+
+ reverse_iterator_impl operator+(int 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) 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)
+ { 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;
+ };