mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Add fmt::format and deprecate fmt::Format.
This commit is contained in:
89
format.h
89
format.h
@ -139,6 +139,10 @@ namespace fmt {
|
|||||||
FMT_GCC_EXTENSION typedef long long LongLong;
|
FMT_GCC_EXTENSION typedef long long LongLong;
|
||||||
FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
|
FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
|
||||||
|
|
||||||
|
#if FMT_USE_RVALUE_REFERENCES
|
||||||
|
using std::move;
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicWriter;
|
class BasicWriter;
|
||||||
|
|
||||||
@ -156,11 +160,12 @@ struct FormatSpec;
|
|||||||
or as a result of a formatting operation. It is most useful as a parameter
|
or as a result of a formatting operation. It is most useful as a parameter
|
||||||
type to allow passing different types of strings in a function, for example::
|
type to allow passing different types of strings in a function, for example::
|
||||||
|
|
||||||
Formatter<> Format(StringRef format);
|
template<typename... Args>
|
||||||
|
Writer format(StringRef format, const Args & ... args);
|
||||||
|
|
||||||
Format("{}") << 42;
|
format("{}", 42);
|
||||||
Format(std::string("{}")) << 42;
|
format(std::string("{}"), 42);
|
||||||
Format(Format("{{}}")) << 42;
|
format(format("{{}}"), 42);
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -250,8 +255,14 @@ class Array {
|
|||||||
if (ptr_ != data_) delete [] ptr_;
|
if (ptr_ != data_) delete [] ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMT_DISALLOW_COPY_AND_ASSIGN(Array);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Array() : size_(0), capacity_(SIZE), ptr_(data_) {}
|
||||||
|
~Array() { Free(); }
|
||||||
|
|
||||||
// Move data from other to this array.
|
// Move data from other to this array.
|
||||||
void Move(Array &other) {
|
void move(Array &other) {
|
||||||
size_ = other.size_;
|
size_ = other.size_;
|
||||||
capacity_ = other.capacity_;
|
capacity_ = other.capacity_;
|
||||||
if (other.ptr_ == other.data_) {
|
if (other.ptr_ == other.data_) {
|
||||||
@ -265,21 +276,15 @@ class Array {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_DISALLOW_COPY_AND_ASSIGN(Array);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Array() : size_(0), capacity_(SIZE), ptr_(data_) {}
|
|
||||||
~Array() { Free(); }
|
|
||||||
|
|
||||||
#if FMT_USE_RVALUE_REFERENCES
|
#if FMT_USE_RVALUE_REFERENCES
|
||||||
Array(Array &&other) {
|
Array(Array &&other) {
|
||||||
Move(other);
|
move(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array& operator=(Array &&other) {
|
Array& operator=(Array &&other) {
|
||||||
assert(this != &other);
|
assert(this != &other);
|
||||||
Free();
|
Free();
|
||||||
Move(other);
|
move(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -977,7 +982,8 @@ template <typename Char>
|
|||||||
class BasicWriter {
|
class BasicWriter {
|
||||||
private:
|
private:
|
||||||
// Output buffer.
|
// Output buffer.
|
||||||
mutable internal::Array<Char, internal::INLINE_BUFFER_SIZE> buffer_;
|
typedef internal::Array<Char, internal::INLINE_BUFFER_SIZE> Buffer;
|
||||||
|
mutable Buffer buffer_;
|
||||||
|
|
||||||
// Make BasicFormatter a friend so that it can access ArgInfo and Arg.
|
// Make BasicFormatter a friend so that it can access ArgInfo and Arg.
|
||||||
friend class BasicFormatter<Char>;
|
friend class BasicFormatter<Char>;
|
||||||
@ -1220,6 +1226,21 @@ class BasicWriter {
|
|||||||
buffer_ = std::move(other.buffer_);
|
buffer_ = std::move(other.buffer_);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
friend inline BasicWriter &move(BasicWriter &w) { return w; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Proxy { Buffer *buffer; };
|
||||||
|
|
||||||
|
public:
|
||||||
|
operator Proxy() {
|
||||||
|
Proxy p = {&buffer_};
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Move" constructors.
|
||||||
|
BasicWriter(BasicWriter &other) { buffer_.move(other.buffer_); }
|
||||||
|
BasicWriter(Proxy p) { buffer_.move(*p.buffer); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1988,25 +2009,12 @@ inline Formatter<ANSITerminalSink> PrintColored(Color c, StringRef format) {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
template<typename... Args>
|
|
||||||
void BasicWriter<Char>::Format(
|
|
||||||
BasicStringRef<Char> format, const Args & ... args) {
|
|
||||||
this->format(format, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Formats a string similarly to Python's `str.format
|
Formats a string similarly to Python's `str.format
|
||||||
<http://docs.python.org/3/library/stdtypes.html#str.format>`__ function
|
<http://docs.python.org/3/library/stdtypes.html#str.format>`__ function
|
||||||
and returns an :cpp:class:`fmt::BasicWriter` object containing the output.
|
and returns an :cpp:class:`fmt::BasicWriter` object containing the output.
|
||||||
|
|
||||||
This version of the Format function uses C++11 features such as
|
|
||||||
variadic templates and rvalue references. For C++98 version, see
|
|
||||||
the :cpp:func:`fmt::Format()` overload above.
|
|
||||||
|
|
||||||
*format* is a format string that contains literal text and replacement
|
*format* is a format string that contains literal text and replacement
|
||||||
fields surrounded by braces ``{}``. The formatter object replaces the
|
fields surrounded by braces ``{}``. The formatter object replaces the
|
||||||
fields with formatted arguments and stores the output in a memory buffer.
|
fields with formatted arguments and stores the output in a memory buffer.
|
||||||
@ -2016,11 +2024,30 @@ void BasicWriter<Char>::Format(
|
|||||||
|
|
||||||
**Example**::
|
**Example**::
|
||||||
|
|
||||||
std::string message = str(Format("The answer is {}", 42));
|
std::string message = str(format("The answer is {}", 42));
|
||||||
|
|
||||||
See also `Format String Syntax`_.
|
See also `Format String Syntax`_.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
|
inline Writer format(StringRef format, const ArgList &args) {
|
||||||
|
Writer w;
|
||||||
|
w.format(format, args);
|
||||||
|
return move(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
template<typename... Args>
|
||||||
|
void BasicWriter<Char>::Format(
|
||||||
|
BasicStringRef<Char> format, const Args & ... args) {
|
||||||
|
this->format(format, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is deprecated, use fmt::format instead.
|
||||||
|
template<typename... Args>
|
||||||
|
FMT_DEPRECATED(Writer Format(StringRef format, const Args & ... args));
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
inline Writer Format(StringRef format, const Args & ... args) {
|
inline Writer Format(StringRef format, const Args & ... args) {
|
||||||
Writer w;
|
Writer w;
|
||||||
@ -2038,7 +2065,7 @@ inline WWriter Format(WStringRef 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;
|
||||||
w.Format(format, args...);
|
w.format(format, args...);
|
||||||
std::fwrite(w.data(), 1, w.size(), stdout);
|
std::fwrite(w.data(), 1, w.size(), stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2252,6 +2279,8 @@ inline void FormatDec(char *&buffer, T value) {
|
|||||||
|
|
||||||
#endif // FMT_USE_VARIADIC_TEMPLATES
|
#endif // FMT_USE_VARIADIC_TEMPLATES
|
||||||
|
|
||||||
|
FMT_VARIADIC(fmt::Writer, format, fmt::StringRef)
|
||||||
|
|
||||||
// Restore warnings.
|
// Restore warnings.
|
||||||
#if FMT_GCC_VERSION >= 406
|
#if FMT_GCC_VERSION >= 406
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
|
@ -26,7 +26,7 @@ expect_compile_error("fmt::internal::Array<char, 5> a, b(a);")
|
|||||||
expect_compile_error("fmt::internal::Array<char, 5> a, b; b = a;")
|
expect_compile_error("fmt::internal::Array<char, 5> a, b; b = a;")
|
||||||
|
|
||||||
# Writer is noncopyable.
|
# Writer is noncopyable.
|
||||||
expect_compile_error("fmt::Writer a, b(a);")
|
expect_compile_error("const fmt::Writer a, b(a);")
|
||||||
expect_compile_error("fmt::Writer a, b; b = a;")
|
expect_compile_error("fmt::Writer a, b; b = a;")
|
||||||
|
|
||||||
# Formatter is not copyable from a temporary.
|
# Formatter is not copyable from a temporary.
|
||||||
|
@ -1359,9 +1359,9 @@ TEST(FormatterTest, FormatExamples) {
|
|||||||
std::string message = str(Format("The answer is {}") << 42);
|
std::string message = str(Format("The answer is {}") << 42);
|
||||||
EXPECT_EQ("The answer is 42", message);
|
EXPECT_EQ("The answer is 42", message);
|
||||||
|
|
||||||
EXPECT_EQ("42", str(Format("{}") << 42));
|
EXPECT_EQ("42", str(format("{}", 42)));
|
||||||
EXPECT_EQ("42", str(Format(std::string("{}")) << 42));
|
EXPECT_EQ("42", str(format(std::string("{}"), 42)));
|
||||||
EXPECT_EQ("42", str(Format(Format("{{}}")) << 42));
|
EXPECT_EQ("42", str(format(Format("{{}}"), 42)));
|
||||||
|
|
||||||
Writer writer;
|
Writer writer;
|
||||||
writer.Format("Current point:\n");
|
writer.Format("Current point:\n");
|
||||||
@ -1565,17 +1565,15 @@ TEST(FormatterTest, Examples) {
|
|||||||
std::string path = "somefile";
|
std::string path = "somefile";
|
||||||
ReportError("File not found: {0}") << path;
|
ReportError("File not found: {0}") << path;
|
||||||
|
|
||||||
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
EXPECT_EQ("The answer is 42", str(format("The answer is {}", 42)));
|
||||||
EXPECT_EQ("The answer is 42", str(Format("The answer is {}", 42)));
|
|
||||||
EXPECT_THROW_MSG(
|
EXPECT_THROW_MSG(
|
||||||
Format("The answer is {:d}", "forty-two"), FormatError,
|
format("The answer is {:d}", "forty-two"), FormatError,
|
||||||
"unknown format code 'd' for string");
|
"unknown format code 'd' for string");
|
||||||
EXPECT_EQ(L"Cyrillic letter \x42e",
|
EXPECT_EQ(L"Cyrillic letter \x42e",
|
||||||
str(Format(L"Cyrillic letter {}", L'\x42e')));
|
str(Format(L"Cyrillic letter {}", L'\x42e')));
|
||||||
|
|
||||||
EXPECT_WRITE(stdout,
|
EXPECT_WRITE(stdout,
|
||||||
fmt::Print("{}", std::numeric_limits<double>::infinity()), "inf");
|
fmt::Print("{}", std::numeric_limits<double>::infinity()), "inf");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatIntTest, Data) {
|
TEST(FormatIntTest, Data) {
|
||||||
@ -1644,12 +1642,10 @@ TEST(FormatTest, PrintColored) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
|
|
||||||
TEST(FormatTest, Variadic) {
|
TEST(FormatTest, Variadic) {
|
||||||
EXPECT_EQ("abc1", str(Format("{}c{}", "ab", 1)));
|
EXPECT_EQ("abc1", str(format("{}c{}", "ab", 1)));
|
||||||
EXPECT_EQ(L"abc1", str(Format(L"{}c{}", L"ab", 1)));
|
EXPECT_EQ(L"abc1", str(Format(L"{}c{}", L"ab", 1)));
|
||||||
}
|
}
|
||||||
#endif // FMT_USE_VARIADIC_TEMPLATES
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string str(const T &value) {
|
std::string str(const T &value) {
|
||||||
|
Reference in New Issue
Block a user