Skip to content

Commit 871171a

Browse files
committedMar 2, 2014
[C++11] Add support for OwningPtr<T> to be converted to and from
std::unique_ptr<T>. Patch by Ahmed Charles! llvm-svn: 202609
1 parent 337bd07 commit 871171a

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
 

‎llvm/include/llvm/ADT/OwningPtr.h

+14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Support/Compiler.h"
1818
#include <cassert>
1919
#include <cstddef>
20+
#include <memory>
2021

2122
namespace llvm {
2223

@@ -39,6 +40,17 @@ class OwningPtr {
3940
return *this;
4041
}
4142

43+
OwningPtr(std::unique_ptr<T> &&Other) : Ptr(Other.release()) {}
44+
45+
OwningPtr &operator=(std::unique_ptr<T> &&Other) {
46+
reset(Other.release());
47+
return *this;
48+
}
49+
50+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
51+
operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
52+
#endif
53+
4254
~OwningPtr() {
4355
delete Ptr;
4456
}
@@ -61,6 +73,8 @@ class OwningPtr {
6173
return Tmp;
6274
}
6375

76+
std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
77+
6478
T &operator*() const {
6579
assert(Ptr && "Cannot dereference null pointer");
6680
return *Ptr;

‎llvm/unittests/ADT/OwningPtrTest.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,82 @@ TEST_F(OwningPtrTest, Swap) {
174174
EXPECT_EQ(2u, TrackDestructor::Destructions);
175175
}
176176

177+
TEST_F(OwningPtrTest, UniqueToOwningConstruction) {
178+
TrackDestructor::ResetCounts();
179+
{
180+
std::unique_ptr<TrackDestructor> A(new TrackDestructor(3));
181+
OwningPtr<TrackDestructor> B = std::move(A);
182+
EXPECT_FALSE(A);
183+
EXPECT_TRUE(!A);
184+
EXPECT_FALSE(A.get());
185+
EXPECT_TRUE((bool)B);
186+
EXPECT_FALSE(!B);
187+
EXPECT_TRUE(B.get());
188+
EXPECT_TRUE(B.isValid());
189+
EXPECT_EQ(3, (*B).val);
190+
EXPECT_EQ(3, B->val);
191+
EXPECT_EQ(0u, TrackDestructor::Destructions);
192+
}
193+
EXPECT_EQ(1u, TrackDestructor::Destructions);
194+
}
195+
196+
TEST_F(OwningPtrTest, UniqueToOwningAssignment) {
197+
TrackDestructor::ResetCounts();
198+
{
199+
std::unique_ptr<TrackDestructor> A(new TrackDestructor(3));
200+
OwningPtr<TrackDestructor> B(new TrackDestructor(4));
201+
B = std::move(A);
202+
EXPECT_FALSE(A);
203+
EXPECT_TRUE(!A);
204+
EXPECT_FALSE(A.get());
205+
EXPECT_TRUE((bool)B);
206+
EXPECT_FALSE(!B);
207+
EXPECT_TRUE(B.get());
208+
EXPECT_TRUE(B.isValid());
209+
EXPECT_EQ(3, (*B).val);
210+
EXPECT_EQ(3, B->val);
211+
EXPECT_EQ(1u, TrackDestructor::Destructions);
212+
}
213+
EXPECT_EQ(2u, TrackDestructor::Destructions);
214+
}
215+
216+
TEST_F(OwningPtrTest, TakeUniqueConstruction) {
217+
TrackDestructor::ResetCounts();
218+
{
219+
OwningPtr<TrackDestructor> A(new TrackDestructor(3));
220+
std::unique_ptr<TrackDestructor> B = A.take_unique();
221+
EXPECT_FALSE(A);
222+
EXPECT_TRUE(!A);
223+
EXPECT_FALSE(A.get());
224+
EXPECT_FALSE(A.isValid());
225+
EXPECT_TRUE((bool)B);
226+
EXPECT_FALSE(!B);
227+
EXPECT_TRUE(B.get());
228+
EXPECT_EQ(3, (*B).val);
229+
EXPECT_EQ(3, B->val);
230+
EXPECT_EQ(0u, TrackDestructor::Destructions);
231+
}
232+
EXPECT_EQ(1u, TrackDestructor::Destructions);
233+
}
234+
235+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
236+
TEST_F(OwningPtrTest, OwningToUniqueConstruction) {
237+
TrackDestructor::ResetCounts();
238+
{
239+
OwningPtr<TrackDestructor> A(new TrackDestructor(3));
240+
std::unique_ptr<TrackDestructor> B = std::move(A);
241+
EXPECT_FALSE(A);
242+
EXPECT_TRUE(!A);
243+
EXPECT_FALSE(A.get());
244+
EXPECT_FALSE(A.isValid());
245+
EXPECT_TRUE((bool)B);
246+
EXPECT_FALSE(!B);
247+
EXPECT_TRUE(B.get());
248+
EXPECT_EQ(3, (*B).val);
249+
EXPECT_EQ(3, B->val);
250+
EXPECT_EQ(0u, TrackDestructor::Destructions);
251+
}
252+
EXPECT_EQ(1u, TrackDestructor::Destructions);
253+
}
254+
#endif
177255
}

0 commit comments

Comments
 (0)