diff --git a/format.h b/format.h index 9c6bc906..fb414ca3 100644 --- a/format.h +++ b/format.h @@ -766,6 +766,26 @@ struct WCharHelper { typedef None Unsupported; }; +template +class IsConvertibleToInt { + private: + typedef char yes[1]; + typedef char no[2]; + + static const T &get(); + static yes &check(int); + static no &check(...); + + public: + enum { value = (sizeof(check(get())) == sizeof(yes)) }; +}; + +template +struct EnableIf {}; + +template +struct EnableIf { typedef T type; }; + // Makes a Value object from any type. template class MakeValue : public Value { @@ -885,12 +905,22 @@ class MakeValue : public Value { FMT_MAKE_VALUE(const void *, pointer, POINTER) template - MakeValue(const T &value) { + MakeValue(const T &value, + typename EnableIf::value, int>::type = 0) { custom.value = &value; custom.format = &format_custom_arg; } + template - static uint64_t type(const T &) { return Arg::CUSTOM; } + MakeValue(const T &value, + typename EnableIf::value, int>::type = 0) { + int_value = value; + } + + template + static uint64_t type(const T &) { + return IsConvertibleToInt::value ? Arg::INT : Arg::CUSTOM; + } }; #define FMT_DISPATCH(call) static_cast(this)->call diff --git a/test/printf-test.cc b/test/printf-test.cc index eeae701c..f174577c 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -430,6 +430,12 @@ TEST(PrintfTest, Location) { // TODO: test %n } +enum E { A = 42 }; + +TEST(PrintfTest, Enum) { + EXPECT_PRINTF("42", "%d", A); +} + #if FMT_USE_FILE_DESCRIPTORS TEST(PrintfTest, Examples) { const char *weekday = "Thursday"; diff --git a/test/util-test.cc b/test/util-test.cc index 17936576..92d22d35 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -832,3 +832,8 @@ TEST(UtilTest, ReportWindowsError) { } #endif // _WIN32 + +TEST(UtilTest, IsConvertibleToInt) { + EXPECT_TRUE(fmt::internal::IsConvertibleToInt::value); + EXPECT_FALSE(fmt::internal::IsConvertibleToInt::value); +}