<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Mar 1, 2014 at 7:38 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Sat Mar  1 21:38:32 2014<br>
New Revision: 202609<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=202609&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=202609&view=rev</a><br>
Log:<br>
[C++11] Add support for OwningPtr<T> to be converted to and from<br>
std::unique_ptr<T>.<br>
<br>
Patch by Ahmed Charles!<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/ADT/OwningPtr.h<br>
    llvm/trunk/unittests/ADT/OwningPtrTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/OwningPtr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/OwningPtr.h?rev=202609&r1=202608&r2=202609&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/OwningPtr.h?rev=202609&r1=202608&r2=202609&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/ADT/OwningPtr.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/OwningPtr.h Sat Mar  1 21:38:32 2014<br>
@@ -17,6 +17,7 @@<br>
 #include "llvm/Support/Compiler.h"<br>
 #include <cassert><br>
 #include <cstddef><br>
+#include <memory><br>
<br>
 namespace llvm {<br>
<br>
@@ -39,6 +40,17 @@ public:<br>
     return *this;<br>
   }<br>
<br>
+  OwningPtr(std::unique_ptr<T> &&Other) : Ptr(Other.release()) {}<br>
+<br>
+  OwningPtr &operator=(std::unique_ptr<T> &&Other) {<br></blockquote><div><br></div><div>Why an rvalue reference to a unique_ptr rather than passing the unique_ptr by value?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+    reset(Other.release());<br>
+    return *this;<br>
+  }<br>
+<br>
+#if LLVM_HAS_RVALUE_REFERENCE_THIS<br>
+  operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }<br>
+#endif<br>
+<br>
   ~OwningPtr() {<br>
     delete Ptr;<br>
   }<br>
@@ -61,6 +73,8 @@ public:<br>
     return Tmp;<br>
   }<br>
<br>
+  std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }<br>
+<br>
   T &operator*() const {<br>
     assert(Ptr && "Cannot dereference null pointer");<br>
     return *Ptr;<br>
<br>
Modified: llvm/trunk/unittests/ADT/OwningPtrTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/OwningPtrTest.cpp?rev=202609&r1=202608&r2=202609&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/OwningPtrTest.cpp?rev=202609&r1=202608&r2=202609&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/unittests/ADT/OwningPtrTest.cpp (original)<br>
+++ llvm/trunk/unittests/ADT/OwningPtrTest.cpp Sat Mar  1 21:38:32 2014<br>
@@ -174,4 +174,82 @@ TEST_F(OwningPtrTest, Swap) {<br>
   EXPECT_EQ(2u, TrackDestructor::Destructions);<br>
 }<br>
<br>
+TEST_F(OwningPtrTest, UniqueToOwningConstruction) {<br>
+  TrackDestructor::ResetCounts();<br>
+  {<br>
+    std::unique_ptr<TrackDestructor> A(new TrackDestructor(3));<br>
+    OwningPtr<TrackDestructor> B = std::move(A);<br>
+    EXPECT_FALSE(A);<br>
+    EXPECT_TRUE(!A);<br>
+    EXPECT_FALSE(A.get());<br>
+    EXPECT_TRUE((bool)B);<br>
+    EXPECT_FALSE(!B);<br>
+    EXPECT_TRUE(B.get());<br>
+    EXPECT_TRUE(B.isValid());<br>
+    EXPECT_EQ(3, (*B).val);<br>
+    EXPECT_EQ(3, B->val);<br>
+    EXPECT_EQ(0u, TrackDestructor::Destructions);<br>
+  }<br>
+  EXPECT_EQ(1u, TrackDestructor::Destructions);<br>
+}<br>
+<br>
+TEST_F(OwningPtrTest, UniqueToOwningAssignment) {<br>
+  TrackDestructor::ResetCounts();<br>
+  {<br>
+    std::unique_ptr<TrackDestructor> A(new TrackDestructor(3));<br>
+    OwningPtr<TrackDestructor> B(new TrackDestructor(4));<br>
+    B = std::move(A);<br>
+    EXPECT_FALSE(A);<br>
+    EXPECT_TRUE(!A);<br>
+    EXPECT_FALSE(A.get());<br>
+    EXPECT_TRUE((bool)B);<br>
+    EXPECT_FALSE(!B);<br>
+    EXPECT_TRUE(B.get());<br>
+    EXPECT_TRUE(B.isValid());<br>
+    EXPECT_EQ(3, (*B).val);<br>
+    EXPECT_EQ(3, B->val);<br>
+    EXPECT_EQ(1u, TrackDestructor::Destructions);<br>
+  }<br>
+  EXPECT_EQ(2u, TrackDestructor::Destructions);<br>
+}<br>
+<br>
+TEST_F(OwningPtrTest, TakeUniqueConstruction) {<br>
+  TrackDestructor::ResetCounts();<br>
+  {<br>
+    OwningPtr<TrackDestructor> A(new TrackDestructor(3));<br>
+    std::unique_ptr<TrackDestructor> B = A.take_unique();<br>
+    EXPECT_FALSE(A);<br>
+    EXPECT_TRUE(!A);<br>
+    EXPECT_FALSE(A.get());<br>
+    EXPECT_FALSE(A.isValid());<br>
+    EXPECT_TRUE((bool)B);<br>
+    EXPECT_FALSE(!B);<br>
+    EXPECT_TRUE(B.get());<br>
+    EXPECT_EQ(3, (*B).val);<br>
+    EXPECT_EQ(3, B->val);<br>
+    EXPECT_EQ(0u, TrackDestructor::Destructions);<br>
+  }<br>
+  EXPECT_EQ(1u, TrackDestructor::Destructions);<br>
+}<br>
+<br>
+#if LLVM_HAS_RVALUE_REFERENCE_THIS<br>
+TEST_F(OwningPtrTest, OwningToUniqueConstruction) {<br>
+  TrackDestructor::ResetCounts();<br>
+  {<br>
+    OwningPtr<TrackDestructor> A(new TrackDestructor(3));<br>
+    std::unique_ptr<TrackDestructor> B = std::move(A);<br>
+    EXPECT_FALSE(A);<br>
+    EXPECT_TRUE(!A);<br>
+    EXPECT_FALSE(A.get());<br>
+    EXPECT_FALSE(A.isValid());<br>
+    EXPECT_TRUE((bool)B);<br>
+    EXPECT_FALSE(!B);<br>
+    EXPECT_TRUE(B.get());<br>
+    EXPECT_EQ(3, (*B).val);<br>
+    EXPECT_EQ(3, B->val);<br>
+    EXPECT_EQ(0u, TrackDestructor::Destructions);<br>
+  }<br>
+  EXPECT_EQ(1u, TrackDestructor::Destructions);<br>
+}<br>
+#endif<br>
 }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>