Restructure printf_arg_formatter to make it customizable

This commit is contained in:
ToolsDevler
2019-04-11 11:05:55 +02:00
committed by Victor Zverovich
parent 5d755d0a4e
commit 2b415b7af7
2 changed files with 78 additions and 17 deletions
+48
View File
@@ -554,3 +554,51 @@ TEST(PrintfTest, VSPrintfMakeWArgsExample) {
fmt::make_wprintf_args(42, L"something")));
#endif
}
typedef fmt::printf_arg_formatter<
fmt::back_insert_range<fmt::internal::buffer<char>>> formatter_t;
typedef fmt::basic_printf_context<formatter_t::iterator, char> context_t;
// A custom printf argument formatter that doesn't print `-` for floating-point
// values rounded to 0.
class custom_printf_arg_formatter : public formatter_t {
public:
using formatter_t::iterator;
custom_printf_arg_formatter(formatter_t::iterator iter, formatter_t::format_specs& spec, context_t& ctx)
: formatter_t(iter, spec, ctx) {}
using formatter_t::operator();
#if FMT_MSC_VER > 0 && FMT_MSC_VER <= 1804
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
iterator operator()(T value) {
#else
iterator operator()(double value) {
#endif
// Comparing a float to 0.0 is safe.
if (round(value * pow(10, spec()->precision)) == 0.0) value = 0;
return formatter_t::operator()(value);
}
};
typedef fmt::basic_format_args<context_t> format_args_t;
std::string custom_vformat(fmt::string_view format_str, format_args_t args) {
fmt::memory_buffer buffer;
fmt::vprintf<custom_printf_arg_formatter>(buffer, format_str, args);
return std::string(buffer.data(), buffer.size());
}
template <typename... Args>
std::string custom_format(const char* format_str, const Args&... args) {
auto va = fmt::make_printf_args (args...);
return custom_vformat(format_str, va);
}
TEST(CustomFormatterTest, Format) {
EXPECT_EQ("0.00", custom_format("%.2f", -.00001));
EXPECT_EQ("0.00", custom_format("%.2f", .00001));
EXPECT_EQ("1.00", custom_format("%.2f", 1.00001));
EXPECT_EQ("-1.00", custom_format("%.2f", -1.00001));
}