Refactor action classes, Action -> Sink, add comments.
This commit is contained in:
parent
d2bf073334
commit
d9db89814f
@ -1479,32 +1479,43 @@ TEST(StringRefTest, ConvertToString) {
|
|||||||
EXPECT_EQ("abc", s);
|
EXPECT_EQ("abc", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CountCalls {
|
TEST(FormatterTest, Ctor) {
|
||||||
int &num_calls;
|
fmt::Formatter<> f1("test");
|
||||||
|
fmt::Formatter<> f1copy(f1);
|
||||||
|
fmt::Formatter<> f2("test", fmt::NullSink());
|
||||||
|
fmt::Formatter<fmt::NullSink> f3("test");
|
||||||
|
fmt::Formatter<fmt::NullSink, wchar_t> f4(L"test");
|
||||||
|
fmt::Formatter<fmt::NullSink, wchar_t> f4copy(f4);
|
||||||
|
fmt::Formatter<fmt::NullSink, wchar_t> f5(L"test", fmt::NullSink());
|
||||||
|
}
|
||||||
|
|
||||||
CountCalls(int &num_calls) : num_calls(num_calls) {}
|
// A sink that counts the number of times the output is written to it.
|
||||||
|
struct CountingSink {
|
||||||
|
int &num_writes;
|
||||||
|
|
||||||
|
explicit CountingSink(int &num_calls) : num_writes(num_writes) {}
|
||||||
|
|
||||||
void operator()(const Writer &) const {
|
void operator()(const Writer &) const {
|
||||||
++num_calls;
|
++num_writes;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(FormatterTest, Action) {
|
TEST(FormatterTest, Sink) {
|
||||||
int num_calls = 0;
|
int num_writes = 0;
|
||||||
{
|
{
|
||||||
fmt::Formatter<CountCalls> af("test", CountCalls(num_calls));
|
fmt::Formatter<CountingSink> f("test", CountingSink(num_writes));
|
||||||
EXPECT_EQ(0, num_calls);
|
EXPECT_EQ(0, num_writes);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(1, num_calls);
|
EXPECT_EQ(1, num_writes);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, ActionNotCalledOnError) {
|
TEST(FormatterTest, OutputNotWrittenOnError) {
|
||||||
int num_calls = 0;
|
int num_writes = 0;
|
||||||
{
|
{
|
||||||
typedef fmt::Formatter<CountCalls> TestFormatter;
|
typedef fmt::Formatter<CountingSink> TestFormatter;
|
||||||
EXPECT_THROW(TestFormatter af("{0", CountCalls(num_calls)), FormatError);
|
EXPECT_THROW(TestFormatter f("{0", CountingSink(num_writes)), FormatError);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, num_calls);
|
EXPECT_EQ(0, num_writes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The test doesn't compile on older compilers which follow C++03 and
|
// The test doesn't compile on older compilers which follow C++03 and
|
||||||
@ -1641,7 +1652,7 @@ class File {
|
|||||||
int fd() const { return fd_; }
|
int fd() const { return fd_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(ColorTest, PrintColored) {
|
TEST(FormatTest, PrintColored) {
|
||||||
std::fflush(stdout);
|
std::fflush(stdout);
|
||||||
File saved_stdio(dup(1));
|
File saved_stdio(dup(1));
|
||||||
EXPECT_NE(-1, saved_stdio.fd());
|
EXPECT_NE(-1, saved_stdio.fd());
|
||||||
@ -1661,6 +1672,13 @@ TEST(ColorTest, PrintColored) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
||||||
|
TEST(FormatTest, Variadic) {
|
||||||
|
EXPECT_EQ("Hello, world!1", str(Format("Hello, {}!{}", "world", 1)));
|
||||||
|
EXPECT_EQ(L"Hello, world!1", str(Format(L"Hello, {}!{}", L"world", 1)));
|
||||||
|
}
|
||||||
|
#endif // FMT_USE_VARIADIC_TEMPLATES
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string str(const T &value) {
|
std::string str(const T &value) {
|
||||||
return fmt::str(fmt::Format("{0}") << value);
|
return fmt::str(fmt::Format("{0}") << value);
|
||||||
@ -1672,13 +1690,6 @@ TEST(StrTest, Convert) {
|
|||||||
EXPECT_EQ("2012-12-9", s);
|
EXPECT_EQ("2012-12-9", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
|
||||||
TEST(FormatTest, Variadic) {
|
|
||||||
EXPECT_EQ("Hello, world!1", str(Format("Hello, {}!{}", "world", 1)));
|
|
||||||
EXPECT_EQ(L"Hello, world!1", str(Format(L"Hello, {}!{}", L"world", 1)));
|
|
||||||
}
|
|
||||||
#endif // FMT_USE_VARIADIC_TEMPLATES
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Disable message boxes on assertion failures.
|
// Disable message boxes on assertion failures.
|
||||||
|
@ -688,12 +688,13 @@ void fmt::BasicWriter<Char>::FormatParser::Format(
|
|||||||
writer.buffer_.append(start, s);
|
writer.buffer_.append(start, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::ColorWriter::operator()(const fmt::BasicWriter<char> &w) const {
|
void fmt::ANSITerminalSink::operator()(
|
||||||
|
const fmt::BasicWriter<char> &w) const {
|
||||||
char escape[] = "\x1b[30m";
|
char escape[] = "\x1b[30m";
|
||||||
escape[3] = '0' + static_cast<char>(color_);
|
escape[3] = '0' + static_cast<char>(color_);
|
||||||
std::fputs(escape, stdout);
|
std::fputs(escape, file_);
|
||||||
std::fwrite(w.data(), 1, w.size(), stdout);
|
std::fwrite(w.data(), 1, w.size(), file_);
|
||||||
std::fputs(RESET_COLOR, stdout);
|
std::fputs(RESET_COLOR, file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit instantiations for char.
|
// Explicit instantiations for char.
|
||||||
|
280
format.h
280
format.h
@ -805,13 +805,13 @@ class BasicWriter {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Argument action that does nothing.
|
// An argument action that does nothing.
|
||||||
struct EmptyArgAction {
|
struct NullArgAction {
|
||||||
void operator()() const {}
|
void operator()() const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A wrapper around a format argument.
|
// A wrapper around a format argument.
|
||||||
template <typename Action = EmptyArgAction>
|
template <typename Action = NullArgAction>
|
||||||
class BasicArg : public Action, public ArgInfo {
|
class BasicArg : public Action, public ArgInfo {
|
||||||
private:
|
private:
|
||||||
// This method is private to disallow formatting of arbitrary pointers.
|
// This method is private to disallow formatting of arbitrary pointers.
|
||||||
@ -1039,7 +1039,7 @@ class BasicWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a character to the stream.
|
Writes a character to the stream.
|
||||||
*/
|
*/
|
||||||
BasicWriter &operator<<(char value) {
|
BasicWriter &operator<<(char value) {
|
||||||
*GrowBuffer(1) = value;
|
*GrowBuffer(1) = value;
|
||||||
@ -1239,7 +1239,7 @@ class BasicFormatter {
|
|||||||
// Here an Arg object wraps a temporary std::string which is destroyed at
|
// Here an Arg object wraps a temporary std::string which is destroyed at
|
||||||
// the end of the full expression. Since the string object is constructed
|
// the end of the full expression. Since the string object is constructed
|
||||||
// before the Arg object, it will be destroyed after, so it will be alive
|
// before the Arg object, it will be destroyed after, so it will be alive
|
||||||
// in the Arg's destructor where the action is called.
|
// in the Arg's destructor where the action is invoked.
|
||||||
// Note that the string object will not necessarily be alive when the
|
// Note that the string object will not necessarily be alive when the
|
||||||
// destructor of BasicFormatter is called. Otherwise we wouldn't need
|
// destructor of BasicFormatter is called. Otherwise we wouldn't need
|
||||||
// this class.
|
// this class.
|
||||||
@ -1368,41 +1368,41 @@ inline const wchar_t *c_str(internal::FormatterProxy<wchar_t> p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A formatting action that does nothing.
|
A sink that ignores output.
|
||||||
*/
|
*/
|
||||||
class NoAction {
|
class NullSink {
|
||||||
public:
|
public:
|
||||||
/** Does nothing. */
|
/** Ignores the output. */
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void operator()(const BasicWriter<Char> &) const {}
|
void operator()(const BasicWriter<Char> &) const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
A formatter with an action performed when formatting is complete.
|
A formatter that sends output to a sink. Objects of this class normally
|
||||||
Objects of this class normally exist only as temporaries returned
|
exist only as temporaries returned by one of the formatting functions.
|
||||||
by one of the formatting functions. You can use this class to create
|
You can use this class to create your own functions similar to
|
||||||
your own functions similar to :cpp:func:`fmt::Format()`.
|
:cpp:func:`fmt::Format()`.
|
||||||
|
|
||||||
**Example**::
|
**Example**::
|
||||||
|
|
||||||
struct PrintError {
|
struct ErrorSink {
|
||||||
void operator()(const fmt::Writer &w) const {
|
void operator()(const fmt::Writer &w) const {
|
||||||
fmt::Print("Error: {}\n") << w.str();
|
fmt::Print("Error: {}\n") << w.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Formats an error message and prints it to stdout.
|
// Formats an error message and prints it to stdout.
|
||||||
fmt::Formatter<PrintError> ReportError(const char *format) {
|
fmt::Formatter<ErrorSink> ReportError(const char *format) {
|
||||||
fmt::Formatter f<PrintError>(format);
|
fmt::Formatter f<ErrorSink>(format);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportError("File not found: {}") << path;
|
ReportError("File not found: {}") << path;
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Action = NoAction, typename Char = char>
|
template <typename Sink = NullSink, typename Char = char>
|
||||||
class Formatter : private Action, public BasicFormatter<Char> {
|
class Formatter : private Sink, public BasicFormatter<Char> {
|
||||||
private:
|
private:
|
||||||
BasicWriter<Char> writer_;
|
BasicWriter<Char> writer_;
|
||||||
bool inactive_;
|
bool inactive_;
|
||||||
@ -1412,26 +1412,44 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Constructs a formatter with a format string and an action.
|
Constructs a formatter with a format string and a sink.
|
||||||
The action should be an unary function object that takes a const
|
The sink should be an unary function object that takes a const
|
||||||
reference to :cpp:class:`fmt::BasicWriter` as an argument.
|
reference to :cpp:class:`fmt::BasicWriter`, representing the
|
||||||
See :cpp:class:`fmt::NoAction` and :cpp:class:`fmt::Write` for
|
formatting output, as an argument. See :cpp:class:`fmt::NullSink`
|
||||||
examples of action classes.
|
and :cpp:class:`fmt::FileSink` for examples of sink classes.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
explicit Formatter(BasicStringRef<Char> format, Action a = Action())
|
explicit Formatter(BasicStringRef<Char> format, Sink s = Sink())
|
||||||
: Action(a), BasicFormatter<Char>(writer_, format.c_str()),
|
: Sink(s), BasicFormatter<Char>(writer_, format.c_str()),
|
||||||
inactive_(false) {
|
inactive_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Formatter(Formatter &f)
|
|
||||||
: Action(f), BasicFormatter<Char>(writer_, f.TakeFormatString()),
|
|
||||||
inactive_(false) {
|
|
||||||
f.inactive_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs the actual formatting, invokes the action and destroys the object.
|
\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)
|
||||||
|
: Sink(other), BasicFormatter<Char>(writer_, other.TakeFormatString()),
|
||||||
|
inactive_(false) {
|
||||||
|
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_) {
|
||||||
@ -1441,6 +1459,118 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Formats a string similarly to Python's `str.format
|
||||||
|
<http://docs.python.org/3/library/stdtypes.html#str.format>`__.
|
||||||
|
Returns a temporary formatter object that accepts arguments via
|
||||||
|
operator ``<<``.
|
||||||
|
|
||||||
|
*format* is a format string that contains literal text and replacement
|
||||||
|
fields surrounded by braces ``{}``. The formatter object replaces the
|
||||||
|
fields with formatted arguments and stores the output in a memory buffer.
|
||||||
|
The content of the buffer can be converted to ``std::string`` with
|
||||||
|
:cpp:func:`fmt::str()` or accessed as a C string with
|
||||||
|
:cpp:func:`fmt::c_str()`.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
std::string message = str(Format("The answer is {}") << 42);
|
||||||
|
|
||||||
|
See also `Format String Syntax`_.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
inline Formatter<> Format(StringRef format) {
|
||||||
|
Formatter<> f(format);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Formatter<NullSink, wchar_t> Format(WStringRef format) {
|
||||||
|
Formatter<NullSink, wchar_t> f(format);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A sink that writes output to a file. */
|
||||||
|
class FileSink {
|
||||||
|
private:
|
||||||
|
std::FILE *file_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSink(std::FILE *f) : file_(f) {}
|
||||||
|
|
||||||
|
/** Writes the output to a file. */
|
||||||
|
void operator()(const BasicWriter<char> &w) const {
|
||||||
|
// TODO: check error
|
||||||
|
std::fwrite(w.data(), w.size(), 1, file_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Formats a string and prints it to stdout.
|
||||||
|
// Example:
|
||||||
|
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
||||||
|
// TODO: wchar overload
|
||||||
|
inline Formatter<FileSink> Print(StringRef format) {
|
||||||
|
Formatter<FileSink> f(format, stdout);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
|
||||||
|
|
||||||
|
/**
|
||||||
|
A sink that writes output to a terminal using ANSI escape sequences
|
||||||
|
to specify color.
|
||||||
|
*/
|
||||||
|
class ANSITerminalSink {
|
||||||
|
private:
|
||||||
|
std::FILE *file_;
|
||||||
|
Color color_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Formats a string and prints it to stdout using ANSI escape sequences
|
||||||
|
to specify color (experimental).
|
||||||
|
Example:
|
||||||
|
PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
|
||||||
|
*/
|
||||||
|
inline Formatter<ANSITerminalSink> PrintColored(Color c, StringRef format) {
|
||||||
|
Formatter<ANSITerminalSink> f(format, ANSITerminalSink(stdout, c));
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
inline Writer Format(const StringRef &format, const Args & ... args) {
|
||||||
|
Writer w;
|
||||||
|
w.Format(format, args...);
|
||||||
|
return std::move(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
inline WWriter Format(const WStringRef &format, const Args & ... args) {
|
||||||
|
WWriter w;
|
||||||
|
w.Format(format, args...);
|
||||||
|
return std::move(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Print(StringRef format, const Args & ... args) {
|
||||||
|
Writer w;
|
||||||
|
w.Format(format, args...);
|
||||||
|
std::fwrite(w.data(), 1, w.size(), stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fast integer formatter.
|
Fast integer formatter.
|
||||||
*/
|
*/
|
||||||
@ -1473,7 +1603,7 @@ class FormatInt {
|
|||||||
*--buffer_end = internal::DIGITS[index];
|
*--buffer_end = internal::DIGITS[index];
|
||||||
return buffer_end;
|
return buffer_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormatSigned(LongLong value) {
|
void FormatSigned(LongLong value) {
|
||||||
ULongLong abs_value = value;
|
ULongLong abs_value = value;
|
||||||
bool negative = value < 0;
|
bool negative = value < 0;
|
||||||
@ -1542,92 +1672,6 @@ inline void FormatDec(char *&buffer, T value) {
|
|||||||
internal::FormatDecimal(buffer, abs_value, num_digits);
|
internal::FormatDecimal(buffer, abs_value, num_digits);
|
||||||
buffer += num_digits;
|
buffer += num_digits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Formats a string similarly to Python's `str.format
|
|
||||||
<http://docs.python.org/3/library/stdtypes.html#str.format>`__.
|
|
||||||
Returns a temporary formatter object that accepts arguments via
|
|
||||||
operator ``<<``.
|
|
||||||
|
|
||||||
*format* is a format string that contains literal text and replacement
|
|
||||||
fields surrounded by braces ``{}``. The formatter object replaces the
|
|
||||||
fields with formatted arguments and stores the output in a memory buffer.
|
|
||||||
The content of the buffer can be converted to ``std::string`` with
|
|
||||||
:cpp:func:`fmt::str()` or accessed as a C string with
|
|
||||||
:cpp:func:`fmt::c_str()`.
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
std::string message = str(Format("The answer is {}") << 42);
|
|
||||||
|
|
||||||
See also `Format String Syntax`_.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
inline Formatter<> Format(StringRef format) {
|
|
||||||
Formatter<> f(format);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Formatter<NoAction, wchar_t> Format(WStringRef format) {
|
|
||||||
Formatter<NoAction, wchar_t> f(format);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A formatting action that writes formatted output to stdout. */
|
|
||||||
class Write {
|
|
||||||
public:
|
|
||||||
/** Writes the output to stdout. */
|
|
||||||
void operator()(const BasicWriter<char> &w) const {
|
|
||||||
std::fwrite(w.data(), 1, w.size(), stdout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Formats a string and prints it to stdout.
|
|
||||||
// Example:
|
|
||||||
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
|
||||||
inline Formatter<Write> Print(StringRef format) {
|
|
||||||
Formatter<Write> f(format);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
|
|
||||||
|
|
||||||
/** A formatting action that writes colored output to stdout. */
|
|
||||||
class ColorWriter {
|
|
||||||
private:
|
|
||||||
Color color_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ColorWriter(Color c) : color_(c) {}
|
|
||||||
|
|
||||||
/** Writes the colored output to stdout. */
|
|
||||||
void operator()(const BasicWriter<char> &w) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Formats a string and prints it to stdout with the given color.
|
|
||||||
// Example:
|
|
||||||
// PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
|
|
||||||
inline Formatter<ColorWriter> PrintColored(Color c, StringRef format) {
|
|
||||||
Formatter<ColorWriter> f(format, ColorWriter(c));
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
|
||||||
template<typename... Args>
|
|
||||||
inline Writer Format(const StringRef &format, const Args & ... args) {
|
|
||||||
Writer w;
|
|
||||||
w.Format(format, args...);
|
|
||||||
return std::move(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
inline WWriter Format(const WStringRef &format, const Args & ... args) {
|
|
||||||
WWriter w;
|
|
||||||
w.Format(format, args...);
|
|
||||||
return std::move(w);
|
|
||||||
}
|
|
||||||
#endif // FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore warnings.
|
// Restore warnings.
|
||||||
|
Loading…
Reference in New Issue
Block a user