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