X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1528e0b85fed193f8a4a25f20dcc36064bb71d2a..7da37f2c5d7addc655e3c6bcd29a8877c360b35b:/include/wx/strvararg.h diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index 729b41069b..2e6f3033a4 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -18,12 +18,12 @@ #include "wx/cpp.h" #include "wx/chartype.h" -#include "wx/wxcrt.h" #include "wx/strconv.h" #include "wx/buffer.h" +#include "wx/unichar.h" -class WXDLLIMPEXP_BASE wxCStrData; -class WXDLLIMPEXP_BASE wxString; +class WXDLLIMPEXP_FWD_BASE wxCStrData; +class WXDLLIMPEXP_FWD_BASE wxString; // ---------------------------------------------------------------------------- // WX_DEFINE_VARARG_FUNC* macros @@ -47,6 +47,9 @@ class WXDLLIMPEXP_BASE wxString; // * wchar_t* if wxUSE_UNICODE_WCHAR or if wxUSE_UNICODE_UTF8 and the current // locale is not UTF-8 // +// Note that wxFormatString *must* be used for the format parameter of these +// functions, otherwise the implementation won't work correctly. +// // Parameters: // [ there are examples in square brackets showing values of the parameters // for the wxFprintf() wrapper for fprintf() function with the following @@ -111,11 +114,12 @@ class WXDLLIMPEXP_BASE wxString; // wxFormatString // ---------------------------------------------------------------------------- -// This class should be used for format string argument of the functions +// This class must 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()) +// like c_str()). It also converts format string to the correct form that +// accounts for string changes done by wxArgNormalizer<> // // Note that this class can _only_ be used for function arguments! class WXDLLIMPEXP_BASE wxFormatString @@ -138,19 +142,37 @@ public: operator const char*() const { return wx_const_cast(wxFormatString*, this)->AsChar(); } private: + // InputAsChar() returns the value converted passed to ctor, only converted + // to char, while AsChar() takes the the string returned by InputAsChar() + // and does format string conversion on it as well (and similarly for + // ..AsWChar() below) + const char* InputAsChar(); const char* AsChar(); + wxCharBuffer m_convertedChar; #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* InputAsWChar(); const wchar_t* AsWChar(); + wxWCharBuffer m_convertedWChar; #endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY private: +#ifdef __VISUALC__ + // "struct 'ConvertedBuffer' needs to have dll-interface to be used by + // clients of class 'wxString'" - this is private, we don't care + #pragma warning (disable:4251) +#endif wxCharBuffer m_char; wxWCharBuffer m_wchar; +#ifdef __VISUALC__ + #pragma warning (default:4251) +#endif + // 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 @@ -418,6 +440,45 @@ WX_ARG_NORMALIZER_FORWARD(wxStdWideString, const wxStdWideString&); #endif // wxUSE_STD_STRING +// versions for wxUniChar, wxUniCharRef: + +#if !wxUSE_UTF8_LOCALE_ONLY +template<> +struct wxArgNormalizerWchar +{ + wxArgNormalizerWchar(const wxUniChar& s) : m_value(s) {} + + // FIXME-UTF8: use wchar_t once ANSI build is removed + wxChar get() const { return m_value; } + + wxChar m_value; +}; +#endif // !wxUSE_UTF8_LOCALE_ONLY + +#if wxUSE_UNICODE_UTF8 +template<> +struct wxArgNormalizerUtf8 +{ + wxArgNormalizerUtf8(const wxUniChar& s) : m_value(s.AsUTF8()) {} + + const wxStringCharType *get() const { return m_value; } + + wxUniChar::Utf8CharBuffer m_value; +}; +#endif // wxUSE_UNICODE_UTF8 + +WX_ARG_NORMALIZER_FORWARD(wxUniChar, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(const wxUniCharRef&, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(wxUniCharRef, const wxUniChar&); +// convert char/wchar_t to wxUniChar to get output in the right encoding: +WX_ARG_NORMALIZER_FORWARD(char, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(const char&, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(unsigned char, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(const unsigned char&, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(wchar_t, const wxUniChar&); +WX_ARG_NORMALIZER_FORWARD(const wchar_t&, const wxUniChar&); + + #undef WX_ARG_NORMALIZER_FORWARD #undef _WX_ARG_NORMALIZER_FORWARD_IMPL @@ -731,4 +792,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_