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 { ...@@ -37,25 +37,33 @@ namespace folly {
* @author Xu Ning (xning@fb.com) * @author Xu Ning (xning@fb.com)
*/ */
template<typename T, typename Dp = std::default_delete<T>, typename... Args> #if __cplusplus >= 201402L
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T, Dp>>::type
/* 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) { 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) // Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
template<typename T, typename Dp = std::default_delete<T>> template<typename T>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T, Dp>>::type typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(const size_t n) { 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) // 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< 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; make_unique(Args&&...) = delete;
#endif
/** /**
* static_function_deleter * static_function_deleter
* *
......
...@@ -37,6 +37,11 @@ class AsyncPipeReader : public EventHandler, ...@@ -37,6 +37,11 @@ class AsyncPipeReader : public EventHandler,
typedef std::unique_ptr<AsyncPipeReader, typedef std::unique_ptr<AsyncPipeReader,
folly::DelayedDestruction::Destructor> UniquePtr; 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) AsyncPipeReader(folly::EventBase* eventBase, int pipeFd)
: EventHandler(eventBase, pipeFd), : EventHandler(eventBase, pipeFd),
fd_(pipeFd) {} fd_(pipeFd) {}
...@@ -93,6 +98,11 @@ class AsyncPipeWriter : public EventHandler, ...@@ -93,6 +98,11 @@ class AsyncPipeWriter : public EventHandler,
typedef std::unique_ptr<AsyncPipeWriter, typedef std::unique_ptr<AsyncPipeWriter,
folly::DelayedDestruction::Destructor> UniquePtr; 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) AsyncPipeWriter(folly::EventBase* eventBase, int pipeFd)
: EventHandler(eventBase, pipeFd), : EventHandler(eventBase, pipeFd),
fd_(pipeFd) {} fd_(pipeFd) {}
......
...@@ -60,6 +60,11 @@ class HHWheelTimer : private folly::AsyncTimeout, ...@@ -60,6 +60,11 @@ class HHWheelTimer : private folly::AsyncTimeout,
public: public:
typedef std::unique_ptr<HHWheelTimer, Destructor> UniquePtr; 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. * A callback to be notified when a timeout has expired.
*/ */
......
...@@ -73,11 +73,9 @@ class AsyncPipeTest: public Test { ...@@ -73,11 +73,9 @@ class AsyncPipeTest: public Test {
EXPECT_EQ(::fcntl(pipeFds_[0], F_SETFL, O_NONBLOCK), 0); EXPECT_EQ(::fcntl(pipeFds_[0], F_SETFL, O_NONBLOCK), 0);
EXPECT_EQ(::fcntl(pipeFds_[1], F_SETFL, O_NONBLOCK), 0); EXPECT_EQ(::fcntl(pipeFds_[1], F_SETFL, O_NONBLOCK), 0);
reader_ = folly::make_unique<folly::AsyncPipeReader, reader_ = folly::AsyncPipeReader::newReader(
folly::DelayedDestruction::Destructor>(
&eventBase_, pipeFds_[0]); &eventBase_, pipeFds_[0]);
writer_ = folly::make_unique<folly::AsyncPipeWriter, writer_ = folly::AsyncPipeWriter::newWriter(
folly::DelayedDestruction::Destructor>(
&eventBase_, pipeFds_[1]); &eventBase_, pipeFds_[1]);
} }
......
...@@ -25,53 +25,12 @@ ...@@ -25,53 +25,12 @@
using namespace folly; using namespace folly;
namespace { TEST(make_unique, compatible_with_std_make_unique) {
class disposable { // HACK: To enforce that `folly::` is imported here.
public: to_shared_ptr(std::unique_ptr<std::string>());
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(to_shared_ptr, example_with_dtor) { using namespace std;
bool disposed = false; make_unique<string>("hello, world");
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);
} }
template <std::size_t> struct T {}; 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