+// ----------------------------------------------------------------------------
+// wxCStrData
+// ----------------------------------------------------------------------------
+
+// Lightweight object returned by wxString::c_str() and implicitly convertible
+// to either const char* or const wchar_t*.
+class WXDLLIMPEXP_BASE wxCStrData
+{
+private:
+ // Ctors; for internal use by wxString and wxCStrData only
+ wxCStrData(const wxString *str, size_t offset = 0, bool owned = false)
+ : m_str(str), m_offset(offset), m_owned(owned) {}
+
+public:
+ // Ctor constructs the object from char literal; they are needed to make
+ // operator?: compile and they intentionally take char*, not const char*
+ wxCStrData(char *buf);
+ wxCStrData(wchar_t *buf);
+
+ ~wxCStrData();
+
+ // FIXME: we'll need convertors for both char* and wchar_t* and NONE
+ // for wxChar*, but that's after completing the transition to
+ // "smart" wxUniChar class. For now, just have conversion to
+ // char* in ANSI build and wchar_t in Unicode build.
+#if wxUSE_UNICODE
+ const wchar_t* AsWChar() const;
+ operator const wchar_t*() const { return AsWChar(); }
+#else
+ const char* AsChar() const;
+ operator const char*() const { return AsChar(); }
+#endif
+
+ wxString AsString() const;
+ operator wxString() const;
+
+ // allow expressions like "c_str()[0]":
+ wxUniChar operator[](int n) const { return operator[](size_t(n)); }
+ wxUniChar operator[](size_t n) const;
+ wxUniChar operator[](long n) const { return operator[](size_t(n)); }
+#ifndef wxSIZE_T_IS_UINT
+ wxUniChar operator[](unsigned int n) const { return operator[](size_t(n)); }
+#endif // size_t != unsigned int
+
+ // these operators are needed to emulate the pointer semantics of c_str():
+ // expressions like "wxChar *p = str.c_str() + 1;" should continue to work
+ // (we need both versions to resolve ambiguities):
+ wxCStrData operator+(int n) const
+ { return wxCStrData(m_str, m_offset + n, m_owned); }
+ wxCStrData operator+(long n) const
+ { return wxCStrData(m_str, m_offset + n, m_owned); }
+ wxCStrData operator+(size_t n) const
+ { return wxCStrData(m_str, m_offset + n, m_owned); }
+
+ // this operator is need to make expressions like "*c_str()" or
+ // "*(c_str() + 2)" work
+ wxUniChar operator*() const;
+
+private:
+ const wxString *m_str;
+ size_t m_offset;
+ bool m_owned;
+
+ friend class WXDLLIMPEXP_BASE wxString;
+};
+
+// ----------------------------------------------------------------------------
+// wxStringPrintfMixin
+// ---------------------------------------------------------------------------
+
+// NB: VC6 has a bug that causes linker errors if you have template methods
+// in a class using __declspec(dllimport). The solution is to split such
+// class into two classes, one that contains the template methods and does
+// *not* use WXDLLIMPEXP_BASE and another class that contains the rest
+// (with DLL linkage).
+//
+// We only do this for VC6 here, because the code is less efficient
+// (Printf() has to use dynamic_cast<>) and because OpenWatcom compiler
+// cannot compile this code.
+
+#if defined(__VISUALC__) && __VISUALC__ < 1300
+ #define wxNEEDS_WXSTRING_PRINTF_MIXIN
+#endif
+
+#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
+// this class contains implementation of wxString's vararg methods, it's
+// exported from wxBase DLL
+class WXDLLIMPEXP_BASE wxStringPrintfMixinBase
+{
+protected:
+ wxStringPrintfMixinBase() {}
+
+ int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
+ static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
+};
+
+// this class contains template wrappers for wxString's vararg methods, it's
+// intentionally *not* exported from the DLL in order to fix the VC6 bug
+// described above
+class wxStringPrintfMixin : public wxStringPrintfMixinBase
+{
+private:
+ // to further complicate things, we can't return wxString from
+ // wxStringPrintfMixin::Format() because wxString is not yet declared at
+ // this point; the solution is to use this fake type trait template - this
+ // way the compiler won't know the return type until Format() is used
+ // (this doesn't compile with Watcom, but VC6 compiles it just fine):
+ template<typename T> struct StringReturnType
+ {
+ typedef wxString type;
+ };
+
+public:
+ // these are duplicated wxString methods, they're also declared below
+ // if !wxNEEDS_WXSTRING_PRINTF_MIXIN:
+
+ // int Printf(const wxChar *pszFormat, ...);
+ WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
+ // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
+ WX_DEFINE_VARARG_FUNC(static typename StringReturnType<T1>::type,
+ Format, DoFormat)
+ // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
+ WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
+
+protected:
+ wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
+};
+#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
+
+