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 @@
#include <folly/io/async/EventBase.h>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <unordered_set>
#include <utility>
namespace folly {
......@@ -84,21 +84,21 @@ class EventBaseLocal : public detail::EventBaseLocalBase {
setVoid(evb, std::move(smartPtr));
}
template<typename... Args>
void emplace(EventBase& evb, Args... args) {
auto smartPtr = std::make_shared<T>(args...);
template <typename... Args>
void emplace(EventBase& evb, Args&&... args) {
auto smartPtr = std::make_shared<T>(std::forward<Args>(args)...);
setVoid(evb, smartPtr);
}
template<typename... Args>
T& getOrCreate(EventBase& evb, Args... args) {
template <typename... Args>
T& getOrCreate(EventBase& evb, Args&&... args) {
std::lock_guard<std::mutex> lg(evb.localStorageMutex_);
auto it2 = evb.localStorage_.find(key_);
if (LIKELY(it2 != evb.localStorage_.end())) {
return *static_cast<T*>(it2->second.get());
} else {
auto smartPtr = std::make_shared<T>(args...);
auto smartPtr = std::make_shared<T>(std::forward<Args>(args)...);
auto ptr = smartPtr.get();
setVoidUnlocked(evb, std::move(smartPtr));
return *ptr;
......
......@@ -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<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