From cbaddefdddca6d655ce7922c41abd10f364d6e48 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 15 Dec 2012 20:17:03 -0800 Subject: [PATCH] Forbid copying of ActiveFormat other that from a temporary object. --- format.h | 36 ++++++++++++++++++++++-------------- format_test.cc | 17 +---------------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/format.h b/format.h index eb507a99..316b057a 100644 --- a/format.h +++ b/format.h @@ -402,8 +402,18 @@ class ActiveFormatter : public internal::ArgInserter { Formatter formatter_; Action action_; + // Forbid copying other than from a temporary. Do not implement. + ActiveFormatter(ActiveFormatter &); + // 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: // Creates an active formatter with a format string and an action. @@ -415,21 +425,21 @@ class ActiveFormatter : public internal::ArgInserter { Init(formatter_, format); } - // Creates an active formatter with the same format string and action - // as other has and modifies other so that it doesn't call action in - // destructor. Note that the buffer content is not copied because the - // 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(const Proxy &p) + : ArgInserter(0), action_(p.action) { + Init(formatter_, p.format); } ~ActiveFormatter() { if (formatter()) action_(*Format()); } + + operator Proxy() { + const char *fmt = format(); + ResetFormatter(); + return Proxy(fmt, action_); + } }; // A formatting action that does nothing. @@ -441,8 +451,7 @@ struct Ignore { // Example: // std::string s = str(Format("Elapsed time: {0:.2f} seconds") << 1.23); inline ActiveFormatter Format(const char *format) { - ActiveFormatter af(format); - return af; + return ActiveFormatter(format); } // A formatting action that writes formatted output to stdout. @@ -456,8 +465,7 @@ struct Write { // Example: // Print("Elapsed time: {0:.2f} seconds") << 1.23; inline ActiveFormatter Print(const char *format) { - ActiveFormatter af(format); - return af; + return ActiveFormatter(format); } } diff --git a/format_test.cc b/format_test.cc index 78c885c6..17f660f6 100644 --- a/format_test.cc +++ b/format_test.cc @@ -708,20 +708,6 @@ TEST(ActiveFormatterTest, Action) { EXPECT_EQ(1, num_calls); } -TEST(ActiveFormatterTest, Copy) { - int num_calls = 0; - typedef fmt::ActiveFormatter AF; - std::auto_ptr 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) { int num_calls = 0; { @@ -751,8 +737,7 @@ struct PrintError { }; fmt::ActiveFormatter ReportError(const char *format) { - fmt::ActiveFormatter af(format); - return af; + return fmt::ActiveFormatter(format); } TEST(ActiveFormatterTest, Example) {