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