xref: /aosp_15_r20/external/federated-compute/fcp/base/unique_value_test.cc (revision 14675a029014e728ec732f129a32e299b2da0601)
1*14675a02SAndroid Build Coastguard Worker /*
2*14675a02SAndroid Build Coastguard Worker  * Copyright 2019 Google LLC
3*14675a02SAndroid Build Coastguard Worker  *
4*14675a02SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*14675a02SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*14675a02SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*14675a02SAndroid Build Coastguard Worker  *
8*14675a02SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*14675a02SAndroid Build Coastguard Worker  *
10*14675a02SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*14675a02SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*14675a02SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*14675a02SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*14675a02SAndroid Build Coastguard Worker  * limitations under the License.
15*14675a02SAndroid Build Coastguard Worker  */
16*14675a02SAndroid Build Coastguard Worker 
17*14675a02SAndroid Build Coastguard Worker #include "fcp/base/unique_value.h"
18*14675a02SAndroid Build Coastguard Worker 
19*14675a02SAndroid Build Coastguard Worker #include <utility>
20*14675a02SAndroid Build Coastguard Worker 
21*14675a02SAndroid Build Coastguard Worker #include "gmock/gmock.h"
22*14675a02SAndroid Build Coastguard Worker #include "gtest/gtest.h"
23*14675a02SAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
24*14675a02SAndroid Build Coastguard Worker #include "fcp/base/monitoring.h"
25*14675a02SAndroid Build Coastguard Worker 
26*14675a02SAndroid Build Coastguard Worker namespace fcp {
27*14675a02SAndroid Build Coastguard Worker 
28*14675a02SAndroid Build Coastguard Worker using ::testing::Eq;
29*14675a02SAndroid Build Coastguard Worker 
30*14675a02SAndroid Build Coastguard Worker struct ValueBox {
31*14675a02SAndroid Build Coastguard Worker   bool destructed = false;
32*14675a02SAndroid Build Coastguard Worker   int value = 0;
33*14675a02SAndroid Build Coastguard Worker };
34*14675a02SAndroid Build Coastguard Worker 
35*14675a02SAndroid Build Coastguard Worker class TracedValue {
36*14675a02SAndroid Build Coastguard Worker  public:
TracedValue(int value)37*14675a02SAndroid Build Coastguard Worker   explicit TracedValue(int value) : local_value_(0), box_(nullptr) {
38*14675a02SAndroid Build Coastguard Worker     UpdateValue(value);
39*14675a02SAndroid Build Coastguard Worker   }
40*14675a02SAndroid Build Coastguard Worker 
AttachToBox(ValueBox * box)41*14675a02SAndroid Build Coastguard Worker   void AttachToBox(ValueBox* box) {
42*14675a02SAndroid Build Coastguard Worker     FCP_CHECK(box_ == nullptr);
43*14675a02SAndroid Build Coastguard Worker     box_ = box;
44*14675a02SAndroid Build Coastguard Worker     UpdateValue(local_value_);
45*14675a02SAndroid Build Coastguard Worker   }
46*14675a02SAndroid Build Coastguard Worker 
TracedValue(TracedValue const & other)47*14675a02SAndroid Build Coastguard Worker   TracedValue(TracedValue const& other) : local_value_(0), box_(nullptr) {
48*14675a02SAndroid Build Coastguard Worker     UpdateValue(other.value());
49*14675a02SAndroid Build Coastguard Worker   }
50*14675a02SAndroid Build Coastguard Worker 
operator =(TracedValue const & other)51*14675a02SAndroid Build Coastguard Worker   TracedValue& operator=(TracedValue const& other) {
52*14675a02SAndroid Build Coastguard Worker     UpdateValue(other.value());
53*14675a02SAndroid Build Coastguard Worker     return *this;
54*14675a02SAndroid Build Coastguard Worker   }
55*14675a02SAndroid Build Coastguard Worker 
~TracedValue()56*14675a02SAndroid Build Coastguard Worker   ~TracedValue() {
57*14675a02SAndroid Build Coastguard Worker     if (box_) {
58*14675a02SAndroid Build Coastguard Worker       box_->destructed = true;
59*14675a02SAndroid Build Coastguard Worker     }
60*14675a02SAndroid Build Coastguard Worker   }
61*14675a02SAndroid Build Coastguard Worker 
value() const62*14675a02SAndroid Build Coastguard Worker   int value() const { return local_value_; }
63*14675a02SAndroid Build Coastguard Worker 
64*14675a02SAndroid Build Coastguard Worker  private:
UpdateValue(int value)65*14675a02SAndroid Build Coastguard Worker   void UpdateValue(int value) {
66*14675a02SAndroid Build Coastguard Worker     local_value_ = value;
67*14675a02SAndroid Build Coastguard Worker     if (box_) {
68*14675a02SAndroid Build Coastguard Worker       box_->destructed = false;
69*14675a02SAndroid Build Coastguard Worker       box_->value = value;
70*14675a02SAndroid Build Coastguard Worker     }
71*14675a02SAndroid Build Coastguard Worker   }
72*14675a02SAndroid Build Coastguard Worker 
73*14675a02SAndroid Build Coastguard Worker   int local_value_;
74*14675a02SAndroid Build Coastguard Worker   ValueBox* box_;
75*14675a02SAndroid Build Coastguard Worker };
76*14675a02SAndroid Build Coastguard Worker 
TEST(UniqueValueTest,MoveToInnerScope)77*14675a02SAndroid Build Coastguard Worker TEST(UniqueValueTest, MoveToInnerScope) {
78*14675a02SAndroid Build Coastguard Worker   ValueBox box_a{};
79*14675a02SAndroid Build Coastguard Worker   ValueBox box_b{};
80*14675a02SAndroid Build Coastguard Worker 
81*14675a02SAndroid Build Coastguard Worker   {
82*14675a02SAndroid Build Coastguard Worker     UniqueValue<TracedValue> a = MakeUniqueValue<TracedValue>(123);
83*14675a02SAndroid Build Coastguard Worker     a->AttachToBox(&box_a);
84*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(false));
85*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.value, Eq(123));
86*14675a02SAndroid Build Coastguard Worker 
87*14675a02SAndroid Build Coastguard Worker     {
88*14675a02SAndroid Build Coastguard Worker       UniqueValue<TracedValue> b = MakeUniqueValue<TracedValue>(456);
89*14675a02SAndroid Build Coastguard Worker       b->AttachToBox(&box_b);
90*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.destructed, Eq(false));
91*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.value, Eq(456));
92*14675a02SAndroid Build Coastguard Worker 
93*14675a02SAndroid Build Coastguard Worker       b = std::move(a);
94*14675a02SAndroid Build Coastguard Worker 
95*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_a.destructed, Eq(true));
96*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.destructed, Eq(false));
97*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.value, Eq(123));
98*14675a02SAndroid Build Coastguard Worker     }
99*14675a02SAndroid Build Coastguard Worker 
100*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(true));
101*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_b.destructed, Eq(true));
102*14675a02SAndroid Build Coastguard Worker   }
103*14675a02SAndroid Build Coastguard Worker }
104*14675a02SAndroid Build Coastguard Worker 
TEST(UniqueValueTest,MoveToOuterScope)105*14675a02SAndroid Build Coastguard Worker TEST(UniqueValueTest, MoveToOuterScope) {
106*14675a02SAndroid Build Coastguard Worker   ValueBox box_a{};
107*14675a02SAndroid Build Coastguard Worker   ValueBox box_b{};
108*14675a02SAndroid Build Coastguard Worker 
109*14675a02SAndroid Build Coastguard Worker   {
110*14675a02SAndroid Build Coastguard Worker     UniqueValue<TracedValue> a = MakeUniqueValue<TracedValue>(123);
111*14675a02SAndroid Build Coastguard Worker     a->AttachToBox(&box_a);
112*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(false));
113*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.value, Eq(123));
114*14675a02SAndroid Build Coastguard Worker 
115*14675a02SAndroid Build Coastguard Worker     {
116*14675a02SAndroid Build Coastguard Worker       UniqueValue<TracedValue> b = MakeUniqueValue<TracedValue>(456);
117*14675a02SAndroid Build Coastguard Worker       b->AttachToBox(&box_b);
118*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.destructed, Eq(false));
119*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.value, Eq(456));
120*14675a02SAndroid Build Coastguard Worker 
121*14675a02SAndroid Build Coastguard Worker       a = std::move(b);
122*14675a02SAndroid Build Coastguard Worker 
123*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_a.destructed, Eq(false));
124*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_a.value, Eq(456));
125*14675a02SAndroid Build Coastguard Worker       EXPECT_THAT(box_b.destructed, Eq(true));
126*14675a02SAndroid Build Coastguard Worker     }
127*14675a02SAndroid Build Coastguard Worker 
128*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(false));
129*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.value, Eq(456));
130*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_b.destructed, Eq(true));
131*14675a02SAndroid Build Coastguard Worker   }
132*14675a02SAndroid Build Coastguard Worker 
133*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_a.destructed, Eq(true));
134*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_b.destructed, Eq(true));
135*14675a02SAndroid Build Coastguard Worker }
136*14675a02SAndroid Build Coastguard Worker 
TEST(UniqueValueTest,Emplace)137*14675a02SAndroid Build Coastguard Worker TEST(UniqueValueTest, Emplace) {
138*14675a02SAndroid Build Coastguard Worker   ValueBox box_a{};
139*14675a02SAndroid Build Coastguard Worker   ValueBox box_b{};
140*14675a02SAndroid Build Coastguard Worker   {
141*14675a02SAndroid Build Coastguard Worker     UniqueValue<TracedValue> v{std::nullopt};
142*14675a02SAndroid Build Coastguard Worker     v.Emplace(123);
143*14675a02SAndroid Build Coastguard Worker     v->AttachToBox(&box_a);
144*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(false));
145*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.value, Eq(123));
146*14675a02SAndroid Build Coastguard Worker     v.Emplace(321);
147*14675a02SAndroid Build Coastguard Worker     v->AttachToBox(&box_b);
148*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_a.destructed, Eq(true));
149*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_b.destructed, Eq(false));
150*14675a02SAndroid Build Coastguard Worker     EXPECT_THAT(box_b.value, Eq(321));
151*14675a02SAndroid Build Coastguard Worker   }
152*14675a02SAndroid Build Coastguard Worker }
153*14675a02SAndroid Build Coastguard Worker 
TEST(UniqueValueTest,Reset)154*14675a02SAndroid Build Coastguard Worker TEST(UniqueValueTest, Reset) {
155*14675a02SAndroid Build Coastguard Worker   ValueBox box_a{};
156*14675a02SAndroid Build Coastguard Worker   UniqueValue<TracedValue> v = MakeUniqueValue<TracedValue>(123);
157*14675a02SAndroid Build Coastguard Worker   v.Emplace(123);
158*14675a02SAndroid Build Coastguard Worker   v->AttachToBox(&box_a);
159*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_a.destructed, Eq(false));
160*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_a.value, Eq(123));
161*14675a02SAndroid Build Coastguard Worker   v.Reset();
162*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_a.destructed, Eq(true));
163*14675a02SAndroid Build Coastguard Worker   v.Reset();
164*14675a02SAndroid Build Coastguard Worker   EXPECT_THAT(box_a.destructed, Eq(true));
165*14675a02SAndroid Build Coastguard Worker }
166*14675a02SAndroid Build Coastguard Worker 
167*14675a02SAndroid Build Coastguard Worker }  // namespace fcp
168