From: Yedidya Feldblum Date: Sat, 3 Oct 2015 04:47:38 +0000 (-0700) Subject: Converge folly::make_unique to C++14's std::make_unique X-Git-Tag: deprecate-dynamic-initializer~361 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=62504e55283a9b3072c6eb8f88fd0e67c14414e7;p=folly.git 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 --- diff --git a/folly/Memory.h b/folly/Memory.h index b58edf20..eadc1c81 100644 --- a/folly/Memory.h +++ b/folly/Memory.h @@ -37,25 +37,33 @@ namespace folly { * @author Xu Ning (xning@fb.com) */ -template, typename... Args> -typename std::enable_if::value, std::unique_ptr>::type +#if __cplusplus >= 201402L + +/* using override */ using std::make_unique; + +#else + +template +typename std::enable_if::value, std::unique_ptr>::type make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); + return std::unique_ptr(new T(std::forward(args)...)); } // Allows 'make_unique(10)'. (N3690 s20.9.1.4 p3-4) -template> -typename std::enable_if::value, std::unique_ptr>::type +template +typename std::enable_if::value, std::unique_ptr>::type make_unique(const size_t n) { - return std::unique_ptr(new typename std::remove_extent::type[n]()); + return std::unique_ptr(new typename std::remove_extent::type[n]()); } // Disallows 'make_unique()'. (N3690 s20.9.1.4 p5) -template, typename... Args> +template typename std::enable_if< - std::extent::value != 0, std::unique_ptr>::type + std::extent::value != 0, std::unique_ptr>::type make_unique(Args&&...) = delete; +#endif + /** * static_function_deleter * diff --git a/folly/io/async/AsyncPipe.h b/folly/io/async/AsyncPipe.h index 63e73acb..40d5021a 100644 --- a/folly/io/async/AsyncPipe.h +++ b/folly/io/async/AsyncPipe.h @@ -37,6 +37,11 @@ class AsyncPipeReader : public EventHandler, typedef std::unique_ptr UniquePtr; + template + static UniquePtr newReader(Args&&... args) { + return UniquePtr(new AsyncPipeReader(std::forward(args)...)); + } + AsyncPipeReader(folly::EventBase* eventBase, int pipeFd) : EventHandler(eventBase, pipeFd), fd_(pipeFd) {} @@ -93,6 +98,11 @@ class AsyncPipeWriter : public EventHandler, typedef std::unique_ptr UniquePtr; + template + static UniquePtr newWriter(Args&&... args) { + return UniquePtr(new AsyncPipeWriter(std::forward(args)...)); + } + AsyncPipeWriter(folly::EventBase* eventBase, int pipeFd) : EventHandler(eventBase, pipeFd), fd_(pipeFd) {} diff --git a/folly/io/async/HHWheelTimer.h b/folly/io/async/HHWheelTimer.h index 22824c22..0609ea66 100644 --- a/folly/io/async/HHWheelTimer.h +++ b/folly/io/async/HHWheelTimer.h @@ -60,6 +60,11 @@ class HHWheelTimer : private folly::AsyncTimeout, public: typedef std::unique_ptr UniquePtr; + template + static UniquePtr newTimer(Args&&... args) { + return UniquePtr(new HHWheelTimer(std::forward(args)...)); + } + /** * A callback to be notified when a timeout has expired. */ diff --git a/folly/io/async/test/AsyncPipeTest.cpp b/folly/io/async/test/AsyncPipeTest.cpp index 750e9aa9..215d9056 100644 --- a/folly/io/async/test/AsyncPipeTest.cpp +++ b/folly/io/async/test/AsyncPipeTest.cpp @@ -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( + reader_ = folly::AsyncPipeReader::newReader( &eventBase_, pipeFds_[0]); - writer_ = folly::make_unique( + writer_ = folly::AsyncPipeWriter::newWriter( &eventBase_, pipeFds_[1]); } diff --git a/folly/test/MemoryTest.cpp b/folly/test/MemoryTest.cpp index a62cd11e..5c014588 100644 --- a/folly/test/MemoryTest.cpp +++ b/folly/test/MemoryTest.cpp @@ -25,53 +25,12 @@ using namespace folly; -namespace { -class disposable { - public: - explicit disposable(std::function onDispose) : - onDispose_(std::move(onDispose)) {} - static void dispose(disposable* f) { - ASSERT_NE(nullptr, f); - f->onDispose_(); - delete f; - } - private: - std::function onDispose_; -}; -} - -TEST(static_function_deleter, example) { - size_t count = 0; - using disposable_deleter = - static_function_deleter; - make_unique([&] { ++count; }); - EXPECT_EQ(1, count); -} - -TEST(static_function_deleter, nullptr) { - using disposable_deleter = - static_function_deleter; - std::unique_ptr(nullptr); -} - -TEST(to_shared_ptr, example) { - auto uptr = make_unique("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()); -TEST(to_shared_ptr, example_with_dtor) { - bool disposed = false; - using disposable_deleter = - static_function_deleter; - auto uptr = - make_unique([&] { 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("hello, world"); } template struct T {};