Reimplement wxString::Printf() as variadic template
This implementation uses std::index_sequence which is C++14-only, so we'll need to increase the minimum C++ version requirements if we use it.
This commit is contained in:
parent
84229199c7
commit
6456ddac57
3 changed files with 69 additions and 45 deletions
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include "wx/beforestd.h"
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include "wx/afterstd.h"
|
||||
|
||||
// by default we cache the mapping of the positions in UTF-8 string to the byte
|
||||
|
|
@ -2195,17 +2197,27 @@ public:
|
|||
|
||||
// formatted input/output
|
||||
// as sprintf(), returns the number of characters written or < 0 on error
|
||||
// (take 'this' into account in attribute parameter count)
|
||||
// int Printf(const wxString& format, ...);
|
||||
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxFormatString&),
|
||||
DoPrintfWchar, DoPrintfUtf8)
|
||||
template <typename... Targs>
|
||||
int Printf(const wxString& format, Targs... args)
|
||||
{
|
||||
// Package the arguments into a tuple to pass them on together with the
|
||||
// indices that are needed by the implementation.
|
||||
return DoPrintf(format,
|
||||
std::make_tuple(args...),
|
||||
std::index_sequence_for<Targs...>{});
|
||||
}
|
||||
|
||||
// as vprintf(), returns the number of characters written or < 0 on error
|
||||
int PrintfV(const wxString& format, va_list argptr);
|
||||
|
||||
// returns the string containing the result of Printf() to it
|
||||
// static wxString Format(const wxString& format, ...) WX_ATTRIBUTE_PRINTF_1;
|
||||
WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxFormatString&),
|
||||
DoFormatWchar, DoFormatUtf8)
|
||||
template <typename... Targs>
|
||||
static wxString Format(const wxString& format, Targs... args)
|
||||
{
|
||||
wxString s;
|
||||
s.Printf(format, args...);
|
||||
return s;
|
||||
}
|
||||
// the same as above, but takes a va_list
|
||||
static wxString FormatV(const wxString& format, va_list argptr);
|
||||
|
||||
|
|
@ -2228,10 +2240,11 @@ public:
|
|||
enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
|
||||
|
||||
// use Printf()
|
||||
// (take 'this' into account in attribute parameter count)
|
||||
// int sprintf(const wxString& format, ...) WX_ATTRIBUTE_PRINTF_2;
|
||||
WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxFormatString&),
|
||||
DoPrintfWchar, DoPrintfUtf8)
|
||||
template <typename... Targs>
|
||||
int sprintf(const wxString& format, Targs... args)
|
||||
{
|
||||
return Printf(format, args...);
|
||||
}
|
||||
|
||||
// use Cmp()
|
||||
int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
|
||||
|
|
@ -3373,13 +3386,36 @@ public:
|
|||
wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); }
|
||||
|
||||
private:
|
||||
template <typename ArgsTuple, std::size_t... Ns>
|
||||
int DoPrintf(const wxFormatString& format,
|
||||
const ArgsTuple& args,
|
||||
std::index_sequence<Ns...>)
|
||||
{
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||
if ( wxLocaleIsUtf8 )
|
||||
#endif
|
||||
return DoPrintfUtf8
|
||||
(
|
||||
format,
|
||||
wxNormalizeArgUtf8(std::get<Ns>(args), &format, Ns).get()...
|
||||
);
|
||||
#endif // wxUSE_UNICODE_UTF8
|
||||
|
||||
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||
return DoPrintfWchar
|
||||
(
|
||||
format,
|
||||
wxNormalizeArgWchar(std::get<Ns>(args), &format, Ns).get()...
|
||||
);
|
||||
#endif // !wxUSE_UTF8_LOCALE_ONLY
|
||||
}
|
||||
|
||||
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||
int DoPrintfWchar(const wxChar *format, ...);
|
||||
static wxString DoFormatWchar(const wxChar *format, ...);
|
||||
#endif
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
int DoPrintfUtf8(const char *format, ...);
|
||||
static wxString DoFormatUtf8(const char *format, ...);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -467,6 +467,18 @@ struct wxArgNormalizerWchar : public wxArgNormalizer<T>
|
|||
const wxFormatString *fmt, unsigned index)
|
||||
: wxArgNormalizer<T>(value, fmt, index) {}
|
||||
};
|
||||
|
||||
// Helper function for creating a wxArgNormalizerWchar<T> with type deduced
|
||||
// from the type of the argument.
|
||||
//
|
||||
// NB: Unlike the class ctor, which uses 1-based indices, it takes 0-based
|
||||
// index which makes it more convenient to use in pack expansions.
|
||||
template<typename T>
|
||||
wxArgNormalizerWchar<T>
|
||||
wxNormalizeArgWchar(T value, const wxFormatString *fmt, unsigned indexFrom0)
|
||||
{
|
||||
return wxArgNormalizerWchar<T>(value, fmt, indexFrom0 + 1);
|
||||
}
|
||||
#endif // !wxUSE_UTF8_LOCALE_ONLY
|
||||
|
||||
// normalizer for passing arguments to functions working with UTF-8 encoded
|
||||
|
|
@ -480,6 +492,14 @@ struct wxArgNormalizerWchar : public wxArgNormalizer<T>
|
|||
: wxArgNormalizer<T>(value, fmt, index) {}
|
||||
};
|
||||
|
||||
// Same type-deducing helper as above, but for wxArgNormalizerUtf8<T>
|
||||
template<typename T>
|
||||
wxArgNormalizerUtf8<T>
|
||||
wxNormalizeArgUtf8(T value, const wxFormatString *fmt, unsigned indexFrom0)
|
||||
{
|
||||
return wxArgNormalizerUtf8<T>(value, fmt, indexFrom0 + 1);
|
||||
}
|
||||
|
||||
#define wxArgNormalizerNative wxArgNormalizerUtf8
|
||||
#else // wxUSE_UNICODE_WCHAR
|
||||
#define wxArgNormalizerNative wxArgNormalizerWchar
|
||||
|
|
|
|||
|
|
@ -1679,38 +1679,6 @@ wxString wxString::FromCDouble(double val, int precision)
|
|||
// formatted output
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||
/* static */
|
||||
wxString wxString::DoFormatWchar(const wxChar *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
|
||||
wxString s;
|
||||
s.PrintfV(format, argptr);
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif // !wxUSE_UTF8_LOCALE_ONLY
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
/* static */
|
||||
wxString wxString::DoFormatUtf8(const char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
|
||||
wxString s;
|
||||
s.PrintfV(format, argptr);
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif // wxUSE_UNICODE_UTF8
|
||||
|
||||
/* static */
|
||||
wxString wxString::FormatV(const wxString& format, va_list argptr)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue