return get() != nullptr;
}
+ /**
+ * reset() that transfers ownership from a smart pointer
+ */
+ template <
+ typename SourceT,
+ typename Deleter,
+ typename = typename std::enable_if<
+ std::is_convertible<SourceT*, T*>::value>::type>
+ void reset(std::unique_ptr<SourceT, Deleter> source) {
+ auto deleter = [delegate = source.get_deleter()](
+ T * ptr, TLPDestructionMode) {
+ delegate(ptr);
+ };
+ reset(source.release(), deleter);
+ }
+
+ /**
+ * reset() that transfers ownership from a smart pointer with the default
+ * deleter
+ */
+ template <
+ typename SourceT,
+ typename = typename std::enable_if<
+ std::is_convertible<SourceT*, T*>::value>::type>
+ void reset(std::unique_ptr<SourceT> source) {
+ reset(source.release());
+ }
+
/**
* reset() with a custom deleter:
* deleter(T* ptr, TLPDestructionMode mode)
#include <gtest/gtest.h>
#include <folly/Baton.h>
+#include <folly/Memory.h>
#include <folly/experimental/io/FsUtil.h>
using namespace folly;
}
static void customDeleter(Widget* w, TLPDestructionMode mode) {
- totalVal_ += (mode == TLPDestructionMode::ALL_THREADS) * 1000;
+ totalVal_ += (mode == TLPDestructionMode::ALL_THREADS) ? 1000 : 1;
delete w;
}
};
w.reset(new Widget(), Widget::customDeleter);
w.get()->val_ += 10;
}).join();
+ EXPECT_EQ(11, Widget::totalVal_);
+ }
+ EXPECT_EQ(11, Widget::totalVal_);
+}
+
+TEST(ThreadLocalPtr, CustomDeleterOwnershipTransfer) {
+ Widget::totalVal_ = 0;
+ {
+ ThreadLocalPtr<Widget> w;
+ auto deleter = [](Widget* ptr) {
+ Widget::customDeleter(ptr, TLPDestructionMode::THIS_THREAD);
+ };
+ std::unique_ptr<Widget, typeof(deleter)> source(new Widget(), deleter);
+ std::thread([&w, &source]() {
+ w.reset(std::move(source));
+ w.get()->val_ += 10;
+ }).join();
+ EXPECT_EQ(11, Widget::totalVal_);
+ }
+ EXPECT_EQ(11, Widget::totalVal_);
+}
+
+TEST(ThreadLocalPtr, DefaultDeleterOwnershipTransfer) {
+ Widget::totalVal_ = 0;
+ {
+ ThreadLocalPtr<Widget> w;
+ auto source = folly::make_unique<Widget>();
+ std::thread([&w, &source]() {
+ w.reset(std::move(source));
+ w.get()->val_ += 10;
+ }).join();
EXPECT_EQ(10, Widget::totalVal_);
}
EXPECT_EQ(10, Widget::totalVal_);