1 #include <cstring>
2
3 #include "gtest/gtest.h"
4
5 #include "chre/util/unique_ptr.h"
6
7 using chre::UniquePtr;
8 using chre::MakeUnique;
9 using chre::MakeUniqueZeroFill;
10
11 struct Value {
ValueValue12 Value(int value) : value(value) {
13 constructionCounter++;
14 }
15
~ValueValue16 ~Value() {
17 constructionCounter--;
18 }
19
operator =Value20 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
TEST(UniquePtr,Construct)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
TEST(UniquePtr,MakeUniqueZeroFill)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
TEST(UniquePtr,MoveConstruct)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
TEST(UniquePtr,Move)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
TEST(UniquePtr,Release)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
TEST(UniquePtr,Reset)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
TEST(UniquePtr,EqualityOperator)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