From 0028ce57b63f42d0955ef6c14ae60262573637d2 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Fri, 26 Aug 2016 17:23:13 -0700 Subject: [PATCH] Get rid of FMT_VARIADIC --- fmt/format.cc | 15 ++++---- fmt/format.h | 70 ++++++++++++++--------------------- fmt/ostream.cc | 3 +- fmt/ostream.h | 10 ++++- fmt/posix.h | 11 ++++-- fmt/printf.h | 65 ++++++++++++++++++++++---------- test/custom-formatter-test.cc | 18 +++++++-- test/format-test.cc | 18 ++++++--- test/macro-test.cc | 21 ----------- 9 files changed, 127 insertions(+), 104 deletions(-) diff --git a/fmt/format.cc b/fmt/format.cc index c4d67d56..5137feb4 100644 --- a/fmt/format.cc +++ b/fmt/format.cc @@ -483,28 +483,29 @@ FMT_FUNC void report_windows_error( } #endif -FMT_FUNC void print(std::FILE *f, CStringRef format_str, format_args args) { +FMT_FUNC void vprint(std::FILE *f, CStringRef format_str, format_args args) { MemoryWriter w; w.write(format_str, args); std::fwrite(w.data(), 1, w.size(), f); } -FMT_FUNC void print(CStringRef format_str, format_args args) { - print(stdout, format_str, args); +FMT_FUNC void vprint(CStringRef format_str, format_args args) { + vprint(stdout, format_str, args); } -FMT_FUNC void print_colored(Color c, CStringRef format, format_args args) { +FMT_FUNC void vprint_colored(Color c, CStringRef format, format_args args) { char escape[] = "\x1b[30m"; escape[3] = static_cast('0' + c); std::fputs(escape, stdout); - print(format, args); + vprint(format, args); std::fputs(RESET_COLOR, stdout); } template -void printf(BasicWriter &w, BasicCStringRef format, format_args args); +void printf(BasicWriter &w, BasicCStringRef format, + format_args args); -FMT_FUNC int fprintf(std::FILE *f, CStringRef format, format_args args) { +FMT_FUNC int vfprintf(std::FILE *f, CStringRef format, format_args args) { MemoryWriter w; printf(w, format, args); std::size_t size = w.size(); diff --git a/fmt/format.h b/fmt/format.h index e05fa09f..b2645b63 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3116,13 +3116,20 @@ FMT_API void report_windows_error(int error_code, enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; +FMT_API void vprint_colored(Color c, CStringRef format, format_args args); + /** Formats a string and prints it to stdout using ANSI escape sequences to specify color (experimental). Example: print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); */ -FMT_API void print_colored(Color c, CStringRef format, format_args args); +template +inline void print_colored(Color c, CStringRef format_str, + const Args & ... args) { + vprint_colored(c, format_str, + internal::make_format_args>(args...)); +} inline std::string vformat(CStringRef format_str, format_args args) { MemoryWriter w; @@ -3145,12 +3152,20 @@ inline std::string format(CStringRef format_str, const Args & ... args) { return vformat(format_str, vargs); } -inline std::wstring format(WCStringRef format_str, format_args args) { +inline std::wstring vformat(WCStringRef format_str, format_args args) { WMemoryWriter w; w.write(format_str, args); return w.str(); } +template +inline std::wstring format(WCStringRef format_str, const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vformat(format_str, vargs); +} + +FMT_API void vprint(std::FILE *f, CStringRef format_str, format_args args); + /** \rst Prints formatted data to the file *f*. @@ -3160,7 +3175,13 @@ inline std::wstring format(WCStringRef format_str, format_args args) { print(stderr, "Don't {}!", "panic"); \endrst */ -FMT_API void print(std::FILE *f, CStringRef format_str, format_args args); +template +inline void print(std::FILE *f, CStringRef format_str, const Args & ... args) { + vprint(f, format_str, + internal::make_format_args>(args...)); +} + +FMT_API void vprint(CStringRef format_str, format_args args); /** \rst @@ -3171,7 +3192,10 @@ FMT_API void print(std::FILE *f, CStringRef format_str, format_args args); print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ -FMT_API void print(CStringRef format_str, format_args args); +template +inline void print(CStringRef format_str, const Args & ... args) { + vprint(format_str, internal::make_format_args>(args...)); +} /** Fast integer formatter. @@ -3340,39 +3364,6 @@ void arg(WStringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::format_args(store)); \ } -/** - \rst - Defines a variadic function with the specified return type, function name - and argument types passed as variable arguments to this macro. - - **Example**:: - - void print_error(const char *file, int line, const char *format, - fmt::format_args args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args); - } - FMT_VARIADIC(void, print_error, const char *, int, const char *) - - ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that - don't implement variadic templates. You don't have to use this macro if - you don't need legacy compiler support and can use variadic templates - directly:: - - template - void print_error(const char *file, int line, const char *format, - const Args & ... args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args...); - } - \endrst - */ -#define FMT_VARIADIC(ReturnType, func, ...) \ - FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) - -#define FMT_VARIADIC_W(ReturnType, func, ...) \ - FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) - #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id) #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id) @@ -3396,11 +3387,6 @@ void arg(WStringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__) namespace fmt { -FMT_VARIADIC_W(std::wstring, format, WCStringRef) -FMT_VARIADIC(void, print, CStringRef) -FMT_VARIADIC(void, print, std::FILE *, CStringRef) -FMT_VARIADIC(void, print_colored, Color, CStringRef) - namespace internal { template inline bool is_name_start(Char c) { diff --git a/fmt/ostream.cc b/fmt/ostream.cc index 92b00a09..9719d248 100644 --- a/fmt/ostream.cc +++ b/fmt/ostream.cc @@ -27,7 +27,8 @@ FMT_FUNC void write(std::ostream &os, Writer &w) { } } -FMT_FUNC void print(std::ostream &os, CStringRef format_str, format_args args) { +FMT_FUNC void vprint(std::ostream &os, CStringRef format_str, + format_args args) { MemoryWriter w; w.write(format_str, args); internal::write(os, w); diff --git a/fmt/ostream.h b/fmt/ostream.h index db433ea0..89b4b872 100644 --- a/fmt/ostream.h +++ b/fmt/ostream.h @@ -86,6 +86,8 @@ void format_arg(BasicFormatter &f, format_str = f.format(format_str, MakeArg(str)); } +FMT_API void vprint(std::ostream &os, CStringRef format_str, format_args args); + /** \rst Prints formatted data to the stream *os*. @@ -95,8 +97,12 @@ void format_arg(BasicFormatter &f, print(cerr, "Don't {}!", "panic"); \endrst */ -FMT_API void print(std::ostream &os, CStringRef format_str, format_args args); -FMT_VARIADIC(void, print, std::ostream &, CStringRef) +template +inline void print(std::ostream &os, CStringRef format_str, + const Args & ... args) { + vprint(os, format_str, + internal::make_format_args>(args...)); +} } // namespace fmt #ifdef FMT_HEADER_ONLY diff --git a/fmt/posix.h b/fmt/posix.h index e6b2e900..78e72050 100644 --- a/fmt/posix.h +++ b/fmt/posix.h @@ -166,10 +166,15 @@ public: // of MinGW that define fileno as a macro. int (fileno)() const; - void print(CStringRef format_str, const format_args &args) { - fmt::print(file_, format_str, args); + void vprint(CStringRef format_str, const format_args &args) { + fmt::vprint(file_, format_str, args); + } + + template + inline void print(CStringRef format_str, const Args & ... args) { + vprint(format_str, + internal::make_format_args>(args...)); } - FMT_VARIADIC(void, print, CStringRef) }; // A file. Closed file is represented by a File object with descriptor -1. diff --git a/fmt/printf.h b/fmt/printf.h index 9be2c424..3d5507cd 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -484,10 +484,17 @@ void PrintfFormatter::format(BasicCStringRef format_str) { } template -void printf(BasicWriter &w, BasicCStringRef format, format_args args) { +void printf(BasicWriter &w, BasicCStringRef format, + format_args args) { PrintfFormatter(args, w).format(format); } +inline std::string vsprintf(CStringRef format, format_args args) { + MemoryWriter w; + printf(w, format, args); + return w.str(); +} + /** \rst Formats arguments and returns the result as a string. @@ -497,19 +504,25 @@ void printf(BasicWriter &w, BasicCStringRef format, format_args args std::string message = fmt::sprintf("The answer is %d", 42); \endrst */ -inline std::string sprintf(CStringRef format, format_args args) { - MemoryWriter w; - printf(w, format, args); - return w.str(); +template +inline std::string sprintf(CStringRef format_str, const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vsprintf(format_str, vargs); } -FMT_VARIADIC(std::string, sprintf, CStringRef) -inline std::wstring sprintf(WCStringRef format, format_args args) { +inline std::wstring vsprintf(WCStringRef format, format_args args) { WMemoryWriter w; printf(w, format, args); return w.str(); } -FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) + +template +inline std::wstring sprintf(WCStringRef format_str, const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vsprintf(format_str, vargs); +} + +FMT_API int vfprintf(std::FILE *f, CStringRef format, format_args args); /** \rst @@ -520,8 +533,15 @@ FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) fmt::fprintf(stderr, "Don't %s!", "panic"); \endrst */ -FMT_API int fprintf(std::FILE *f, CStringRef format, format_args args); -FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) +template +inline int fprintf(std::FILE *f, CStringRef format_str, const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vfprintf(f, format_str, vargs); +} + +inline int vprintf(CStringRef format, format_args args) { + return vfprintf(stdout, format, args); +} /** \rst @@ -532,10 +552,18 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) fmt::printf("Elapsed time: %.2f seconds", 1.23); \endrst */ -inline int printf(CStringRef format, format_args args) { - return fprintf(stdout, format, args); +template +inline int printf(CStringRef format_str, const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vprintf(format_str, vargs); +} + +inline int vfprintf(std::ostream &os, CStringRef format_str, format_args args) { + MemoryWriter w; + printf(w, format_str, args); + internal::write(os, w); + return static_cast(w.size()); } -FMT_VARIADIC(int, printf, CStringRef) /** \rst @@ -546,13 +574,12 @@ FMT_VARIADIC(int, printf, CStringRef) fprintf(cerr, "Don't %s!", "panic"); \endrst */ -inline int fprintf(std::ostream &os, CStringRef format_str, format_args args) { - MemoryWriter w; - printf(w, format_str, args); - internal::write(os, w); - return static_cast(w.size()); +template +inline int fprintf(std::ostream &os, CStringRef format_str, + const Args & ... args) { + auto vargs = internal::make_format_args>(args...); + return vfprintf(os, format_str, vargs); } -FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) } // namespace fmt #endif // FMT_PRINTF_H_ diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc index 436986c1..2bcc1d65 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -45,22 +45,32 @@ class CustomPrintfArgFormatter : } }; -std::string custom_format(const char *format_str, fmt::format_args args) { +std::string vcustom_format(const char *format_str, fmt::format_args args) { fmt::MemoryWriter writer; // Pass custom argument formatter as a template arg to BasicFormatter. fmt::BasicFormatter formatter(args, writer); formatter.format(format_str); return writer.str(); } -FMT_VARIADIC(std::string, custom_format, const char *) -std::string custom_sprintf(const char* format_str, fmt::format_args args){ +template +std::string custom_format(const char *format_str, const Args & ... args) { + auto va = fmt::internal::make_format_args>(args...); + return vcustom_format(format_str, va); +} + +std::string vcustom_sprintf(const char* format_str, fmt::format_args args) { fmt::MemoryWriter writer; fmt::PrintfFormatter formatter(args, writer); formatter.format(format_str); return writer.str(); } -FMT_VARIADIC(std::string, custom_sprintf, const char*); + +template +std::string custom_sprintf(const char *format_str, const Args & ... args) { + auto va = fmt::internal::make_format_args>(args...); + return vcustom_sprintf(format_str, va); +} TEST(CustomFormatterTest, Format) { EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001)); diff --git a/test/format-test.cc b/test/format-test.cc index e18d136e..fef96b1f 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1563,15 +1563,18 @@ TEST(StrTest, Convert) { EXPECT_EQ("2012-12-9", s); } -std::string format_message(int id, const char *format, - const fmt::format_args &args) { +std::string vformat_message(int id, const char *format, fmt::format_args args) { MemoryWriter w; w.write("[{}] ", id); w.write(format, args); return w.str(); } -FMT_VARIADIC(std::string, format_message, int, const char *) +template +std::string format_message(int id, const char *format, const Args & ... args) { + auto va = fmt::internal::make_format_args>(args...); + return vformat_message(id, format, va); +} TEST(FormatTest, FormatMessageExample) { EXPECT_EQ("[42] something happened", @@ -1643,12 +1646,17 @@ class MockArgFormatter : MOCK_METHOD1(visit_int, void (int value)); }; -void custom_format(const char *format_str, fmt::format_args args) { +void vcustom_format(const char *format_str, fmt::format_args args) { fmt::MemoryWriter writer; fmt::BasicFormatter formatter(args, writer); formatter.format(format_str); } -FMT_VARIADIC(void, custom_format, const char *) + +template +void custom_format(const char *format_str, const Args & ... args) { + auto va = fmt::internal::make_format_args>(args...); + return vcustom_format(format_str, va); +} TEST(FormatTest, CustomArgFormatter) { custom_format("{}", 42); diff --git a/test/macro-test.cc b/test/macro-test.cc index ed35151b..b39fc495 100644 --- a/test/macro-test.cc +++ b/test/macro-test.cc @@ -85,24 +85,3 @@ TEST(UtilTest, VariadicVoid) { test_variadic_void("", 10, 20, 30, 40, 50, 60, 70, 80, 90, 100); EXPECT_EQ(550, result); } - -template -struct S {}; - -#define GET_TYPE(n) S - -int test_variadic(FMT_GEN(10, GET_TYPE), const fmt::format_args &args) { \ - int result = 0; \ - for (unsigned i = 0; args[i].type; ++i) \ - result += args[i].int_value; \ - return result; -} -FMT_VARIADIC(int, test_variadic, - S<0>, S<1>, S<2>, S<3>, S<4>, S<5>, S<6>, S<7>, S<8>, S<9>) - -#define MAKE_ARG(n) S() - -TEST(UtilTest, Variadic) { - EXPECT_EQ(550, test_variadic(FMT_GEN(10, MAKE_ARG), - 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)); -}