mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-13 00:40:51 +00:00
Forbid copying from a temporary (Basic)Formatter object.
This commit is contained in:
parent
e8a2bdf2d1
commit
383a8423ef
55
format.h
55
format.h
@ -774,7 +774,8 @@ BasicWriter<Char> &BasicWriter<Char>::operator<<(
|
|||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) {
|
BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) {
|
||||||
return BasicFormatter<Char>(*this, format.c_str());
|
BasicFormatter<Char> f(*this, format.c_str());
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BasicWriter<char> Writer;
|
typedef BasicWriter<char> Writer;
|
||||||
@ -936,8 +937,12 @@ class BasicFormatter {
|
|||||||
|
|
||||||
friend class internal::FormatterProxy<Char>;
|
friend class internal::FormatterProxy<Char>;
|
||||||
|
|
||||||
// Forbid copying other than from a temporary. Do not implement.
|
// Forbid copying from a temporary as in the following example:
|
||||||
BasicFormatter(BasicFormatter &);
|
// fmt::Formatter<> f = Format("test"); // not allowed
|
||||||
|
// This is done because BasicFormatter objects should normally exist
|
||||||
|
// only as temporaries returned by one of the formatting functions.
|
||||||
|
// Do not implement.
|
||||||
|
BasicFormatter(const BasicFormatter &);
|
||||||
BasicFormatter& operator=(const BasicFormatter &);
|
BasicFormatter& operator=(const BasicFormatter &);
|
||||||
|
|
||||||
void Add(const Arg &arg) {
|
void Add(const Arg &arg) {
|
||||||
@ -988,13 +993,8 @@ class BasicFormatter {
|
|||||||
CompleteFormatting();
|
CompleteFormatting();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a formatter from a proxy object.
|
BasicFormatter(BasicFormatter &f) : writer_(f.writer_), format_(f.format_) {
|
||||||
BasicFormatter(const Proxy &p) : writer_(p.writer), format_(p.format) {}
|
f.format_ = 0;
|
||||||
|
|
||||||
operator Proxy() {
|
|
||||||
const Char *format = format_;
|
|
||||||
format_ = 0;
|
|
||||||
return Proxy(writer_, format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feeds an argument to a formatter.
|
// Feeds an argument to a formatter.
|
||||||
@ -1089,7 +1089,7 @@ class NoAction {
|
|||||||
|
|
||||||
// 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<PrintError> ReportError(const char *format) {
|
||||||
return fmt::Formatter<PrintError>(format);
|
return Move(fmt::Formatter<PrintError>(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportError("File not found: {}") << path;
|
ReportError("File not found: {}") << path;
|
||||||
@ -1102,16 +1102,9 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
bool inactive_;
|
bool inactive_;
|
||||||
|
|
||||||
// Forbid copying other than from a temporary. Do not implement.
|
// Forbid copying other than from a temporary. Do not implement.
|
||||||
Formatter(Formatter &);
|
Formatter(const Formatter &);
|
||||||
Formatter& operator=(const Formatter &);
|
Formatter& operator=(const Formatter &);
|
||||||
|
|
||||||
struct Proxy {
|
|
||||||
const Char *format;
|
|
||||||
Action action;
|
|
||||||
|
|
||||||
Proxy(const Char *fmt, Action a) : format(fmt), action(a) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -1127,10 +1120,10 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
inactive_(false) {
|
inactive_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a formatter from a proxy object.
|
Formatter(Formatter &f)
|
||||||
Formatter(const Proxy &p)
|
: Action(f), BasicFormatter<Char>(writer_, f.TakeFormatString()),
|
||||||
: Action(p.action), BasicFormatter<Char>(writer_, p.format),
|
|
||||||
inactive_(false) {
|
inactive_(false) {
|
||||||
|
f.inactive_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1142,14 +1135,14 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
(*this)(writer_);
|
(*this)(writer_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the formatter into a proxy object.
|
|
||||||
operator Proxy() {
|
|
||||||
inactive_ = true;
|
|
||||||
return Proxy(this->TakeFormatString(), *this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Removes a const qualifier from a formatter object making it moveable.
|
||||||
|
template <typename Action, typename Char>
|
||||||
|
Formatter<Action, Char> &Move(const Formatter<Action, Char> &f) {
|
||||||
|
return const_cast<Formatter<Action, Char> &>(f);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fast integer formatter.
|
Fast integer formatter.
|
||||||
*/
|
*/
|
||||||
@ -1223,11 +1216,11 @@ class FormatInt {
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
inline Formatter<> Format(StringRef format) {
|
inline Formatter<> Format(StringRef format) {
|
||||||
return Formatter<>(format);
|
return Move(Formatter<>(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Formatter<NoAction, wchar_t> Format(WStringRef format) {
|
inline Formatter<NoAction, wchar_t> Format(WStringRef format) {
|
||||||
return Formatter<NoAction, wchar_t>(format);
|
return Move(Formatter<NoAction, wchar_t>(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A formatting action that writes formatted output to stdout. */
|
/** A formatting action that writes formatted output to stdout. */
|
||||||
@ -1243,7 +1236,7 @@ class Write {
|
|||||||
// Example:
|
// Example:
|
||||||
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
||||||
inline Formatter<Write> Print(StringRef format) {
|
inline Formatter<Write> Print(StringRef format) {
|
||||||
return Formatter<Write>(format);
|
return Move(Formatter<Write>(format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1327,7 +1327,7 @@ struct PrintError {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fmt::Formatter<PrintError> ReportError(const char *format) {
|
fmt::Formatter<PrintError> ReportError(const char *format) {
|
||||||
return fmt::Formatter<PrintError>(format);
|
return Move(fmt::Formatter<PrintError>(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, Examples) {
|
TEST(FormatterTest, Examples) {
|
||||||
|
Loading…
Reference in New Issue
Block a user