Implement printing of values that are convertible to int such as enums

This commit is contained in:
Victor Zverovich 2015-03-10 07:53:46 -07:00
parent 08d759c425
commit 5821aec7b9
3 changed files with 43 additions and 2 deletions

View File

@ -766,6 +766,26 @@ struct WCharHelper<T, wchar_t> {
typedef None<T> Unsupported;
};
template <typename T>
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<bool B, class T = void>
struct EnableIf {};
template<class T>
struct EnableIf<true, T> { typedef T type; };
// Makes a Value object from any type.
template <typename Char>
class MakeValue : public Value {
@ -885,12 +905,22 @@ class MakeValue : public Value {
FMT_MAKE_VALUE(const void *, pointer, POINTER)
template <typename T>
MakeValue(const T &value) {
MakeValue(const T &value,
typename EnableIf<!IsConvertibleToInt<T>::value, int>::type = 0) {
custom.value = &value;
custom.format = &format_custom_arg<T>;
}
template <typename T>
static uint64_t type(const T &) { return Arg::CUSTOM; }
MakeValue(const T &value,
typename EnableIf<IsConvertibleToInt<T>::value, int>::type = 0) {
int_value = value;
}
template <typename T>
static uint64_t type(const T &) {
return IsConvertibleToInt<T>::value ? Arg::INT : Arg::CUSTOM;
}
};
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call

View File

@ -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";

View File

@ -832,3 +832,8 @@ TEST(UtilTest, ReportWindowsError) {
}
#endif // _WIN32
TEST(UtilTest, IsConvertibleToInt) {
EXPECT_TRUE(fmt::internal::IsConvertibleToInt<char>::value);
EXPECT_FALSE(fmt::internal::IsConvertibleToInt<const char *>::value);
}