1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/container/internal/test_instance_tracker.h"
16
17 #include "gtest/gtest.h"
18
19 namespace {
20
21 using absl::test_internal::CopyableMovableInstance;
22 using absl::test_internal::CopyableOnlyInstance;
23 using absl::test_internal::InstanceTracker;
24 using absl::test_internal::MovableOnlyInstance;
25
TEST(TestInstanceTracker,CopyableMovable)26 TEST(TestInstanceTracker, CopyableMovable) {
27 InstanceTracker tracker;
28 CopyableMovableInstance src(1);
29 EXPECT_EQ(1, src.value()) << src;
30 CopyableMovableInstance copy(src);
31 CopyableMovableInstance move(std::move(src));
32 EXPECT_EQ(1, tracker.copies());
33 EXPECT_EQ(1, tracker.moves());
34 EXPECT_EQ(0, tracker.swaps());
35 EXPECT_EQ(3, tracker.instances());
36 EXPECT_EQ(2, tracker.live_instances());
37 tracker.ResetCopiesMovesSwaps();
38
39 CopyableMovableInstance copy_assign(1);
40 copy_assign = copy;
41 CopyableMovableInstance move_assign(1);
42 move_assign = std::move(move);
43 EXPECT_EQ(1, tracker.copies());
44 EXPECT_EQ(1, tracker.moves());
45 EXPECT_EQ(0, tracker.swaps());
46 EXPECT_EQ(5, tracker.instances());
47 EXPECT_EQ(3, tracker.live_instances());
48 tracker.ResetCopiesMovesSwaps();
49
50 {
51 using std::swap;
52 swap(move_assign, copy);
53 swap(copy, move_assign);
54 EXPECT_EQ(2, tracker.swaps());
55 EXPECT_EQ(0, tracker.copies());
56 EXPECT_EQ(0, tracker.moves());
57 EXPECT_EQ(5, tracker.instances());
58 EXPECT_EQ(3, tracker.live_instances());
59 }
60 }
61
TEST(TestInstanceTracker,CopyableOnly)62 TEST(TestInstanceTracker, CopyableOnly) {
63 InstanceTracker tracker;
64 CopyableOnlyInstance src(1);
65 EXPECT_EQ(1, src.value()) << src;
66 CopyableOnlyInstance copy(src);
67 CopyableOnlyInstance copy2(std::move(src)); // NOLINT
68 EXPECT_EQ(2, tracker.copies());
69 EXPECT_EQ(0, tracker.moves());
70 EXPECT_EQ(3, tracker.instances());
71 EXPECT_EQ(3, tracker.live_instances());
72 tracker.ResetCopiesMovesSwaps();
73
74 CopyableOnlyInstance copy_assign(1);
75 copy_assign = copy;
76 CopyableOnlyInstance copy_assign2(1);
77 copy_assign2 = std::move(copy2); // NOLINT
78 EXPECT_EQ(2, tracker.copies());
79 EXPECT_EQ(0, tracker.moves());
80 EXPECT_EQ(5, tracker.instances());
81 EXPECT_EQ(5, tracker.live_instances());
82 tracker.ResetCopiesMovesSwaps();
83
84 {
85 using std::swap;
86 swap(src, copy);
87 swap(copy, src);
88 EXPECT_EQ(2, tracker.swaps());
89 EXPECT_EQ(0, tracker.copies());
90 EXPECT_EQ(0, tracker.moves());
91 EXPECT_EQ(5, tracker.instances());
92 EXPECT_EQ(5, tracker.live_instances());
93 }
94 }
95
TEST(TestInstanceTracker,MovableOnly)96 TEST(TestInstanceTracker, MovableOnly) {
97 InstanceTracker tracker;
98 MovableOnlyInstance src(1);
99 EXPECT_EQ(1, src.value()) << src;
100 MovableOnlyInstance move(std::move(src));
101 MovableOnlyInstance move_assign(2);
102 move_assign = std::move(move);
103 EXPECT_EQ(3, tracker.instances());
104 EXPECT_EQ(1, tracker.live_instances());
105 EXPECT_EQ(2, tracker.moves());
106 EXPECT_EQ(0, tracker.copies());
107 tracker.ResetCopiesMovesSwaps();
108
109 {
110 using std::swap;
111 MovableOnlyInstance other(2);
112 swap(move_assign, other);
113 swap(other, move_assign);
114 EXPECT_EQ(2, tracker.swaps());
115 EXPECT_EQ(0, tracker.copies());
116 EXPECT_EQ(0, tracker.moves());
117 EXPECT_EQ(4, tracker.instances());
118 EXPECT_EQ(2, tracker.live_instances());
119 }
120 }
121
TEST(TestInstanceTracker,ExistingInstances)122 TEST(TestInstanceTracker, ExistingInstances) {
123 CopyableMovableInstance uncounted_instance(1);
124 CopyableMovableInstance uncounted_live_instance(
125 std::move(uncounted_instance));
126 InstanceTracker tracker;
127 EXPECT_EQ(0, tracker.instances());
128 EXPECT_EQ(0, tracker.live_instances());
129 EXPECT_EQ(0, tracker.copies());
130 {
131 CopyableMovableInstance instance1(1);
132 EXPECT_EQ(1, tracker.instances());
133 EXPECT_EQ(1, tracker.live_instances());
134 EXPECT_EQ(0, tracker.copies());
135 EXPECT_EQ(0, tracker.moves());
136 {
137 InstanceTracker tracker2;
138 CopyableMovableInstance instance2(instance1);
139 CopyableMovableInstance instance3(std::move(instance2));
140 EXPECT_EQ(3, tracker.instances());
141 EXPECT_EQ(2, tracker.live_instances());
142 EXPECT_EQ(1, tracker.copies());
143 EXPECT_EQ(1, tracker.moves());
144 EXPECT_EQ(2, tracker2.instances());
145 EXPECT_EQ(1, tracker2.live_instances());
146 EXPECT_EQ(1, tracker2.copies());
147 EXPECT_EQ(1, tracker2.moves());
148 }
149 EXPECT_EQ(1, tracker.instances());
150 EXPECT_EQ(1, tracker.live_instances());
151 EXPECT_EQ(1, tracker.copies());
152 EXPECT_EQ(1, tracker.moves());
153 }
154 EXPECT_EQ(0, tracker.instances());
155 EXPECT_EQ(0, tracker.live_instances());
156 EXPECT_EQ(1, tracker.copies());
157 EXPECT_EQ(1, tracker.moves());
158 }
159
TEST(TestInstanceTracker,Comparisons)160 TEST(TestInstanceTracker, Comparisons) {
161 InstanceTracker tracker;
162 MovableOnlyInstance one(1), two(2);
163
164 EXPECT_EQ(0, tracker.comparisons());
165 EXPECT_FALSE(one == two);
166 EXPECT_EQ(1, tracker.comparisons());
167 EXPECT_TRUE(one != two);
168 EXPECT_EQ(2, tracker.comparisons());
169 EXPECT_TRUE(one < two);
170 EXPECT_EQ(3, tracker.comparisons());
171 EXPECT_FALSE(one > two);
172 EXPECT_EQ(4, tracker.comparisons());
173 EXPECT_TRUE(one <= two);
174 EXPECT_EQ(5, tracker.comparisons());
175 EXPECT_FALSE(one >= two);
176 EXPECT_EQ(6, tracker.comparisons());
177 EXPECT_TRUE(one.compare(two) < 0); // NOLINT
178 EXPECT_EQ(7, tracker.comparisons());
179
180 tracker.ResetCopiesMovesSwaps();
181 EXPECT_EQ(0, tracker.comparisons());
182 }
183
184 } // namespace
185