1*84e33947SAndroid Build Coastguard Worker
2*84e33947SAndroid Build Coastguard Worker /*
3*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
4*84e33947SAndroid Build Coastguard Worker *
5*84e33947SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*84e33947SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*84e33947SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*84e33947SAndroid Build Coastguard Worker *
9*84e33947SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*84e33947SAndroid Build Coastguard Worker *
11*84e33947SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*84e33947SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*84e33947SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*84e33947SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*84e33947SAndroid Build Coastguard Worker * limitations under the License.
16*84e33947SAndroid Build Coastguard Worker */
17*84e33947SAndroid Build Coastguard Worker
18*84e33947SAndroid Build Coastguard Worker #include "gtest/gtest.h"
19*84e33947SAndroid Build Coastguard Worker
20*84e33947SAndroid Build Coastguard Worker #include <cassert>
21*84e33947SAndroid Build Coastguard Worker
22*84e33947SAndroid Build Coastguard Worker #include "chre/util/non_copyable.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/util/optional.h"
24*84e33947SAndroid Build Coastguard Worker
25*84e33947SAndroid Build Coastguard Worker using chre::Optional;
26*84e33947SAndroid Build Coastguard Worker
27*84e33947SAndroid Build Coastguard Worker class DestructorTestingObject {
28*84e33947SAndroid Build Coastguard Worker public:
~DestructorTestingObject()29*84e33947SAndroid Build Coastguard Worker ~DestructorTestingObject() {
30*84e33947SAndroid Build Coastguard Worker if (valueToFlipWhenDestruct != nullptr) {
31*84e33947SAndroid Build Coastguard Worker *valueToFlipWhenDestruct = !*valueToFlipWhenDestruct;
32*84e33947SAndroid Build Coastguard Worker }
33*84e33947SAndroid Build Coastguard Worker }
34*84e33947SAndroid Build Coastguard Worker
setValueToFlipWhenDestruct(bool * value)35*84e33947SAndroid Build Coastguard Worker void setValueToFlipWhenDestruct(bool *value) {
36*84e33947SAndroid Build Coastguard Worker valueToFlipWhenDestruct = value;
37*84e33947SAndroid Build Coastguard Worker }
38*84e33947SAndroid Build Coastguard Worker
39*84e33947SAndroid Build Coastguard Worker private:
40*84e33947SAndroid Build Coastguard Worker bool *valueToFlipWhenDestruct = nullptr;
41*84e33947SAndroid Build Coastguard Worker };
42*84e33947SAndroid Build Coastguard Worker
TEST(Optional,ShouldDestructContainedObject)43*84e33947SAndroid Build Coastguard Worker TEST(Optional, ShouldDestructContainedObject) {
44*84e33947SAndroid Build Coastguard Worker bool destructed = false;
45*84e33947SAndroid Build Coastguard Worker {
46*84e33947SAndroid Build Coastguard Worker Optional<DestructorTestingObject> object(DestructorTestingObject{});
47*84e33947SAndroid Build Coastguard Worker object.value().setValueToFlipWhenDestruct(&destructed);
48*84e33947SAndroid Build Coastguard Worker }
49*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(destructed);
50*84e33947SAndroid Build Coastguard Worker }
51*84e33947SAndroid Build Coastguard Worker
TEST(Optional,NoValueByDefault)52*84e33947SAndroid Build Coastguard Worker TEST(Optional, NoValueByDefault) {
53*84e33947SAndroid Build Coastguard Worker Optional<int> myInt;
54*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myInt.has_value());
55*84e33947SAndroid Build Coastguard Worker }
56*84e33947SAndroid Build Coastguard Worker
TEST(Optional,NonDefaultValueByDefault)57*84e33947SAndroid Build Coastguard Worker TEST(Optional, NonDefaultValueByDefault) {
58*84e33947SAndroid Build Coastguard Worker Optional<int> myInt(0x1337);
59*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
60*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myInt, 0x1337);
61*84e33947SAndroid Build Coastguard Worker }
62*84e33947SAndroid Build Coastguard Worker
TEST(Optional,NonDefaultMovedValueByDefault)63*84e33947SAndroid Build Coastguard Worker TEST(Optional, NonDefaultMovedValueByDefault) {
64*84e33947SAndroid Build Coastguard Worker Optional<int> myInt(std::move(0x1337));
65*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
66*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myInt, 0x1337);
67*84e33947SAndroid Build Coastguard Worker }
68*84e33947SAndroid Build Coastguard Worker
TEST(Optional,CopyConstruct)69*84e33947SAndroid Build Coastguard Worker TEST(Optional, CopyConstruct) {
70*84e33947SAndroid Build Coastguard Worker Optional<int> myInt(0x1337);
71*84e33947SAndroid Build Coastguard Worker Optional<int> myNewInt(myInt);
72*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myNewInt.has_value());
73*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myNewInt, 0x1337);
74*84e33947SAndroid Build Coastguard Worker }
75*84e33947SAndroid Build Coastguard Worker
TEST(Optional,CopyConstructConst)76*84e33947SAndroid Build Coastguard Worker TEST(Optional, CopyConstructConst) {
77*84e33947SAndroid Build Coastguard Worker const Optional<int> myInt(0x1337);
78*84e33947SAndroid Build Coastguard Worker Optional<int> myNewInt(myInt);
79*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myNewInt.has_value());
80*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myNewInt, 0x1337);
81*84e33947SAndroid Build Coastguard Worker }
82*84e33947SAndroid Build Coastguard Worker
TEST(Optional,CopyAssignAndRead)83*84e33947SAndroid Build Coastguard Worker TEST(Optional, CopyAssignAndRead) {
84*84e33947SAndroid Build Coastguard Worker Optional<int> myInt;
85*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myInt.has_value());
86*84e33947SAndroid Build Coastguard Worker myInt = 0x1337;
87*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myInt, 0x1337);
88*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
89*84e33947SAndroid Build Coastguard Worker myInt.reset();
90*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myInt.has_value());
91*84e33947SAndroid Build Coastguard Worker }
92*84e33947SAndroid Build Coastguard Worker
TEST(Optional,MoveAssignAndRead)93*84e33947SAndroid Build Coastguard Worker TEST(Optional, MoveAssignAndRead) {
94*84e33947SAndroid Build Coastguard Worker Optional<int> myInt;
95*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myInt.has_value());
96*84e33947SAndroid Build Coastguard Worker myInt = std::move(0xcafe);
97*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
98*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myInt, 0xcafe);
99*84e33947SAndroid Build Coastguard Worker }
100*84e33947SAndroid Build Coastguard Worker
TEST(Optional,OptionalMoveAssignAndRead)101*84e33947SAndroid Build Coastguard Worker TEST(Optional, OptionalMoveAssignAndRead) {
102*84e33947SAndroid Build Coastguard Worker Optional<int> myInt(0x1337);
103*84e33947SAndroid Build Coastguard Worker Optional<int> myMovedInt;
104*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myMovedInt.has_value());
105*84e33947SAndroid Build Coastguard Worker myMovedInt = std::move(myInt);
106*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
107*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myMovedInt.has_value());
108*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myMovedInt, 0x1337);
109*84e33947SAndroid Build Coastguard Worker }
110*84e33947SAndroid Build Coastguard Worker
TEST(Optional,OptionalCopyAssignAndRead)111*84e33947SAndroid Build Coastguard Worker TEST(Optional, OptionalCopyAssignAndRead) {
112*84e33947SAndroid Build Coastguard Worker Optional<int> myInt(0x1337);
113*84e33947SAndroid Build Coastguard Worker Optional<int> myCopiedInt;
114*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(myCopiedInt.has_value());
115*84e33947SAndroid Build Coastguard Worker myCopiedInt = myInt;
116*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myInt.has_value());
117*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(myCopiedInt.has_value());
118*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myInt, 0x1337);
119*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*myCopiedInt, 0x1337);
120*84e33947SAndroid Build Coastguard Worker }
121*84e33947SAndroid Build Coastguard Worker
122*84e33947SAndroid Build Coastguard Worker static constexpr int kInvalidValue = -1;
123*84e33947SAndroid Build Coastguard Worker
124*84e33947SAndroid Build Coastguard Worker class MovableButNonCopyable : public chre::NonCopyable {
125*84e33947SAndroid Build Coastguard Worker public:
126*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable() = default;
MovableButNonCopyable(int value)127*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable(int value) : mValue(value) {}
MovableButNonCopyable(MovableButNonCopyable && other)128*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable(MovableButNonCopyable &&other) {
129*84e33947SAndroid Build Coastguard Worker mValue = other.mValue;
130*84e33947SAndroid Build Coastguard Worker other.mValue = kInvalidValue;
131*84e33947SAndroid Build Coastguard Worker }
132*84e33947SAndroid Build Coastguard Worker
operator =(MovableButNonCopyable && other)133*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable &operator=(MovableButNonCopyable &&other) {
134*84e33947SAndroid Build Coastguard Worker assert(mMagic == kConstructedMagic);
135*84e33947SAndroid Build Coastguard Worker mValue = other.mValue;
136*84e33947SAndroid Build Coastguard Worker other.mValue = kInvalidValue;
137*84e33947SAndroid Build Coastguard Worker return *this;
138*84e33947SAndroid Build Coastguard Worker }
139*84e33947SAndroid Build Coastguard Worker
~MovableButNonCopyable()140*84e33947SAndroid Build Coastguard Worker ~MovableButNonCopyable() {
141*84e33947SAndroid Build Coastguard Worker mMagic = kUninitializedMagic;
142*84e33947SAndroid Build Coastguard Worker mValue = kUninitializedMagic;
143*84e33947SAndroid Build Coastguard Worker }
144*84e33947SAndroid Build Coastguard Worker
getValue() const145*84e33947SAndroid Build Coastguard Worker int getValue() const {
146*84e33947SAndroid Build Coastguard Worker return mValue;
147*84e33947SAndroid Build Coastguard Worker }
148*84e33947SAndroid Build Coastguard Worker
149*84e33947SAndroid Build Coastguard Worker private:
150*84e33947SAndroid Build Coastguard Worker static constexpr int kConstructedMagic = 0xfeedc0fe;
151*84e33947SAndroid Build Coastguard Worker static constexpr int kUninitializedMagic = 0xdeadbeef;
152*84e33947SAndroid Build Coastguard Worker
153*84e33947SAndroid Build Coastguard Worker int mMagic = kConstructedMagic;
154*84e33947SAndroid Build Coastguard Worker int mValue = kInvalidValue;
155*84e33947SAndroid Build Coastguard Worker };
156*84e33947SAndroid Build Coastguard Worker
TEST(Optional,UninitializedAssignment)157*84e33947SAndroid Build Coastguard Worker TEST(Optional, UninitializedAssignment) {
158*84e33947SAndroid Build Coastguard Worker constexpr int kValue1 = 0xd00d;
159*84e33947SAndroid Build Coastguard Worker constexpr int kValue2 = 0xcafe;
160*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable transferee1(kValue1);
161*84e33947SAndroid Build Coastguard Worker MovableButNonCopyable transferee2(kValue2);
162*84e33947SAndroid Build Coastguard Worker
163*84e33947SAndroid Build Coastguard Worker Optional<MovableButNonCopyable> container;
164*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(container.has_value());
165*84e33947SAndroid Build Coastguard Worker
166*84e33947SAndroid Build Coastguard Worker container = std::move(transferee1);
167*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(container.has_value());
168*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(container->getValue(), kValue1);
169*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(transferee1.getValue(), kInvalidValue);
170*84e33947SAndroid Build Coastguard Worker
171*84e33947SAndroid Build Coastguard Worker container.reset();
172*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(container.has_value());
173*84e33947SAndroid Build Coastguard Worker
174*84e33947SAndroid Build Coastguard Worker container = std::move(transferee2);
175*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(container.has_value());
176*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(container->getValue(), kValue2);
177*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(transferee2.getValue(), kInvalidValue);
178*84e33947SAndroid Build Coastguard Worker }
179*84e33947SAndroid Build Coastguard Worker
180*84e33947SAndroid Build Coastguard Worker // TODO: should add some tests to cover the possible assignment outcomes between
181*84e33947SAndroid Build Coastguard Worker // two Optional instances (e.g. assign one w/o value to one w/value, etc)
182