Forbid copying of ActiveFormat other that from a temporary object.

This commit is contained in:
Victor Zverovich 2012-12-15 20:17:03 -08:00
parent 4dbf00b4e0
commit cbaddefddd
2 changed files with 23 additions and 30 deletions

View File

@ -402,9 +402,19 @@ class ActiveFormatter : public internal::ArgInserter {
Formatter formatter_; Formatter formatter_;
Action action_; Action action_;
// Forbid copying other than from a temporary. Do not implement.
ActiveFormatter(ActiveFormatter &);
// Do not implement. // Do not implement.
ActiveFormatter& operator=(const ActiveFormatter &); ActiveFormatter& operator=(const ActiveFormatter &);
struct Proxy {
const char *format;
Action action;
Proxy(const char *fmt, Action a) : format(fmt), action(a) {}
};
public: public:
// Creates an active formatter with a format string and an action. // Creates an active formatter with a format string and an action.
// Action should be an unary function object that takes a const // Action should be an unary function object that takes a const
@ -415,21 +425,21 @@ class ActiveFormatter : public internal::ArgInserter {
Init(formatter_, format); Init(formatter_, format);
} }
// Creates an active formatter with the same format string and action ActiveFormatter(const Proxy &p)
// as other has and modifies other so that it doesn't call action in : ArgInserter(0), action_(p.action) {
// destructor. Note that the buffer content is not copied because the Init(formatter_, p.format);
// the buffer in ActiveFormatter is populated when all the arguments
// are provided.
ActiveFormatter(const ActiveFormatter &other)
: ArgInserter(0), action_(other.action_) {
Init(formatter_, other.format());
other.ResetFormatter();
} }
~ActiveFormatter() { ~ActiveFormatter() {
if (formatter()) if (formatter())
action_(*Format()); action_(*Format());
} }
operator Proxy() {
const char *fmt = format();
ResetFormatter();
return Proxy(fmt, action_);
}
}; };
// A formatting action that does nothing. // A formatting action that does nothing.
@ -441,8 +451,7 @@ struct Ignore {
// Example: // Example:
// std::string s = str(Format("Elapsed time: {0:.2f} seconds") << 1.23); // std::string s = str(Format("Elapsed time: {0:.2f} seconds") << 1.23);
inline ActiveFormatter<Ignore> Format(const char *format) { inline ActiveFormatter<Ignore> Format(const char *format) {
ActiveFormatter<Ignore> af(format); return ActiveFormatter<Ignore>(format);
return af;
} }
// A formatting action that writes formatted output to stdout. // A formatting action that writes formatted output to stdout.
@ -456,8 +465,7 @@ struct Write {
// Example: // Example:
// Print("Elapsed time: {0:.2f} seconds") << 1.23; // Print("Elapsed time: {0:.2f} seconds") << 1.23;
inline ActiveFormatter<Write> Print(const char *format) { inline ActiveFormatter<Write> Print(const char *format) {
ActiveFormatter<Write> af(format); return ActiveFormatter<Write>(format);
return af;
} }
} }

View File

@ -708,20 +708,6 @@ TEST(ActiveFormatterTest, Action) {
EXPECT_EQ(1, num_calls); EXPECT_EQ(1, num_calls);
} }
TEST(ActiveFormatterTest, Copy) {
int num_calls = 0;
typedef fmt::ActiveFormatter<CountCalls> AF;
std::auto_ptr<AF> af(new AF("test", CountCalls(num_calls)));
EXPECT_EQ(0, num_calls);
{
AF copy(*af);
EXPECT_EQ(0, num_calls);
af.reset();
EXPECT_EQ(0, num_calls);
}
EXPECT_EQ(1, num_calls);
}
TEST(ActiveFormatterTest, ActionNotCalledOnError) { TEST(ActiveFormatterTest, ActionNotCalledOnError) {
int num_calls = 0; int num_calls = 0;
{ {
@ -751,8 +737,7 @@ struct PrintError {
}; };
fmt::ActiveFormatter<PrintError> ReportError(const char *format) { fmt::ActiveFormatter<PrintError> ReportError(const char *format) {
fmt::ActiveFormatter<PrintError> af(format); return fmt::ActiveFormatter<PrintError>(format);
return af;
} }
TEST(ActiveFormatterTest, Example) { TEST(ActiveFormatterTest, Example) {