1 #include <cstring> 2 3 #include "gtest/gtest.h" 4 5 #include "chre/util/unique_ptr.h" 6 7 using chre::MakeUnique; 8 using chre::MakeUniqueZeroFill; 9 using chre::UniquePtr; 10 11 struct Value { 12 Value(int value) : value(value) { 13 constructionCounter++; 14 } 15 16 ~Value() { 17 constructionCounter--; 18 } 19 20 Value &operator=(Value &&other) { 21 value = other.value; 22 return *this; 23 } 24 25 int value; 26 static int constructionCounter; 27 }; 28 29 int Value::constructionCounter = 0; 30 31 TEST(UniquePtr, Construct) { 32 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 33 ASSERT_FALSE(myInt.isNull()); 34 EXPECT_EQ(myInt.get()->value, 0xcafe); 35 EXPECT_EQ(myInt->value, 0xcafe); 36 EXPECT_EQ((*myInt).value, 0xcafe); 37 EXPECT_EQ(myInt[0].value, 0xcafe); 38 } 39 40 struct BigArray { 41 int x[2048]; 42 }; 43 44 TEST(UniquePtr, MakeUniqueZeroFill) { 45 BigArray baseline = {}; 46 auto myArray = MakeUniqueZeroFill<BigArray>(); 47 ASSERT_FALSE(myArray.isNull()); 48 // Note that this doesn't actually test things properly, because we don't 49 // guarantee that malloc is not already giving us zeroed out memory. To 50 // properly do it, we could inject the allocator, but this function is simple 51 // enough that it's not really worth the effort. 52 EXPECT_EQ(std::memcmp(&baseline, myArray.get(), sizeof(baseline)), 0); 53 } 54 55 TEST(UniquePtr, MoveConstruct) { 56 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 57 ASSERT_FALSE(myInt.isNull()); 58 Value *value = myInt.get(); 59 60 UniquePtr<Value> moved(std::move(myInt)); 61 EXPECT_EQ(moved.get(), value); 62 EXPECT_EQ(myInt.get(), nullptr); 63 } 64 65 TEST(UniquePtr, Move) { 66 Value::constructionCounter = 0; 67 68 { 69 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 70 ASSERT_FALSE(myInt.isNull()); 71 EXPECT_EQ(Value::constructionCounter, 1); 72 73 UniquePtr<Value> myMovedInt = MakeUnique<Value>(0); 74 ASSERT_FALSE(myMovedInt.isNull()); 75 EXPECT_EQ(Value::constructionCounter, 2); 76 myMovedInt = std::move(myInt); 77 ASSERT_FALSE(myMovedInt.isNull()); 78 ASSERT_TRUE(myInt.isNull()); 79 EXPECT_EQ(myMovedInt.get()->value, 0xcafe); 80 } 81 82 EXPECT_EQ(Value::constructionCounter, 0); 83 } 84 85 TEST(UniquePtr, Release) { 86 Value::constructionCounter = 0; 87 88 Value *value1, *value2; 89 { 90 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 91 ASSERT_FALSE(myInt.isNull()); 92 EXPECT_EQ(Value::constructionCounter, 1); 93 value1 = myInt.get(); 94 EXPECT_NE(value1, nullptr); 95 value2 = myInt.release(); 96 EXPECT_EQ(value1, value2); 97 EXPECT_EQ(myInt.get(), nullptr); 98 EXPECT_TRUE(myInt.isNull()); 99 } 100 101 EXPECT_EQ(Value::constructionCounter, 1); 102 EXPECT_EQ(value2->value, 0xcafe); 103 value2->~Value(); 104 chre::memoryFree(value2); 105 } 106 107 TEST(UniquePtr, Reset) { 108 Value::constructionCounter = 0; 109 110 { 111 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 112 EXPECT_EQ(myInt.get()->value, 0xcafe); 113 EXPECT_EQ(Value::constructionCounter, 1); 114 myInt.reset(nullptr); 115 EXPECT_EQ(myInt.get(), nullptr); 116 EXPECT_EQ(Value::constructionCounter, 0); 117 118 myInt = MakeUnique<Value>(0xcafe); 119 UniquePtr<Value> myInt2 = MakeUnique<Value>(0xface); 120 EXPECT_EQ(Value::constructionCounter, 2); 121 myInt.reset(myInt2.release()); 122 EXPECT_EQ(Value::constructionCounter, 1); 123 EXPECT_EQ(myInt.get()->value, 0xface); 124 EXPECT_EQ(myInt2.get(), nullptr); 125 126 myInt.reset(); 127 EXPECT_EQ(myInt.get(), nullptr); 128 } 129 130 EXPECT_EQ(Value::constructionCounter, 0); 131 } 132 133 TEST(UniquePtr, EqualityOperator) { 134 Value::constructionCounter = 0; 135 136 { 137 UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe); 138 EXPECT_TRUE(myInt != nullptr); 139 140 myInt.reset(); 141 EXPECT_TRUE(myInt == nullptr); 142 } 143 144 EXPECT_EQ(Value::constructionCounter, 0); 145 } 146