Commit cafd8d8e authored by Victor Zverovich's avatar Victor Zverovich Committed by Facebook Github Bot

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
parent aee35091
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include <folly/io/async/EventBase.h> #include <folly/io/async/EventBase.h>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <utility>
namespace folly { namespace folly {
...@@ -84,21 +84,21 @@ class EventBaseLocal : public detail::EventBaseLocalBase { ...@@ -84,21 +84,21 @@ class EventBaseLocal : public detail::EventBaseLocalBase {
setVoid(evb, std::move(smartPtr)); setVoid(evb, std::move(smartPtr));
} }
template<typename... Args> template <typename... Args>
void emplace(EventBase& evb, Args... args) { void emplace(EventBase& evb, Args&&... args) {
auto smartPtr = std::make_shared<T>(args...); auto smartPtr = std::make_shared<T>(std::forward<Args>(args)...);
setVoid(evb, smartPtr); setVoid(evb, smartPtr);
} }
template<typename... Args> template <typename... Args>
T& getOrCreate(EventBase& evb, Args... args) { T& getOrCreate(EventBase& evb, Args&&... args) {
std::lock_guard<std::mutex> lg(evb.localStorageMutex_); std::lock_guard<std::mutex> lg(evb.localStorageMutex_);
auto it2 = evb.localStorage_.find(key_); auto it2 = evb.localStorage_.find(key_);
if (LIKELY(it2 != evb.localStorage_.end())) { if (LIKELY(it2 != evb.localStorage_.end())) {
return *static_cast<T*>(it2->second.get()); return *static_cast<T*>(it2->second.get());
} else { } else {
auto smartPtr = std::make_shared<T>(args...); auto smartPtr = std::make_shared<T>(std::forward<Args>(args)...);
auto ptr = smartPtr.get(); auto ptr = smartPtr.get();
setVoidUnlocked(evb, std::move(smartPtr)); setVoidUnlocked(evb, std::move(smartPtr));
return *ptr; return *ptr;
......
...@@ -87,3 +87,23 @@ TEST(EventBaseLocalTest, getOrCreate) { ...@@ -87,3 +87,23 @@ TEST(EventBaseLocalTest, getOrCreate) {
auto creator = []() { return new int(4); }; auto creator = []() { return new int(4); };
EXPECT_EQ(ints.getOrCreateFn(evb2, creator), 4); EXPECT_EQ(ints.getOrCreateFn(evb2, creator), 4);
} }
using IntPtr = std::unique_ptr<int>;
TEST(EventBaseLocalTest, getOrCreateNoncopyable) {
folly::EventBase evb1;
folly::EventBaseLocal<IntPtr> ints;
EXPECT_EQ(ints.getOrCreate(evb1), IntPtr());
EXPECT_EQ(ints.getOrCreate(evb1, std::make_unique<int>(5)), IntPtr());
folly::EventBase evb2;
EXPECT_EQ(*ints.getOrCreate(evb2, std::make_unique<int>(5)), 5);
}
TEST(EventBaseLocalTest, emplaceNoncopyable) {
folly::EventBase evb;
folly::EventBaseLocal<IntPtr> ints;
ints.emplace(evb, std::make_unique<int>(42));
EXPECT_EQ(42, **ints.get(evb));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment