diff options
Diffstat (limited to 'unittests/ADT/OwningPtrTest.cpp')
-rw-r--r-- | unittests/ADT/OwningPtrTest.cpp | 273 |
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 +} |