2014-03-08 20:51:31 +08:00
|
|
|
//===- llvm/unittest/ADT/OwningPtrTest.cpp - OwningPtr unit tests ---------===//
|
2014-03-02 11:26:39 +08:00
|
|
|
//
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2014-03-05 16:25:08 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-03-02 11:26:39 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-03-02 11:38:32 +08:00
|
|
|
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
|
2014-03-02 11:26:39 +08:00
|
|
|
}
|