]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/strvararg.h
added wchar_t, wxUniChar overloads for wxStrchr
[wxWidgets.git] / include / wx / strvararg.h
index 82f0039b08a181f86e03ecaba30289ac8b5fd542..7c7ae7ae825d406efd9ccb19b10931bf9e591acf 100644 (file)
@@ -18,9 +18,9 @@
 
 #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;
@@ -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*<T> 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
@@ -364,6 +419,35 @@ WX_ARG_NORMALIZER_FORWARD(wxStdWideString, const wxStdWideString&);
 #endif // wxUSE_STD_STRING
 
 
+// versions for wxUniChar, wxUniCharRef:
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+template<>
+struct wxArgNormalizerWchar<const wxUniChar&>
+    : public wxArgNormalizerWchar<wxChar/*FIXME-UTF8: should be wchar_t after ANSI removal*/>
+{
+    wxArgNormalizerWchar(const wxUniChar& s)
+        : wxArgNormalizerWchar<wxChar>((wxChar)s) {}
+};
+#endif // !wxUSE_UTF8_LOCALE_ONLY
+
+#if wxUSE_UNICODE_UTF8
+template<>
+struct wxArgNormalizerUtf8<const wxUniChar&>
+    : public wxArgNormalizerUtf8<char>
+{
+    wxArgNormalizerUtf8(const wxUniChar& s)
+        // FIXME-UTF8: this is lossy, we need to convert to string, but that
+        // requires format string update
+        : wxArgNormalizerUtf8<char>((const char)s) {}
+};
+#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&);
+
+
 #undef WX_ARG_NORMALIZER_FORWARD
 #undef _WX_ARG_NORMALIZER_FORWARD_IMPL
 
@@ -677,4 +761,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_