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