[PATCH] Add conversions between OwningPtr<T> and std::unique_ptr<T>.
Ahmed Charles
acharles at outlook.com
Sat Mar 1 15:45:56 PST 2014
Hi chandlerc,
Note: The implicit conversion from OwningPtr<T> to std::unique_ptr<T>
requires rvalue references for this support in the compiler to avoid
moving from an lvalue OwningPtr<T>. To work around this, take_unique is
available, which returns a std::unique_ptr<T>.
std::unique_ptr<T> supports conversions to/from other other types as well
as configurable deletion. Neither of these is supported by OwningPtr<T>,
and thus are not supported by this change.
http://llvm-reviews.chandlerc.com/D2910
Files:
include/llvm/ADT/OwningPtr.h
unittests/ADT/OwningPtrTest.cpp
Index: include/llvm/ADT/OwningPtr.h
===================================================================
--- include/llvm/ADT/OwningPtr.h
+++ include/llvm/ADT/OwningPtr.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
+#include <memory>
namespace llvm {
@@ -39,6 +40,19 @@
return *this;
}
+ OwningPtr(std::unique_ptr<T> &&Other) : Ptr(Other.release()) {}
+
+ OwningPtr &operator=(std::unique_ptr<T> &&Other) {
+ reset(Other.release());
+ return *this;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS && 0
+ operator std::unique_ptr<T>() && {
+ return std::unique_ptr<T>(take());
+ }
+#endif
+
~OwningPtr() {
delete Ptr;
}
@@ -61,6 +75,10 @@
return Tmp;
}
+ std::unique_ptr<T> take_unique() {
+ return std::unique_ptr<T>(take());
+ }
+
T &operator*() const {
assert(Ptr && "Cannot dereference null pointer");
return *Ptr;
Index: unittests/ADT/OwningPtrTest.cpp
===================================================================
--- unittests/ADT/OwningPtrTest.cpp
+++ unittests/ADT/OwningPtrTest.cpp
@@ -178,5 +178,84 @@
EXPECT_EQ(2u, TrackDestructor::Destructions);
}
+TEST_F(OwningPtrTest, UniqueToOwningConstruction) {
+ TrackDestructor::ResetCounts();
+ {
+ std::unique_ptr<TrackDestructor> A(new TrackDestructor(3));
+ OwningPtr<TrackDestructor> B = std::move(A);
+ EXPECT_FALSE(A);
+ EXPECT_TRUE(!A);
+ EXPECT_FALSE(A.get());
+ EXPECT_TRUE(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<TrackDestructor> A(new TrackDestructor(3));
+ OwningPtr<TrackDestructor> B(new TrackDestructor(4));
+ B = std::move(A);
+ EXPECT_FALSE(A);
+ EXPECT_TRUE(!A);
+ EXPECT_FALSE(A.get());
+ EXPECT_TRUE(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<TrackDestructor> A(new TrackDestructor(3));
+ std::unique_ptr<TrackDestructor> B = A.take_unique();
+ EXPECT_FALSE(A);
+ EXPECT_TRUE(!A);
+ EXPECT_FALSE(A.get());
+ EXPECT_FALSE(A.isValid());
+ EXPECT_TRUE(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 && 0
+TEST_F(OwningPtrTest, OwningToUniqueConstruction) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> A(new TrackDestructor(3));
+ std::unique_ptr<TrackDestructor> B = std::move(A);
+ EXPECT_FALSE(A);
+ EXPECT_TRUE(!A);
+ EXPECT_FALSE(A.get());
+ EXPECT_FALSE(A.isValid());
+ EXPECT_TRUE(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
+
} // end anonymous namespace
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2910.1.patch
Type: text/x-patch
Size: 3487 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140301/62429c70/attachment.bin>
More information about the llvm-commits
mailing list