From cafd8d8eda615c4576e78858f4055ebf34c89b4b Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 18 Mar 2017 06:29:19 -0700 Subject: [PATCH] Make EventBaseLocal::getOrCreate work with noncopyable args Summary: Use perfect forwarding in `EventBaseLocal::getOrCreate` to make it work with noncopyable but moveable arguments. Reviewed By: yfeldblum Differential Revision: D4730566 fbshipit-source-id: fa02348b7a9217fef980ec5e743b5990b9d19e9a --- folly/io/async/EventBaseLocal.h | 14 +++++++------- folly/io/async/test/EventBaseLocalTest.cpp | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/folly/io/async/EventBaseLocal.h b/folly/io/async/EventBaseLocal.h index 4a4a10b1..41f76a75 100644 --- a/folly/io/async/EventBaseLocal.h +++ b/folly/io/async/EventBaseLocal.h @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include namespace folly { @@ -84,21 +84,21 @@ class EventBaseLocal : public detail::EventBaseLocalBase { setVoid(evb, std::move(smartPtr)); } - template - void emplace(EventBase& evb, Args... args) { - auto smartPtr = std::make_shared(args...); + template + void emplace(EventBase& evb, Args&&... args) { + auto smartPtr = std::make_shared(std::forward(args)...); setVoid(evb, smartPtr); } - template - T& getOrCreate(EventBase& evb, Args... args) { + template + T& getOrCreate(EventBase& evb, Args&&... args) { std::lock_guard lg(evb.localStorageMutex_); auto it2 = evb.localStorage_.find(key_); if (LIKELY(it2 != evb.localStorage_.end())) { return *static_cast(it2->second.get()); } else { - auto smartPtr = std::make_shared(args...); + auto smartPtr = std::make_shared(std::forward(args)...); auto ptr = smartPtr.get(); setVoidUnlocked(evb, std::move(smartPtr)); return *ptr; diff --git a/folly/io/async/test/EventBaseLocalTest.cpp b/folly/io/async/test/EventBaseLocalTest.cpp index 96ff491e..f7b963aa 100644 --- a/folly/io/async/test/EventBaseLocalTest.cpp +++ b/folly/io/async/test/EventBaseLocalTest.cpp @@ -87,3 +87,23 @@ TEST(EventBaseLocalTest, getOrCreate) { auto creator = []() { return new int(4); }; EXPECT_EQ(ints.getOrCreateFn(evb2, creator), 4); } + +using IntPtr = std::unique_ptr; + +TEST(EventBaseLocalTest, getOrCreateNoncopyable) { + folly::EventBase evb1; + folly::EventBaseLocal ints; + + EXPECT_EQ(ints.getOrCreate(evb1), IntPtr()); + EXPECT_EQ(ints.getOrCreate(evb1, std::make_unique(5)), IntPtr()); + + folly::EventBase evb2; + EXPECT_EQ(*ints.getOrCreate(evb2, std::make_unique(5)), 5); +} + +TEST(EventBaseLocalTest, emplaceNoncopyable) { + folly::EventBase evb; + folly::EventBaseLocal ints; + ints.emplace(evb, std::make_unique(42)); + EXPECT_EQ(42, **ints.get(evb)); +} -- 2.34.1