From 81baed36bff0d331c71d2358bfb4e28dd2eb64ab Mon Sep 17 00:00:00 2001 From: deadbeef Date: Fri, 10 Feb 2017 18:11:11 -0800 Subject: [PATCH] Add ability to return moved value from FunctorMessageHandler, Optional. This functionality is desired for this CL: https://codereview.webrtc.org/2675173003/ BUG=None Review-Url: https://codereview.webrtc.org/2681283002 Cr-Commit-Position: refs/heads/master@{#16546} --- webrtc/base/messagehandler.h | 19 +++++-------------- webrtc/base/optional.h | 6 ++++++ webrtc/base/optional_unittest.cc | 15 +++++++++++++++ webrtc/base/thread.h | 2 +- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/webrtc/base/messagehandler.h b/webrtc/base/messagehandler.h index 6a3c2ef740..72c0dc6907 100644 --- a/webrtc/base/messagehandler.h +++ b/webrtc/base/messagehandler.h @@ -45,25 +45,15 @@ class FunctorMessageHandler : public MessageHandler { } const ReturnT& result() const { return result_; } + // Returns moved result. Should not call result() or MoveResult() again + // after this. + ReturnT MoveResult() { return std::move(result_); } + private: FunctorT functor_; ReturnT result_; }; -// Specialization for std::unique_ptr. -template -class FunctorMessageHandler, FunctorT> - : public MessageHandler { - public: - explicit FunctorMessageHandler(const FunctorT& functor) : functor_(functor) {} - virtual void OnMessage(Message* msg) { result_ = std::move(functor_()); } - std::unique_ptr result() { return std::move(result_); } - - private: - FunctorT functor_; - std::unique_ptr result_; -}; - // Specialization for ReturnT of void. template class FunctorMessageHandler : public MessageHandler { @@ -74,6 +64,7 @@ class FunctorMessageHandler : public MessageHandler { functor_(); } void result() const {} + void MoveResult() {} private: FunctorT functor_; diff --git a/webrtc/base/optional.h b/webrtc/base/optional.h index 4d2b44e0cb..f5354ee0f2 100644 --- a/webrtc/base/optional.h +++ b/webrtc/base/optional.h @@ -239,6 +239,12 @@ class Optional final { : default_val; } + // Dereference and move value. + T MoveValue() { + RTC_DCHECK(has_value_); + return std::move(value_); + } + // Equality tests. Two Optionals are equal if they contain equivalent values, // or if they're both empty. friend bool operator==(const Optional& m1, const Optional& m2) { diff --git a/webrtc/base/optional_unittest.cc b/webrtc/base/optional_unittest.cc index c1ae9c00d4..65070fabb0 100644 --- a/webrtc/base/optional_unittest.cc +++ b/webrtc/base/optional_unittest.cc @@ -725,4 +725,19 @@ TEST(OptionalTest, TestSwap) { *log); } +TEST(OptionalTest, TestMoveValue) { + auto log = Logger::Setup(); + { + Optional x(Logger(42)); + log->push_back("---"); + Logger moved = x.MoveValue(); + log->push_back("---"); + } + EXPECT_EQ( + V("0:42. explicit constructor", "1:42. move constructor (from 0:42)", + "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---", + "2:42. destructor", "1:42. destructor"), + *log); +} + } // namespace rtc diff --git a/webrtc/base/thread.h b/webrtc/base/thread.h index 29b78e1845..acd84d91d3 100644 --- a/webrtc/base/thread.h +++ b/webrtc/base/thread.h @@ -168,7 +168,7 @@ class LOCKABLE Thread : public MessageQueue { ReturnT Invoke(const Location& posted_from, const FunctorT& functor) { FunctorMessageHandler handler(functor); InvokeInternal(posted_from, &handler); - return handler.result(); + return handler.MoveResult(); } // From MessageQueue