Commit 62504e55 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by facebook-github-bot-9

Converge folly::make_unique to C++14's std::make_unique

Summary: [Folly] Converge `folly::make_unique` to C++14's `std::make_unique`.

The primary use-case of ther deleter variety of `folly::make_unique` is `DelayedDestruction`. Let the classes matching this use-case define their own factories.

Reviewed By: @fugalh

Differential Revision: D2495718
parent 96000632
......@@ -37,25 +37,33 @@ namespace folly {
* @author Xu Ning (xning@fb.com)
*/
template<typename T, typename Dp = std::default_delete<T>, typename... Args>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T, Dp>>::type
#if __cplusplus >= 201402L
/* using override */ using std::make_unique;
#else
template<typename T, typename... Args>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(Args&&... args) {
return std::unique_ptr<T, Dp>(new T(std::forward<Args>(args)...));
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
// Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
template<typename T, typename Dp = std::default_delete<T>>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T, Dp>>::type
template<typename T>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(const size_t n) {
return std::unique_ptr<T, Dp>(new typename std::remove_extent<T>::type[n]());
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
}
// Disallows 'make_unique<T[10]>()'. (N3690 s20.9.1.4 p5)
template<typename T, typename Dp = std::default_delete<T>, typename... Args>
template<typename T, typename... Args>
typename std::enable_if<
std::extent<T>::value != 0, std::unique_ptr<T, Dp>>::type
std::extent<T>::value != 0, std::unique_ptr<T>>::type
make_unique(Args&&...) = delete;
#endif
/**
* static_function_deleter
*
......
......@@ -37,6 +37,11 @@ class AsyncPipeReader : public EventHandler,
typedef std::unique_ptr<AsyncPipeReader,
folly::DelayedDestruction::Destructor> UniquePtr;
template <typename... Args>
static UniquePtr newReader(Args&&... args) {
return UniquePtr(new AsyncPipeReader(std::forward<Args>(args)...));
}
AsyncPipeReader(folly::EventBase* eventBase, int pipeFd)
: EventHandler(eventBase, pipeFd),
fd_(pipeFd) {}
......@@ -93,6 +98,11 @@ class AsyncPipeWriter : public EventHandler,
typedef std::unique_ptr<AsyncPipeWriter,
folly::DelayedDestruction::Destructor> UniquePtr;
template <typename... Args>
static UniquePtr newWriter(Args&&... args) {
return UniquePtr(new AsyncPipeWriter(std::forward<Args>(args)...));
}
AsyncPipeWriter(folly::EventBase* eventBase, int pipeFd)
: EventHandler(eventBase, pipeFd),
fd_(pipeFd) {}
......
......@@ -60,6 +60,11 @@ class HHWheelTimer : private folly::AsyncTimeout,
public:
typedef std::unique_ptr<HHWheelTimer, Destructor> UniquePtr;
template <typename... Args>
static UniquePtr newTimer(Args&&... args) {
return UniquePtr(new HHWheelTimer(std::forward<Args>(args)...));
}
/**
* A callback to be notified when a timeout has expired.
*/
......
......@@ -73,11 +73,9 @@ class AsyncPipeTest: public Test {
EXPECT_EQ(::fcntl(pipeFds_[0], F_SETFL, O_NONBLOCK), 0);
EXPECT_EQ(::fcntl(pipeFds_[1], F_SETFL, O_NONBLOCK), 0);
reader_ = folly::make_unique<folly::AsyncPipeReader,
folly::DelayedDestruction::Destructor>(
reader_ = folly::AsyncPipeReader::newReader(
&eventBase_, pipeFds_[0]);
writer_ = folly::make_unique<folly::AsyncPipeWriter,
folly::DelayedDestruction::Destructor>(
writer_ = folly::AsyncPipeWriter::newWriter(
&eventBase_, pipeFds_[1]);
}
......
......@@ -25,53 +25,12 @@
using namespace folly;
namespace {
class disposable {
public:
explicit disposable(std::function<void()> onDispose) :
onDispose_(std::move(onDispose)) {}
static void dispose(disposable* f) {
ASSERT_NE(nullptr, f);
f->onDispose_();
delete f;
}
private:
std::function<void()> onDispose_;
};
}
TEST(static_function_deleter, example) {
size_t count = 0;
using disposable_deleter =
static_function_deleter<disposable, &disposable::dispose>;
make_unique<disposable, disposable_deleter>([&] { ++count; });
EXPECT_EQ(1, count);
}
TEST(static_function_deleter, nullptr) {
using disposable_deleter =
static_function_deleter<disposable, &disposable::dispose>;
std::unique_ptr<disposable, disposable_deleter>(nullptr);
}
TEST(to_shared_ptr, example) {
auto uptr = make_unique<std::string>("hello");
auto sptr = to_shared_ptr(std::move(uptr));
EXPECT_EQ(nullptr, uptr);
EXPECT_EQ("hello", *sptr);
}
TEST(make_unique, compatible_with_std_make_unique) {
// HACK: To enforce that `folly::` is imported here.
to_shared_ptr(std::unique_ptr<std::string>());
TEST(to_shared_ptr, example_with_dtor) {
bool disposed = false;
using disposable_deleter =
static_function_deleter<disposable, &disposable::dispose>;
auto uptr =
make_unique<disposable, disposable_deleter>([&] { disposed = true; });
EXPECT_FALSE(disposed);
auto sptr = to_shared_ptr(std::move(uptr));
EXPECT_FALSE(disposed);
sptr = nullptr;
EXPECT_TRUE(disposed);
using namespace std;
make_unique<string>("hello, world");
}
template <std::size_t> struct T {};
......
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