From: Giuseppe Ottaviano Date: Fri, 23 Jun 2017 22:19:01 +0000 (-0700) Subject: MoveOnly utility X-Git-Tag: v2017.06.26.00~6 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=efcacd1c99bbea5411507e39ce74051a279be5e7 MoveOnly utility Summary: Same as `boost::noncopyable` but it does not disable move constructor/assignment. Reviewed By: luciang Differential Revision: D5311043 fbshipit-source-id: 44fe95712169b95a00e474385be43fa857cfd8ec --- diff --git a/folly/Utility.h b/folly/Utility.h index 4d6725d7..1d378618 100644 --- a/folly/Utility.h +++ b/folly/Utility.h @@ -158,4 +158,27 @@ struct Identity { return static_cast(x); } }; -} + +namespace moveonly_ { // Protection from unintended ADL. + +/** + * Disallow copy but not move in derived types. This is essentially + * boost::noncopyable (the implementation is almost identical) but it + * doesn't delete move constructor and move assignment. + */ +class MoveOnly { + protected: + constexpr MoveOnly() = default; + ~MoveOnly() = default; + + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly&&) = default; + MoveOnly(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = delete; +}; + +} // namespace moveonly_ + +using MoveOnly = moveonly_::MoveOnly; + +} // namespace folly diff --git a/folly/test/UtilityTest.cpp b/folly/test/UtilityTest.cpp index 9b77e170..5507b96f 100644 --- a/folly/test/UtilityTest.cpp +++ b/folly/test/UtilityTest.cpp @@ -14,8 +14,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { @@ -88,3 +89,24 @@ TEST(FollyIntegerSequence, core) { static_assert(seq3.size() == 3, ""); EXPECT_EQ(3, seq3.size()); } + +TEST_F(UtilityTest, MoveOnly) { + class FooBar : folly::MoveOnly { + int a; + }; + + static_assert( + !std::is_copy_constructible::value, + "Should not be copy constructible"); + + // Test that move actually works. + FooBar foobar; + FooBar foobar2(std::move(foobar)); + (void)foobar2; + + // Test that inheriting from MoveOnly doesn't prevent the move + // constructor from being noexcept. + static_assert( + std::is_nothrow_move_constructible::value, + "Should have noexcept move constructor"); +}