Add sprintf overload for wide strings

and fix an issue in formatting user-defined objects.
Thanks to @ScottLangham
This commit is contained in:
vitaut 2015-09-18 16:26:41 -07:00
parent 79d8f59906
commit ef710dee6c
4 changed files with 27 additions and 5 deletions

View File

@ -526,7 +526,8 @@ class PrintfArgFormatter :
void visit_custom(Arg::CustomValue c) { void visit_custom(Arg::CustomValue c) {
BasicFormatter<Char> formatter(ArgList(), this->writer()); BasicFormatter<Char> formatter(ArgList(), this->writer());
const char *format = "}"; const Char format_str[] = {'}', 0};
const Char *format = format_str;
c.format(&formatter, c.value, &format); c.format(&formatter, c.value, &format);
} }
}; };

View File

@ -2706,6 +2706,12 @@ inline std::string sprintf(CStringRef format, ArgList args) {
return w.str(); return w.str();
} }
inline std::wstring sprintf(WCStringRef format, ArgList args) {
WMemoryWriter w;
printf(w, format, args);
return w.str();
}
/** /**
\rst \rst
Prints formatted data to the file *f*. Prints formatted data to the file *f*.
@ -2994,6 +3000,7 @@ FMT_VARIADIC(void, print, std::FILE *, CStringRef)
FMT_VARIADIC(void, print, std::ostream &, CStringRef) FMT_VARIADIC(void, print, std::ostream &, CStringRef)
FMT_VARIADIC(void, print_colored, Color, CStringRef) FMT_VARIADIC(void, print_colored, Color, CStringRef)
FMT_VARIADIC(std::string, sprintf, CStringRef) FMT_VARIADIC(std::string, sprintf, CStringRef)
FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
FMT_VARIADIC(int, printf, CStringRef) FMT_VARIADIC(int, printf, CStringRef)
FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
} }

View File

@ -456,3 +456,7 @@ TEST(PrintfTest, PrintfError) {
EXPECT_LT(result, 0); EXPECT_LT(result, 0);
} }
#endif #endif
TEST(PrintfTest, WideString) {
EXPECT_EQ(L"abc", fmt::sprintf(L"%s", TestWString(L"abc")));
}

View File

@ -68,15 +68,25 @@ inline FILE *safe_fopen(const char *filename, const char *mode) {
#endif #endif
} }
class TestString { template <typename Char>
class BasicTestString {
private: private:
std::string value_; std::basic_string<Char> value_;
static const Char EMPTY[];
public: public:
explicit TestString(const char *value = "") : value_(value) {} explicit BasicTestString(const Char *value = EMPTY) : value_(value) {}
friend std::ostream &operator<<(std::ostream &os, const TestString &s) { friend std::basic_ostream<Char> &operator<<(
std::basic_ostream<Char> &os, const BasicTestString &s) {
os << s.value_; os << s.value_;
return os; return os;
} }
}; };
template <typename Char>
const Char BasicTestString<Char>::EMPTY[] = {0};
typedef BasicTestString<char> TestString;
typedef BasicTestString<wchar_t> TestWString;