X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2523e9b70044baa92a1c63ffdfe179c28ad53536..6626de903e54f907fed5737b61344e31f86262eb:/include/wx/strvararg.h diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index 459c0ffeec..05460711d7 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -70,33 +70,25 @@ class WXDLLIMPEXP_BASE wxString; // if wxUSE_UNICODE_UTF8 and running under UTF-8 locale // (ignored otherwise) [fprintf] // -#define WX_DEFINE_VARARG_FUNC2(rettype, name, numfixed, fixed, impl, implUtf8)\ +#define WX_DEFINE_VARARG_FUNC(rettype, name, numfixed, fixed, impl, implUtf8) \ _WX_VARARG_DEFINE_FUNC_N0(rettype, name, impl, implUtf8, numfixed, fixed) \ - WX_DEFINE_VARARG_FUNC2_SANS_N0(rettype, name, numfixed, fixed, impl, implUtf8) + WX_DEFINE_VARARG_FUNC_SANS_N0(rettype, name, numfixed, fixed, impl, implUtf8) // ditto, but without the version with 0 template/vararg arguments -#define WX_DEFINE_VARARG_FUNC2_SANS_N0(rettype, name, \ +#define WX_DEFINE_VARARG_FUNC_SANS_N0(rettype, name, \ numfixed, fixed, impl, implUtf8) \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC, \ rettype, name, impl, implUtf8, numfixed, fixed) -// like WX_DEFINE_VARARG_FUNC2, but for impl=implUtf8: -#define WX_DEFINE_VARARG_FUNC(rettype, name, numfixed, fixed, impl) \ - WX_DEFINE_VARARG_FUNC2(rettype, name, numfixed, fixed, impl, impl) - -// Like WX_DEFINE_VARARG_FUNC2, but for variadic functions that don't return +// Like WX_DEFINE_VARARG_FUNC, but for variadic functions that don't return // a value. -#define WX_DEFINE_VARARG_FUNC_VOID2(name, numfixed, fixed, impl, implUtf8) \ +#define WX_DEFINE_VARARG_FUNC_VOID(name, numfixed, fixed, impl, implUtf8) \ _WX_VARARG_DEFINE_FUNC_VOID_N0(name, impl, implUtf8, numfixed, fixed) \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC_VOID, \ void, name, impl, implUtf8, numfixed, fixed) -// like WX_DEFINE_VARARG_FUNC_VOID2, but for impl=implUtf8: -#define WX_DEFINE_VARARG_FUNC_VOID(name, numfixed, fixed, impl) \ - WX_DEFINE_VARARG_FUNC_VOID2(name, numfixed, fixed, impl, impl) - // Like WX_DEFINE_VARARG_FUNC_VOID, but instead of wrapping an implementation // function, does nothing in defined functions' bodies. // @@ -105,14 +97,69 @@ class WXDLLIMPEXP_BASE wxString; _WX_VARARG_DEFINE_FUNC_NOP_N0(name, numfixed, fixed) \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC_NOP, \ - void, name, dummy, numfixed, fixed) + void, name, dummy, dummy, numfixed, fixed) // Like WX_DEFINE_VARARG_FUNC_CTOR, but for defining template constructors -#define WX_DEFINE_VARARG_FUNC_CTOR(name, numfixed, fixed, impl) \ - _WX_VARARG_DEFINE_FUNC_CTOR_N0(name, impl, impl, numfixed, fixed) \ +#define WX_DEFINE_VARARG_FUNC_CTOR(name, numfixed, fixed, impl, implUtf8) \ + _WX_VARARG_DEFINE_FUNC_CTOR_N0(name, impl, implUtf8, numfixed, fixed) \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC_CTOR, \ - void, name, impl, impl, numfixed, fixed) + 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 @@ -129,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 @@ -246,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); + } } }; @@ -320,6 +372,53 @@ WX_ARG_NORMALIZER_FORWARD(const wxCharBuffer&, const char*); WX_ARG_NORMALIZER_FORWARD(wxWCharBuffer, const wchar_t*); WX_ARG_NORMALIZER_FORWARD(const wxWCharBuffer&, const wchar_t*); +// versions for std::[w]string: +#if wxUSE_STD_STRING + +#include "wx/stringimpl.h" + +#if !wxUSE_UTF8_LOCALE_ONLY +template<> +struct wxArgNormalizerWchar + : public wxArgNormalizerWchar +{ + wxArgNormalizerWchar(const std::string& s) + : wxArgNormalizerWchar(s.c_str()) {} +}; + +template<> +struct wxArgNormalizerWchar + : public wxArgNormalizerWchar +{ + wxArgNormalizerWchar(const wxStdWideString& s) + : wxArgNormalizerWchar(s.c_str()) {} +}; +#endif // !wxUSE_UTF8_LOCALE_ONLY + +#if wxUSE_UNICODE_UTF8 +template<> +struct wxArgNormalizerUtf8 + : public wxArgNormalizerUtf8 +{ + wxArgNormalizerUtf8(const std::string& s) + : wxArgNormalizerUtf8(s.c_str()) {} +}; + +template<> +struct wxArgNormalizerUtf8 + : public wxArgNormalizerUtf8 +{ + wxArgNormalizerUtf8(const wxStdWideString& s) + : wxArgNormalizerUtf8(s.c_str()) {} +}; +#endif // wxUSE_UNICODE_UTF8 + +WX_ARG_NORMALIZER_FORWARD(std::string, const std::string&); +WX_ARG_NORMALIZER_FORWARD(wxStdWideString, const wxStdWideString&); + +#endif // wxUSE_STD_STRING + + #undef WX_ARG_NORMALIZER_FORWARD #undef _WX_ARG_NORMALIZER_FORWARD_IMPL @@ -501,7 +600,7 @@ private: #define _WX_VARARG_ARG(i) T##i a##i // Like _WX_VARARG_ARG_UNUSED, but outputs argument's type with WXUNUSED: -#define _WX_VARARG_ARG_UNUSED(i) T##i WXUNUSED(a##i) +#define _WX_VARARG_ARG_UNUSED(i) T##i WXUNUSED(a##i) // Generates code snippet for i-th type in vararg function's template<...>: #define _WX_VARARG_TEMPL(i) typename T##i