Commit f7112662 authored by Victor Zverovich's avatar Victor Zverovich

Test MakeArg. Clean the API.

parent 144e1fbb
...@@ -130,6 +130,9 @@ typedef BasicWriter<wchar_t> WWriter; ...@@ -130,6 +130,9 @@ typedef BasicWriter<wchar_t> WWriter;
struct FormatSpec; struct FormatSpec;
template <typename Char, typename T>
void format(BasicWriter<Char> &w, const FormatSpec &spec, const T &value);
/** /**
\rst \rst
A string reference. It can be constructed from a C string or A string reference. It can be constructed from a C string or
...@@ -359,7 +362,7 @@ template <> ...@@ -359,7 +362,7 @@ template <>
class CharTraits<char> : public BasicCharTraits<char> { class CharTraits<char> : public BasicCharTraits<char> {
private: private:
// Conversion from wchar_t to char is not allowed. // Conversion from wchar_t to char is not allowed.
static char ConvertChar(wchar_t); static char convert(wchar_t);
// Conversion from const wchar_t * to const char * is not allowed. // Conversion from const wchar_t * to const char * is not allowed.
static const wchar_t *check(const wchar_t *s); static const wchar_t *check(const wchar_t *s);
...@@ -367,7 +370,7 @@ class CharTraits<char> : public BasicCharTraits<char> { ...@@ -367,7 +370,7 @@ class CharTraits<char> : public BasicCharTraits<char> {
public: public:
typedef const wchar_t *UnsupportedStrType; typedef const wchar_t *UnsupportedStrType;
static char ConvertChar(char value) { return value; } static char convert(char value) { return value; }
static StringValue<char> convert(StringValue<wchar_t>) { static StringValue<char> convert(StringValue<wchar_t>) {
StringValue<char> s = {"", 0}; StringValue<char> s = {"", 0};
...@@ -384,8 +387,8 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { ...@@ -384,8 +387,8 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
public: public:
typedef const char *UnsupportedStrType; typedef const char *UnsupportedStrType;
static wchar_t ConvertChar(char value) { return value; } static wchar_t convert(char value) { return value; }
static wchar_t ConvertChar(wchar_t value) { return value; } static wchar_t convert(wchar_t value) { return value; }
static StringValue<wchar_t> convert(StringValue<wchar_t> s) { return s; } static StringValue<wchar_t> convert(StringValue<wchar_t> s) { return s; }
...@@ -503,9 +506,6 @@ void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) { ...@@ -503,9 +506,6 @@ void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) {
buffer[0] = DIGITS[index]; buffer[0] = DIGITS[index];
} }
template <typename Char, typename T>
void FormatCustomArg(void *writer, const void *arg, const FormatSpec &spec);
#ifdef _WIN32 #ifdef _WIN32
// A converter from UTF-8 to UTF-16. // A converter from UTF-8 to UTF-16.
// It is only provided for Windows since other systems use UTF-8. // It is only provided for Windows since other systems use UTF-8.
...@@ -633,18 +633,26 @@ class MakeArg : public Arg { ...@@ -633,18 +633,26 @@ class MakeArg : public Arg {
template <typename T> template <typename T>
MakeArg(T *value); MakeArg(T *value);
void SetString(StringRef str) { void set_string(StringRef str) {
type = STRING; type = STRING;
string.value = str.c_str(); string.value = str.c_str();
string.size = str.size(); string.size = str.size();
} }
void SetString(WStringRef str) { void set_string(WStringRef str) {
type = WSTRING; type = WSTRING;
wstring.value = CharTraits<Char>::check(str.c_str()); wstring.value = CharTraits<Char>::check(str.c_str());
wstring.size = str.size(); wstring.size = str.size();
} }
// Formats an argument of a custom type, such as a user-defined class.
template <typename T>
static void format_custom_arg(
void *writer, const void *arg, const FormatSpec &spec) {
format(*static_cast<BasicWriter<Char>*>(writer),
spec, *static_cast<const T*>(arg));
}
public: public:
MakeArg() {} MakeArg() {}
MakeArg(bool value) { type = INT; int_value = value; } MakeArg(bool value) { type = INT; int_value = value; }
...@@ -682,18 +690,18 @@ public: ...@@ -682,18 +690,18 @@ public:
MakeArg(char value) { type = CHAR; int_value = value; } MakeArg(char value) { type = CHAR; int_value = value; }
MakeArg(wchar_t value) { MakeArg(wchar_t value) {
type = CHAR; type = CHAR;
int_value = internal::CharTraits<Char>::ConvertChar(value); int_value = internal::CharTraits<Char>::convert(value);
} }
MakeArg(char *value) { SetString(value); } MakeArg(char *value) { set_string(value); }
MakeArg(const char *value) { SetString(value); } MakeArg(const char *value) { set_string(value); }
MakeArg(const std::string &value) { SetString(value); } MakeArg(const std::string &value) { set_string(value); }
MakeArg(StringRef value) { SetString(value); } MakeArg(StringRef value) { set_string(value); }
MakeArg(wchar_t *value) { SetString(value); } MakeArg(wchar_t *value) { set_string(value); }
MakeArg(const wchar_t *value) { SetString(value); } MakeArg(const wchar_t *value) { set_string(value); }
MakeArg(const std::wstring &value) { SetString(value); } MakeArg(const std::wstring &value) { set_string(value); }
MakeArg(WStringRef value) { SetString(value); } MakeArg(WStringRef value) { set_string(value); }
MakeArg(void *value) { type = POINTER; pointer_value = value; } MakeArg(void *value) { type = POINTER; pointer_value = value; }
MakeArg(const void *value) { type = POINTER; pointer_value = value; } MakeArg(const void *value) { type = POINTER; pointer_value = value; }
...@@ -702,7 +710,7 @@ public: ...@@ -702,7 +710,7 @@ public:
MakeArg(const T &value) { MakeArg(const T &value) {
type = CUSTOM; type = CUSTOM;
custom.value = &value; custom.value = &value;
custom.format = &internal::FormatCustomArg<Char, T>; custom.format = &format_custom_arg<T>;
} }
}; };
...@@ -1364,7 +1372,7 @@ class BasicWriter { ...@@ -1364,7 +1372,7 @@ class BasicWriter {
} }
BasicWriter &operator<<(wchar_t value) { BasicWriter &operator<<(wchar_t value) {
*GrowBuffer(1) = internal::CharTraits<Char>::ConvertChar(value); *GrowBuffer(1) = internal::CharTraits<Char>::convert(value);
return *this; return *this;
} }
...@@ -1380,7 +1388,7 @@ class BasicWriter { ...@@ -1380,7 +1388,7 @@ class BasicWriter {
template <typename T, typename Spec, typename FillChar> template <typename T, typename Spec, typename FillChar>
BasicWriter &operator<<(const IntFormatSpec<T, Spec, FillChar> &spec) { BasicWriter &operator<<(const IntFormatSpec<T, Spec, FillChar> &spec) {
internal::CharTraits<Char>::ConvertChar(FillChar()); internal::CharTraits<Char>::convert(FillChar());
FormatInt(spec.value(), spec); FormatInt(spec.value(), spec);
return *this; return *this;
} }
...@@ -1575,15 +1583,6 @@ void format(BasicWriter<Char> &w, const FormatSpec &spec, const T &value) { ...@@ -1575,15 +1583,6 @@ void format(BasicWriter<Char> &w, const FormatSpec &spec, const T &value) {
w.write_str(os.str(), spec); w.write_str(os.str(), spec);
} }
namespace internal {
// Formats an argument of a custom type, such as a user-defined class.
template <typename Char, typename T>
void FormatCustomArg(void *writer, const void *arg, const FormatSpec &spec) {
format(*static_cast<BasicWriter<Char>*>(writer),
spec, *static_cast<const T*>(arg));
}
}
// Reports a system error without throwing an exception. // Reports a system error without throwing an exception.
// Can be used to report errors from destructors. // Can be used to report errors from destructors.
void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true); void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true);
......
...@@ -56,6 +56,9 @@ std::string GetSystemErrorMessage(int error_code) { ...@@ -56,6 +56,9 @@ std::string GetSystemErrorMessage(int error_code) {
return buffer; return buffer;
#endif #endif
} }
struct Test {};
std::ostream &operator<<(std::ostream &os, Test) { return os << "test"; }
} }
TEST(UtilTest, Increment) { TEST(UtilTest, Increment) {
...@@ -173,7 +176,17 @@ TEST(UtilTest, MakeArg) { ...@@ -173,7 +176,17 @@ TEST(UtilTest, MakeArg) {
EXPECT_ARGW(WSTRING, std::wstring, wstring.value, WSTR); EXPECT_ARGW(WSTRING, std::wstring, wstring.value, WSTR);
EXPECT_ARGW(WSTRING, fmt::WStringRef, wstring.value, WSTR); EXPECT_ARGW(WSTRING, fmt::WStringRef, wstring.value, WSTR);
// TODO: test that wide string is rejected by MakeArg<char> int n = 42;
EXPECT_ARG(POINTER, void*, pointer_value, &n);
EXPECT_ARG(POINTER, const void*, pointer_value, &n);
::Test t;
fmt::internal::Arg arg = fmt::internal::MakeArg<char>(t);
EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type);
arg.custom.value = &t;
fmt::Writer w;
arg.custom.format(&w, &t, fmt::FormatSpec());
EXPECT_EQ("test", w.str());
} }
// Tests fmt::internal::CountDigits for integer type Int. // Tests fmt::internal::CountDigits for integer type Int.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment