1 // Copyright 2018 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 #ifndef ABSL_CONTAINER_INTERNAL_TRACKED_H_
16 #define ABSL_CONTAINER_INTERNAL_TRACKED_H_
17 
18 #include <stddef.h>
19 
20 #include <memory>
21 #include <utility>
22 
23 #include "absl/base/config.h"
24 
25 namespace absl {
26 ABSL_NAMESPACE_BEGIN
27 namespace container_internal {
28 
29 // A class that tracks its copies and moves so that it can be queried in tests.
30 template <class T>
31 class Tracked {
32  public:
Tracked()33   Tracked() {}
34   // NOLINTNEXTLINE(runtime/explicit)
Tracked(const T & val)35   Tracked(const T& val) : val_(val) {}
Tracked(const Tracked & that)36   Tracked(const Tracked& that)
37       : val_(that.val_),
38         num_moves_(that.num_moves_),
39         num_copies_(that.num_copies_) {
40     ++(*num_copies_);
41   }
Tracked(Tracked && that)42   Tracked(Tracked&& that)
43       : val_(std::move(that.val_)),
44         num_moves_(std::move(that.num_moves_)),
45         num_copies_(std::move(that.num_copies_)) {
46     ++(*num_moves_);
47   }
48   Tracked& operator=(const Tracked& that) {
49     val_ = that.val_;
50     num_moves_ = that.num_moves_;
51     num_copies_ = that.num_copies_;
52     ++(*num_copies_);
53   }
54   Tracked& operator=(Tracked&& that) {
55     val_ = std::move(that.val_);
56     num_moves_ = std::move(that.num_moves_);
57     num_copies_ = std::move(that.num_copies_);
58     ++(*num_moves_);
59   }
60 
val()61   const T& val() const { return val_; }
62 
63   friend bool operator==(const Tracked& a, const Tracked& b) {
64     return a.val_ == b.val_;
65   }
66   friend bool operator!=(const Tracked& a, const Tracked& b) {
67     return !(a == b);
68   }
69 
num_copies()70   size_t num_copies() { return *num_copies_; }
num_moves()71   size_t num_moves() { return *num_moves_; }
72 
73  private:
74   T val_;
75   std::shared_ptr<size_t> num_moves_ = std::make_shared<size_t>(0);
76   std::shared_ptr<size_t> num_copies_ = std::make_shared<size_t>(0);
77 };
78 
79 }  // namespace container_internal
80 ABSL_NAMESPACE_END
81 }  // namespace absl
82 
83 #endif  // ABSL_CONTAINER_INTERNAL_TRACKED_H_
84