Add fmt::print. Undocument and deprecate old API.

This commit is contained in:
Victor Zverovich 2014-06-28 19:44:39 -07:00
parent 8dbfd723b6
commit 2e03963e9e
2 changed files with 52 additions and 92 deletions

View File

@ -1105,6 +1105,12 @@ void fmt::ANSITerminalSink::operator()(
std::fputs(RESET_COLOR, file_); std::fputs(RESET_COLOR, file_);
} }
void fmt::print(StringRef format, const ArgList &args) {
Writer w;
w.format(format, args);
std::fwrite(w.data(), 1, w.size(), stdout);
}
// Explicit instantiations for char. // Explicit instantiations for char.
template fmt::BasicWriter<char>::CharPtr template fmt::BasicWriter<char>::CharPtr

138
format.h
View File

@ -1241,7 +1241,24 @@ class BasicWriter {
return p; return p;
} }
// "Move" constructors. /**
\rst
A "move" constructor. Constructs a writer transferring the buffer
from other to this object. This constructor is used to return a
writer object from a formatting function since the copy constructor
taking a const reference is disabled to prevent misuse of the API.
It is not implemented as a move constructor for compatibility with
pre-C++11 compilers, but should be treated as such.
**Example**::
fmt::Writer format(fmt::StringRef format, const fmt::ArgList &args) {
fmt::Writer w;
w.format(format, args);
return move(w);
}
\endrst
*/
BasicWriter(BasicWriter &other) { buffer_.move(other.buffer_); } BasicWriter(BasicWriter &other) { buffer_.move(other.buffer_); }
BasicWriter(Proxy p) { buffer_.move(*p.buffer); } BasicWriter(Proxy p) { buffer_.move(*p.buffer); }
#endif #endif
@ -1730,40 +1747,14 @@ inline const wchar_t *c_str(WStringRef s) {
return s.c_str(); return s.c_str();
} }
/** // This class is deprecated. Use variadic functions instead of sinks.
A sink that discards all output written to it.
*/
class NullSink { class NullSink {
public: public:
/** Discards the output. */
template <typename Char> template <typename Char>
void operator()(const BasicWriter<Char> &) const {} void operator()(const BasicWriter<Char> &) const {}
}; };
/** // This class is deprecated. Use variadic functions instead.
\rst
A formatter that sends output to a sink. Objects of this class normally
exist only as temporaries returned by one of the formatting functions.
You can use this class to create your own functions similar to
:cpp:func:`fmt::Format()`.
**Example**::
struct ErrorSink {
void operator()(const fmt::Writer &w) const {
fmt::Print("Error: {}\n") << w.str();
}
};
// Formats an error message and prints it to stdout.
fmt::Formatter<ErrorSink> ReportError(const char *format) {
fmt::Formatter f<ErrorSink>(format);
return f;
}
ReportError("File not found: {}") << path;
\endrst
*/
template <typename Sink = NullSink, typename Char = char> template <typename Sink = NullSink, typename Char = char>
class Formatter : private Sink, public BasicFormatter<Char> { class Formatter : private Sink, public BasicFormatter<Char> {
private: private:
@ -1773,47 +1764,17 @@ class Formatter : private Sink, public BasicFormatter<Char> {
FMT_DISALLOW_COPY_AND_ASSIGN(Formatter); FMT_DISALLOW_COPY_AND_ASSIGN(Formatter);
public: public:
/**
\rst
Constructs a formatter with a format string and a sink.
The sink should be an unary function object that takes a const
reference to :cpp:class:`fmt::BasicWriter`, representing the
formatting output, as an argument. See :cpp:class:`fmt::NullSink`
and :cpp:class:`fmt::FileSink` for examples of sink classes.
\endrst
*/
explicit Formatter(BasicStringRef<Char> format, Sink s = Sink()) explicit Formatter(BasicStringRef<Char> format, Sink s = Sink())
: Sink(s), BasicFormatter<Char>(writer_, format.c_str()), : Sink(s), BasicFormatter<Char>(writer_, format.c_str()),
inactive_(false) { inactive_(false) {
} }
/**
\rst
A "move" constructor. Constructs a formatter transferring the format
string from other to this object. This constructor is used to return
a formatter object from a formatting function since the copy constructor
taking a const reference is disabled to prevent misuse of the API.
It is not implemented as a move constructor for compatibility with
pre-C++11 compilers, but should be treated as such.
**Example**::
fmt::Formatter<> Format(fmt::StringRef format) {
fmt::Formatter<> f(format);
return f;
}
\endrst
*/
Formatter(Formatter &other) Formatter(Formatter &other)
: Sink(other), BasicFormatter<Char>(writer_, other.TakeFormatString()), : Sink(other), BasicFormatter<Char>(writer_, other.TakeFormatString()),
inactive_(false) { inactive_(false) {
other.inactive_ = true; other.inactive_ = true;
} }
/**
Performs the formatting, sends the output to the sink and destroys
the object.
*/
~Formatter() FMT_NOEXCEPT(false) { ~Formatter() FMT_NOEXCEPT(false) {
if (!inactive_) { if (!inactive_) {
this->CompleteFormatting(); this->CompleteFormatting();
@ -1836,10 +1797,7 @@ inline Formatter<NullSink, wchar_t> Format(WStringRef format) {
return f; return f;
} }
/** // This class is deprecated. Use variadic functions instead of sinks.
A sink that gets the error message corresponding to a system error code
as given by errno and throws SystemError.
*/
class SystemErrorSink { class SystemErrorSink {
private: private:
int error_code_; int error_code_;
@ -1871,10 +1829,7 @@ void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true);
#ifdef _WIN32 #ifdef _WIN32
/** // This class is deprecated. Use variadic functions instead of sinks.
A sink that gets the error message corresponding to a Windows error code
as given by GetLastError and throws SystemError.
*/
class WinErrorSink { class WinErrorSink {
private: private:
int error_code_; int error_code_;
@ -1907,7 +1862,7 @@ void ReportWinError(int error_code, StringRef message) FMT_NOEXCEPT(true);
#endif #endif
/** A sink that writes output to a file. */ // This class is deprecated. Use variadic functions instead of sinks.
class FileSink { class FileSink {
private: private:
std::FILE *file_; std::FILE *file_;
@ -1915,7 +1870,6 @@ class FileSink {
public: public:
explicit FileSink(std::FILE *f) : file_(f) {} explicit FileSink(std::FILE *f) : file_(f) {}
/** Writes the output to a file. */
void operator()(const BasicWriter<char> &w) const { void operator()(const BasicWriter<char> &w) const {
if (std::fwrite(w.data(), w.size(), 1, file_) == 0) if (std::fwrite(w.data(), w.size(), 1, file_) == 0)
ThrowSystemError(errno, "cannot write to file"); ThrowSystemError(errno, "cannot write to file");
@ -1952,10 +1906,7 @@ inline Formatter<FileSink> Print(std::FILE *file, StringRef format) {
enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
/** // This class is deprecated. Use variadic functions instead of sinks.
A sink that writes output to a terminal using ANSI escape sequences
to specify color.
*/
class ANSITerminalSink { class ANSITerminalSink {
private: private:
std::FILE *file_; std::FILE *file_;
@ -1964,10 +1915,6 @@ class ANSITerminalSink {
public: public:
ANSITerminalSink(std::FILE *f, Color c) : file_(f), color_(c) {} ANSITerminalSink(std::FILE *f, Color c) : file_(f), color_(c) {}
/**
Writes the output to a terminal using ANSI escape sequences to
specify color.
*/
void operator()(const BasicWriter<char> &w) const; void operator()(const BasicWriter<char> &w) const;
}; };
@ -2014,6 +1961,8 @@ inline WWriter format(WStringRef format, const ArgList &args) {
return move(w); return move(w);
} }
void print(StringRef format, const ArgList &args);
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES #if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
template <typename Char> template <typename Char>
@ -2045,6 +1994,10 @@ inline WWriter Format(WStringRef format, const Args & ... args) {
return std::move(w); return std::move(w);
} }
// This function is deprecated, use fmt::print instead.
template<typename... Args>
FMT_DEPRECATED(void Print(StringRef format, const Args & ... args));
template<typename... Args> template<typename... Args>
void Print(StringRef format, const Args & ... args) { void Print(StringRef format, const Args & ... args) {
Writer w; Writer w;
@ -2207,21 +2160,6 @@ inline void FormatDec(char *&buffer, T value) {
#if FMT_USE_VARIADIC_TEMPLATES #if FMT_USE_VARIADIC_TEMPLATES
/**
Defines a variadic function with the specified return type and argument
types passed as variable arguments.
Example::
std::string FormatMessage(int id, const char *format,
const fmt::ArgList &args) {
fmt::Writer w;
w.format("[{}] ", id);
w.format(format, args);
return w.str();
}
FMT_VARIADIC(std::string, FormatMessage, int, const char *)
*/
# define FMT_VARIADIC_(Char, ReturnType, func, ...) \ # define FMT_VARIADIC_(Char, ReturnType, func, ...) \
template<typename... Args> \ template<typename... Args> \
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
@ -2264,6 +2202,21 @@ inline void FormatDec(char *&buffer, T value) {
#endif // FMT_USE_VARIADIC_TEMPLATES #endif // FMT_USE_VARIADIC_TEMPLATES
/**
Defines a variadic function with the specified return type and argument
types passed as variable arguments.
Example::
std::string FormatMessage(int id, const char *format,
const fmt::ArgList &args) {
fmt::Writer w;
w.format("[{}] ", id);
w.format(format, args);
return w.str();
}
FMT_VARIADIC(std::string, FormatMessage, int, const char *)
*/
#define FMT_VARIADIC(ReturnType, func, ...) \ #define FMT_VARIADIC(ReturnType, func, ...) \
FMT_VARIADIC_(char, ReturnType, func, __VA_ARGS__) FMT_VARIADIC_(char, ReturnType, func, __VA_ARGS__)
@ -2273,6 +2226,7 @@ inline void FormatDec(char *&buffer, T value) {
namespace fmt { namespace fmt {
FMT_VARIADIC(fmt::Writer, format, fmt::StringRef) FMT_VARIADIC(fmt::Writer, format, fmt::StringRef)
FMT_VARIADIC_W(fmt::WWriter, format, fmt::WStringRef) FMT_VARIADIC_W(fmt::WWriter, format, fmt::WStringRef)
FMT_VARIADIC(void, print, fmt::StringRef)
} }
// Restore warnings. // Restore warnings.