xref: /aosp_15_r20/system/chre/util/tests/optional_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
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