Get rid of FMT_VARIADIC

This commit is contained in:
Victor Zverovich 2016-08-26 17:23:13 -07:00
parent ece7ae5f49
commit 0028ce57b6
9 changed files with 127 additions and 104 deletions

View File

@ -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<char>('0' + c);
std::fputs(escape, stdout);
print(format, args);
vprint(format, args);
std::fputs(RESET_COLOR, stdout);
}
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, format_args args);
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> 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();

View File

@ -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 <typename... Args>
inline void print_colored(Color c, CStringRef format_str,
const Args & ... args) {
vprint_colored(c, format_str,
internal::make_format_args<BasicFormatter<char>>(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 <typename... Args>
inline std::wstring format(WCStringRef format_str, const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<wchar_t>>(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 <typename... Args>
inline void print(std::FILE *f, CStringRef format_str, const Args & ... args) {
vprint(f, format_str,
internal::make_format_args<BasicFormatter<char>>(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 <typename... Args>
inline void print(CStringRef format_str, const Args & ... args) {
vprint(format_str, internal::make_format_args<BasicFormatter<char>>(args...));
}
/**
Fast integer formatter.
@ -3340,39 +3364,6 @@ void arg(WStringRef, const internal::NamedArg<Char>&) 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 <typename... Args>
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<Char>&) 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 <typename Char>
inline bool is_name_start(Char c) {

View File

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

View File

@ -86,6 +86,8 @@ void format_arg(BasicFormatter<Char, ArgFormatter> &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<Char, ArgFormatter> &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 <typename... Args>
inline void print(std::ostream &os, CStringRef format_str,
const Args & ... args) {
vprint(os, format_str,
internal::make_format_args<BasicFormatter<char>>(args...));
}
} // namespace fmt
#ifdef FMT_HEADER_ONLY

View File

@ -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 <typename... Args>
inline void print(CStringRef format_str, const Args & ... args) {
vprint(format_str,
internal::make_format_args<BasicFormatter<char>>(args...));
}
FMT_VARIADIC(void, print, CStringRef)
};
// A file. Closed file is represented by a File object with descriptor -1.

View File

@ -484,10 +484,17 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
}
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, format_args args) {
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format,
format_args args) {
PrintfFormatter<Char>(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<Char> &w, BasicCStringRef<Char> 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 <typename... Args>
inline std::string sprintf(CStringRef format_str, const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<char>>(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 <typename... Args>
inline std::wstring sprintf(WCStringRef format_str, const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<wchar_t>>(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 <typename... Args>
inline int fprintf(std::FILE *f, CStringRef format_str, const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<char>>(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 <typename... Args>
inline int printf(CStringRef format_str, const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<char>>(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<int>(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<int>(w.size());
template <typename... Args>
inline int fprintf(std::ostream &os, CStringRef format_str,
const Args & ... args) {
auto vargs = internal::make_format_args<BasicFormatter<char>>(args...);
return vfprintf(os, format_str, vargs);
}
FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt
#endif // FMT_PRINTF_H_

View File

@ -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<char, CustomArgFormatter> 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 <typename... Args>
std::string custom_format(const char *format_str, const Args & ... args) {
auto va = fmt::internal::make_format_args<fmt::BasicFormatter<char>>(args...);
return vcustom_format(format_str, va);
}
std::string vcustom_sprintf(const char* format_str, fmt::format_args args) {
fmt::MemoryWriter writer;
fmt::PrintfFormatter<char, CustomPrintfArgFormatter> formatter(args, writer);
formatter.format(format_str);
return writer.str();
}
FMT_VARIADIC(std::string, custom_sprintf, const char*);
template <typename... Args>
std::string custom_sprintf(const char *format_str, const Args & ... args) {
auto va = fmt::internal::make_format_args<fmt::BasicFormatter<char>>(args...);
return vcustom_sprintf(format_str, va);
}
TEST(CustomFormatterTest, Format) {
EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001));

View File

@ -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 <typename... Args>
std::string format_message(int id, const char *format, const Args & ... args) {
auto va = fmt::internal::make_format_args<fmt::BasicFormatter<char>>(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<char, MockArgFormatter> formatter(args, writer);
formatter.format(format_str);
}
FMT_VARIADIC(void, custom_format, const char *)
template <typename... Args>
void custom_format(const char *format_str, const Args & ... args) {
auto va = fmt::internal::make_format_args<fmt::BasicFormatter<char>>(args...);
return vcustom_format(format_str, va);
}
TEST(FormatTest, CustomArgFormatter) {
custom_format("{}", 42);

View File

@ -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 <int>
struct S {};
#define GET_TYPE(n) S<n>
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<n>()
TEST(UtilTest, Variadic) {
EXPECT_EQ(550, test_variadic(FMT_GEN(10, MAKE_ARG),
10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
}