From 645f7c0cd4950988e4329e32f8d23f2b596f1b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 16 Apr 2015 12:01:04 +0200 Subject: [PATCH] use std::unique_ptr<> as a movable-only container directly instead of wrapping in another class --- src/mbgl/util/run_loop.cpp | 2 +- src/mbgl/util/run_loop.hpp | 47 +++++++++++++++----------------------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/mbgl/util/run_loop.cpp b/src/mbgl/util/run_loop.cpp index e945a0232..fd9ad4306 100644 --- a/src/mbgl/util/run_loop.cpp +++ b/src/mbgl/util/run_loop.cpp @@ -19,7 +19,7 @@ void RunLoop::process() { withMutex([&] { queue_.swap(queue); }); while (!queue_.empty()) { - (queue_.front())(); + (*(queue_.front()))(); queue_.pop(); } } diff --git a/src/mbgl/util/run_loop.hpp b/src/mbgl/util/run_loop.hpp index c39fb6018..d785854e7 100644 --- a/src/mbgl/util/run_loop.hpp +++ b/src/mbgl/util/run_loop.hpp @@ -1,6 +1,8 @@ #ifndef MBGL_UTIL_RUN_LOOP #define MBGL_UTIL_RUN_LOOP +#include +#include #include #include @@ -10,7 +12,7 @@ namespace mbgl { namespace util { -class RunLoop { +class RunLoop : private util::noncopyable { public: RunLoop(); @@ -20,7 +22,8 @@ public: // Invoke fn() in the runloop thread. template void invoke(Fn&& fn) { - withMutex([&] { queue.push(Message(std::move(fn))); }); + auto invokable = util::make_unique>(std::move(fn)); + withMutex([&] { queue.push(std::move(invokable)); }); async.send(); } @@ -51,36 +54,22 @@ public: uv_loop_t* get() { return *loop; } private: + // A movable type-erasing invokable entity wrapper. This allows to store arbitrary invokable + // things (like std::function<>, or the result of a movable-only std::bind()) in the queue. + // Source: http://stackoverflow.com/a/29642072/331379 struct Message { - struct Base { - virtual void operator()() = 0; - virtual ~Base() = default; - }; - - template - struct Invoker : Base { - Invoker(F&& f) : func(std::move(f)) {} - void operator()() override { func(); } - F func; - }; - - Message() = default; - Message(Message&&) = default; - ~Message() = default; - Message& operator=(Message&&) = default; - - // copy members implicitly deleted - - template - Message(Fn fn) - : p_fn(new Invoker(std::move(fn))) { - } - - void operator()() const { (*p_fn)(); } - std::unique_ptr p_fn; + virtual void operator()() = 0; + virtual ~Message() = default; }; - using Queue = std::queue; + template + struct Invoker : Message { + Invoker(F&& f) : func(std::move(f)) {} + void operator()() override { func(); } + F func; + }; + + using Queue = std::queue>; static uv::tls current;