Test MakeArg. Clean the API.

This commit is contained in:
Victor Zverovich 2014-07-04 07:18:44 -07:00
parent 144e1fbb7c
commit f711266244
2 changed files with 43 additions and 31 deletions

View File

@ -130,6 +130,9 @@ typedef BasicWriter<wchar_t> WWriter;
struct FormatSpec;
template <typename Char, typename T>
void format(BasicWriter<Char> &w, const FormatSpec &spec, const T &value);
/**
\rst
A string reference. It can be constructed from a C string or
@ -359,7 +362,7 @@ template <>
class CharTraits<char> : public BasicCharTraits<char> {
private:
// 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.
static const wchar_t *check(const wchar_t *s);
@ -367,7 +370,7 @@ class CharTraits<char> : public BasicCharTraits<char> {
public:
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>) {
StringValue<char> s = {"", 0};
@ -384,8 +387,8 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
public:
typedef const char *UnsupportedStrType;
static wchar_t ConvertChar(char value) { return value; }
static wchar_t ConvertChar(wchar_t value) { return value; }
static wchar_t convert(char value) { return value; }
static wchar_t convert(wchar_t value) { return value; }
static StringValue<wchar_t> convert(StringValue<wchar_t> s) { return s; }
@ -503,9 +506,6 @@ void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) {
buffer[0] = DIGITS[index];
}
template <typename Char, typename T>
void FormatCustomArg(void *writer, const void *arg, const FormatSpec &spec);
#ifdef _WIN32
// A converter from UTF-8 to UTF-16.
// It is only provided for Windows since other systems use UTF-8.
@ -633,18 +633,26 @@ class MakeArg : public Arg {
template <typename T>
MakeArg(T *value);
void SetString(StringRef str) {
void set_string(StringRef str) {
type = STRING;
string.value = str.c_str();
string.size = str.size();
}
void SetString(WStringRef str) {
void set_string(WStringRef str) {
type = WSTRING;
wstring.value = CharTraits<Char>::check(str.c_str());
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:
MakeArg() {}
MakeArg(bool value) { type = INT; int_value = value; }
@ -682,18 +690,18 @@ public:
MakeArg(char value) { type = CHAR; int_value = value; }
MakeArg(wchar_t value) {
type = CHAR;
int_value = internal::CharTraits<Char>::ConvertChar(value);
int_value = internal::CharTraits<Char>::convert(value);
}
MakeArg(char *value) { SetString(value); }
MakeArg(const char *value) { SetString(value); }
MakeArg(const std::string &value) { SetString(value); }
MakeArg(StringRef value) { SetString(value); }
MakeArg(char *value) { set_string(value); }
MakeArg(const char *value) { set_string(value); }
MakeArg(const std::string &value) { set_string(value); }
MakeArg(StringRef value) { set_string(value); }
MakeArg(wchar_t *value) { SetString(value); }
MakeArg(const wchar_t *value) { SetString(value); }
MakeArg(const std::wstring &value) { SetString(value); }
MakeArg(WStringRef value) { SetString(value); }
MakeArg(wchar_t *value) { set_string(value); }
MakeArg(const wchar_t *value) { set_string(value); }
MakeArg(const std::wstring &value) { set_string(value); }
MakeArg(WStringRef value) { set_string(value); }
MakeArg(void *value) { type = POINTER; pointer_value = value; }
MakeArg(const void *value) { type = POINTER; pointer_value = value; }
@ -702,7 +710,7 @@ public:
MakeArg(const T &value) {
type = CUSTOM;
custom.value = &value;
custom.format = &internal::FormatCustomArg<Char, T>;
custom.format = &format_custom_arg<T>;
}
};
@ -1364,7 +1372,7 @@ class BasicWriter {
}
BasicWriter &operator<<(wchar_t value) {
*GrowBuffer(1) = internal::CharTraits<Char>::ConvertChar(value);
*GrowBuffer(1) = internal::CharTraits<Char>::convert(value);
return *this;
}
@ -1380,7 +1388,7 @@ class BasicWriter {
template <typename T, typename Spec, typename FillChar>
BasicWriter &operator<<(const IntFormatSpec<T, Spec, FillChar> &spec) {
internal::CharTraits<Char>::ConvertChar(FillChar());
internal::CharTraits<Char>::convert(FillChar());
FormatInt(spec.value(), spec);
return *this;
}
@ -1575,15 +1583,6 @@ void format(BasicWriter<Char> &w, const FormatSpec &spec, const T &value) {
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.
// Can be used to report errors from destructors.
void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true);

View File

@ -56,6 +56,9 @@ std::string GetSystemErrorMessage(int error_code) {
return buffer;
#endif
}
struct Test {};
std::ostream &operator<<(std::ostream &os, Test) { return os << "test"; }
}
TEST(UtilTest, Increment) {
@ -173,7 +176,17 @@ TEST(UtilTest, MakeArg) {
EXPECT_ARGW(WSTRING, std::wstring, 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.