From: Chandler Carruth Date: Sun, 2 Mar 2014 03:38:32 +0000 (+0000) Subject: [C++11] Add support for OwningPtr to be converted to and from X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=80949c599fb8b2c5d14c517d2ef94ad974989a37;p=oota-llvm.git [C++11] Add support for OwningPtr to be converted to and from std::unique_ptr. Patch by Ahmed Charles! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202609 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h index 3347ccd4a42..4ee00ef6e80 100644 --- a/include/llvm/ADT/OwningPtr.h +++ b/include/llvm/ADT/OwningPtr.h @@ -17,6 +17,7 @@ #include "llvm/Support/Compiler.h" #include #include +#include namespace llvm { @@ -39,6 +40,17 @@ public: return *this; } + OwningPtr(std::unique_ptr &&Other) : Ptr(Other.release()) {} + + OwningPtr &operator=(std::unique_ptr &&Other) { + reset(Other.release()); + return *this; + } + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + operator std::unique_ptr() && { return std::unique_ptr(take()); } +#endif + ~OwningPtr() { delete Ptr; } @@ -61,6 +73,8 @@ public: return Tmp; } + std::unique_ptr take_unique() { return std::unique_ptr(take()); } + T &operator*() const { assert(Ptr && "Cannot dereference null pointer"); return *Ptr; diff --git a/unittests/ADT/OwningPtrTest.cpp b/unittests/ADT/OwningPtrTest.cpp index 75db2ba20be..aef4d97bd66 100644 --- a/unittests/ADT/OwningPtrTest.cpp +++ b/unittests/ADT/OwningPtrTest.cpp @@ -174,4 +174,82 @@ TEST_F(OwningPtrTest, Swap) { EXPECT_EQ(2u, TrackDestructor::Destructions); } +TEST_F(OwningPtrTest, UniqueToOwningConstruction) { + TrackDestructor::ResetCounts(); + { + std::unique_ptr A(new TrackDestructor(3)); + OwningPtr B = std::move(A); + EXPECT_FALSE(A); + EXPECT_TRUE(!A); + EXPECT_FALSE(A.get()); + EXPECT_TRUE((bool)B); + EXPECT_FALSE(!B); + EXPECT_TRUE(B.get()); + EXPECT_TRUE(B.isValid()); + EXPECT_EQ(3, (*B).val); + EXPECT_EQ(3, B->val); + EXPECT_EQ(0u, TrackDestructor::Destructions); + } + EXPECT_EQ(1u, TrackDestructor::Destructions); +} + +TEST_F(OwningPtrTest, UniqueToOwningAssignment) { + TrackDestructor::ResetCounts(); + { + std::unique_ptr A(new TrackDestructor(3)); + OwningPtr B(new TrackDestructor(4)); + B = std::move(A); + EXPECT_FALSE(A); + EXPECT_TRUE(!A); + EXPECT_FALSE(A.get()); + EXPECT_TRUE((bool)B); + EXPECT_FALSE(!B); + EXPECT_TRUE(B.get()); + EXPECT_TRUE(B.isValid()); + EXPECT_EQ(3, (*B).val); + EXPECT_EQ(3, B->val); + EXPECT_EQ(1u, TrackDestructor::Destructions); + } + EXPECT_EQ(2u, TrackDestructor::Destructions); +} + +TEST_F(OwningPtrTest, TakeUniqueConstruction) { + TrackDestructor::ResetCounts(); + { + OwningPtr A(new TrackDestructor(3)); + std::unique_ptr B = A.take_unique(); + EXPECT_FALSE(A); + EXPECT_TRUE(!A); + EXPECT_FALSE(A.get()); + EXPECT_FALSE(A.isValid()); + EXPECT_TRUE((bool)B); + EXPECT_FALSE(!B); + EXPECT_TRUE(B.get()); + EXPECT_EQ(3, (*B).val); + EXPECT_EQ(3, B->val); + EXPECT_EQ(0u, TrackDestructor::Destructions); + } + EXPECT_EQ(1u, TrackDestructor::Destructions); +} + +#if LLVM_HAS_RVALUE_REFERENCE_THIS +TEST_F(OwningPtrTest, OwningToUniqueConstruction) { + TrackDestructor::ResetCounts(); + { + OwningPtr A(new TrackDestructor(3)); + std::unique_ptr B = std::move(A); + EXPECT_FALSE(A); + EXPECT_TRUE(!A); + EXPECT_FALSE(A.get()); + EXPECT_FALSE(A.isValid()); + EXPECT_TRUE((bool)B); + EXPECT_FALSE(!B); + EXPECT_TRUE(B.get()); + EXPECT_EQ(3, (*B).val); + EXPECT_EQ(3, B->val); + EXPECT_EQ(0u, TrackDestructor::Destructions); + } + EXPECT_EQ(1u, TrackDestructor::Destructions); +} +#endif }