X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d1f6e2cfe2edae646d58e94c6a6b5f010f6439f7..b086d55fe11b8b7fc87b476e5cf57c9b403ec6bf:/include/wx/strvararg.h diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index 16273f47a6..c1aa0364f6 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -106,6 +106,61 @@ class WXDLLIMPEXP_BASE wxString; _WX_VARARG_DEFINE_FUNC_CTOR, \ void, name, impl, implUtf8, numfixed, fixed) + +// ---------------------------------------------------------------------------- +// wxFormatString +// ---------------------------------------------------------------------------- + +// This class should be used for format string argument of the functions +// defined using WX_DEFINE_VARARG_FUNC_* macros. It converts the string to +// char* or wchar_t* for passing to implementation function efficiently (i.e. +// without keeping the converted string in memory for longer than necessary, +// like c_str()) +// +// Note that this class can _only_ be used for function arguments! +class WXDLLIMPEXP_BASE wxFormatString +{ +public: + wxFormatString(const char *str) + : m_char(wxCharBuffer::CreateNonOwned(str)), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wchar_t *str) + : m_wchar(wxWCharBuffer::CreateNonOwned(str)), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wxString& str) + : m_str(&str), m_cstr(NULL) {} + wxFormatString(const wxCStrData& str) + : m_str(NULL), m_cstr(&str) {} + wxFormatString(const wxCharBuffer& str) + : m_char(str), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wxWCharBuffer& str) + : m_wchar(str), m_str(NULL), m_cstr(NULL) {} + +#if !wxUSE_UNICODE_WCHAR + operator const char*() const + { return wx_const_cast(wxFormatString*, this)->AsChar(); } +private: + const char* AsChar(); +#endif // !wxUSE_UNICODE_WCHAR + +#if wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY +public: + operator const wchar_t*() const + { return wx_const_cast(wxFormatString*, this)->AsWChar(); } +private: + const wchar_t* AsWChar(); +#endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY + +private: + wxCharBuffer m_char; + wxWCharBuffer m_wchar; + // NB: we can use a pointer here, because wxFormatString is only used + // as function argument, so it has shorter life than the string + // passed to the ctor + const wxString * const m_str; + const wxCStrData * const m_cstr; + + DECLARE_NO_COPY_CLASS(wxFormatString) +}; + // ---------------------------------------------------------------------------- // wxArgNormalizer* converters // ---------------------------------------------------------------------------- @@ -121,9 +176,9 @@ struct wxArgNormalizer // Returns the value in a form that can be safely passed to real vararg // functions. In case of strings, this is char* in ANSI build and wchar_t* // in Unicode build. - const T& get() const { return m_value; } + T get() const { return m_value; } - const T& m_value; + T m_value; }; // normalizer for passing arguments to functions working with wchar_t* (and @@ -238,14 +293,19 @@ struct wxArgNormalizerUtf8 { wxArgNormalizerUtf8(const char* s) { - // FIXME-UTF8: optimize this if current locale is UTF-8 one - - // convert to widechar string first: - wxWCharBuffer buf(wxConvLibc.cMB2WC(s)); - - // then to UTF-8: - if ( buf ) - m_value = wxConvUTF8.cWC2MB(buf); + if ( wxLocaleIsUtf8 ) + { + m_value = wxCharBuffer::CreateNonOwned(s); + } + else + { + // convert to widechar string first: + wxWCharBuffer buf(wxConvLibc.cMB2WC(s)); + + // then to UTF-8: + if ( buf ) + m_value = wxConvUTF8.cWC2MB(buf); + } } }; @@ -672,4 +732,65 @@ private: inline void name(_WX_VARARG_FIXED_UNUSED_EXPAND(numfixed, fixed)) \ {} + +// ---------------------------------------------------------------------------- +// workaround for OpenWatcom bug #351 +// ---------------------------------------------------------------------------- + +#ifdef __WATCOMC__ +// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 + +// This macro can be used to forward a 'vararg' template to another one with +// different fixed arguments types. Parameters are same as for +// WX_DEFINE_VARARG_FUNC (rettype=void can be used here), 'convfixed' is how +// to convert fixed arguments. For example, this is typical code for dealing +// with different forms of format string: +// +// WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wxFormatString&), +// DoPrintfWchar, DoPrintfUtf8) +// #ifdef __WATCOMC__ +// WX_VARARG_WATCOM_WORKAROUND(void, Printf, 1, (const wxString&), +// (wxFormatString(f1))) +// WX_VARARG_WATCOM_WORKAROUND(void, Printf, 1, (const char*), +// (wxFormatString(f1))) +// ... +#define WX_VARARG_WATCOM_WORKAROUND(rettype, name, numfixed, fixed, convfixed)\ + _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ + _WX_VARARG_WATCOM_WORKAROUND, \ + rettype, name, convfixed, dummy, numfixed, fixed) + +#define WX_VARARG_WATCOM_WORKAROUND_CTOR(name, numfixed, fixed, convfixed) \ + _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ + _WX_VARARG_WATCOM_WORKAROUND_CTOR, \ + dummy, name, convfixed, dummy, numfixed, fixed) + +#define _WX_VARARG_WATCOM_UNPACK_1(a1) a1 +#define _WX_VARARG_WATCOM_UNPACK_2(a1, a2) a1, a2 +#define _WX_VARARG_WATCOM_UNPACK_3(a1, a2, a3) a1, a2, a3 +#define _WX_VARARG_WATCOM_UNPACK_4(a1, a2, a3, a4) a1, a2, a3, a4 +#define _WX_VARARG_WATCOM_UNPACK(N, convfixed) \ + _WX_VARARG_WATCOM_UNPACK_##N convfixed + +#define _WX_VARARG_WATCOM_WORKAROUND(N, rettype, name, \ + convfixed, dummy, numfixed, fixed) \ + template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ + rettype name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed), \ + _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \ + { \ + return name(_WX_VARARG_WATCOM_UNPACK(numfixed, convfixed), \ + _WX_VARARG_JOIN(N, _WX_VARARG_PASS_WCHAR)); \ + } + +#define _WX_VARARG_WATCOM_WORKAROUND_CTOR(N, dummy1, name, \ + convfixed, dummy2, numfixed, fixed) \ + template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ + name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed), \ + _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \ + { \ + name(_WX_VARARG_WATCOM_UNPACK(numfixed, convfixed), \ + _WX_VARARG_JOIN(N, _WX_VARARG_PASS_WCHAR)); \ + } + +#endif // __WATCOMC__ + #endif // _WX_STRVARARG_H_