aboutsummaryrefslogtreecommitdiffstats
path: root/unittests/ADT/OwningPtrTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ADT/OwningPtrTest.cpp')
-rw-r--r--unittests/ADT/OwningPtrTest.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/unittests/ADT/OwningPtrTest.cpp b/unittests/ADT/OwningPtrTest.cpp
new file mode 100644
index 0000000..aee955b
--- /dev/null
+++ b/unittests/ADT/OwningPtrTest.cpp
@@ -0,0 +1,273 @@
+//===- llvm/unittest/ADT/OwningPtrTest.cpp - OwningPtr unit tests ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+struct TrackDestructor {
+ static unsigned Destructions;
+ int val;
+ explicit TrackDestructor(int val) : val(val) {}
+ ~TrackDestructor() { ++Destructions; }
+ static void ResetCounts() { Destructions = 0; }
+
+private:
+ TrackDestructor(const TrackDestructor &other) LLVM_DELETED_FUNCTION;
+ TrackDestructor &
+ operator=(const TrackDestructor &other) LLVM_DELETED_FUNCTION;
+ TrackDestructor(TrackDestructor &&other) LLVM_DELETED_FUNCTION;
+ TrackDestructor &operator=(TrackDestructor &&other) LLVM_DELETED_FUNCTION;
+};
+
+unsigned TrackDestructor::Destructions = 0;
+
+// Test fixture
+class OwningPtrTest : public testing::Test {};
+
+TEST_F(OwningPtrTest, DefaultConstruction) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> O;
+ EXPECT_FALSE(O);
+ EXPECT_TRUE(!O);
+ EXPECT_FALSE(O.get());
+ EXPECT_FALSE(O.isValid());
+ }
+ EXPECT_EQ(0u, TrackDestructor::Destructions);
+}
+
+TEST_F(OwningPtrTest, PtrConstruction) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> O(new TrackDestructor(3));
+ EXPECT_TRUE((bool)O);
+ EXPECT_FALSE(!O);
+ EXPECT_TRUE(O.get());
+ EXPECT_TRUE(O.isValid());
+ EXPECT_EQ(3, (*O).val);
+ EXPECT_EQ(3, O->val);
+ EXPECT_EQ(0u, TrackDestructor::Destructions);
+ }
+ EXPECT_EQ(1u, TrackDestructor::Destructions);
+}
+
+TEST_F(OwningPtrTest, Reset) {
+ TrackDestructor::ResetCounts();
+ OwningPtr<TrackDestructor> O(new TrackDestructor(3));
+ EXPECT_EQ(0u, TrackDestructor::Destructions);
+ O.reset();
+ EXPECT_FALSE((bool)O);
+ EXPECT_TRUE(!O);
+ EXPECT_FALSE(O.get());
+ EXPECT_FALSE(O.isValid());
+ EXPECT_EQ(1u, TrackDestructor::Destructions);
+}
+
+TEST_F(OwningPtrTest, Take) {
+ TrackDestructor::ResetCounts();
+ TrackDestructor *T = 0;
+ {
+ OwningPtr<TrackDestructor> O(new TrackDestructor(3));
+ T = O.take();
+ EXPECT_FALSE((bool)O);
+ EXPECT_TRUE(!O);
+ EXPECT_FALSE(O.get());
+ EXPECT_FALSE(O.isValid());
+ EXPECT_TRUE(T);
+ EXPECT_EQ(3, T->val);
+ EXPECT_EQ(0u, TrackDestructor::Destructions);
+ }
+ delete T;
+ EXPECT_EQ(1u, TrackDestructor::Destructions);
+}
+
+TEST_F(OwningPtrTest, Release) {
+ TrackDestructor::ResetCounts();
+ TrackDestructor *T = 0;
+ {
+ OwningPtr<TrackDestructor> O(new TrackDestructor(3));
+ T = O.release();
+ EXPECT_FALSE((bool)O);
+ EXPECT_TRUE(!O);
+ EXPECT_FALSE(O.get());
+ EXPECT_FALSE(O.isValid());
+ EXPECT_TRUE(T);
+ EXPECT_EQ(3, T->val);
+ EXPECT_EQ(0u, TrackDestructor::Destructions);
+ }
+ delete T;
+ EXPECT_EQ(1u, TrackDestructor::Destructions);
+}
+
+TEST_F(OwningPtrTest, MoveConstruction) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> A(new TrackDestructor(3));
+ OwningPtr<TrackDestructor> B = std::move(A);
+ EXPECT_FALSE((bool)A);
+ EXPECT_TRUE(!A);
+ EXPECT_FALSE(A.get());
+ EXPECT_FALSE(A.isValid());
+ 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, MoveAssignment) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<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_FALSE(A.isValid());
+ 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, Swap) {
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> A(new TrackDestructor(3));
+ OwningPtr<TrackDestructor> B(new TrackDestructor(4));
+ B.swap(A);
+ EXPECT_TRUE((bool)A);
+ EXPECT_FALSE(!A);
+ EXPECT_TRUE(A.get());
+ EXPECT_TRUE(A.isValid());
+ EXPECT_EQ(4, (*A).val);
+ EXPECT_EQ(4, A->val);
+ 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(2u, TrackDestructor::Destructions);
+ TrackDestructor::ResetCounts();
+ {
+ OwningPtr<TrackDestructor> A(new TrackDestructor(3));
+ OwningPtr<TrackDestructor> B(new TrackDestructor(4));
+ swap(A, B);
+ EXPECT_TRUE((bool)A);
+ EXPECT_FALSE(!A);
+ EXPECT_TRUE(A.get());
+ EXPECT_TRUE(A.isValid());
+ EXPECT_EQ(4, (*A).val);
+ EXPECT_EQ(4, A->val);
+ 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(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((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<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((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<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((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<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((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
+}