File indexing completed on 2025-01-30 09:31:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_
0016 #define ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_
0017
0018 #include <cstdlib>
0019 #include <ostream>
0020
0021 #include "absl/types/compare.h"
0022
0023 namespace absl {
0024 ABSL_NAMESPACE_BEGIN
0025 namespace test_internal {
0026
0027
0028
0029
0030
0031
0032 class BaseCountedInstance {
0033 public:
0034 explicit BaseCountedInstance(int x) : value_(x) {
0035 ++num_instances_;
0036 ++num_live_instances_;
0037 }
0038 BaseCountedInstance(const BaseCountedInstance& x)
0039 : value_(x.value_), is_live_(x.is_live_) {
0040 ++num_instances_;
0041 if (is_live_) ++num_live_instances_;
0042 ++num_copies_;
0043 }
0044 BaseCountedInstance(BaseCountedInstance&& x)
0045 : value_(x.value_), is_live_(x.is_live_) {
0046 x.is_live_ = false;
0047 ++num_instances_;
0048 ++num_moves_;
0049 }
0050 ~BaseCountedInstance() {
0051 --num_instances_;
0052 if (is_live_) --num_live_instances_;
0053 }
0054
0055 BaseCountedInstance& operator=(const BaseCountedInstance& x) {
0056 value_ = x.value_;
0057 if (is_live_) --num_live_instances_;
0058 is_live_ = x.is_live_;
0059 if (is_live_) ++num_live_instances_;
0060 ++num_copies_;
0061 return *this;
0062 }
0063 BaseCountedInstance& operator=(BaseCountedInstance&& x) {
0064 value_ = x.value_;
0065 if (is_live_) --num_live_instances_;
0066 is_live_ = x.is_live_;
0067 x.is_live_ = false;
0068 ++num_moves_;
0069 return *this;
0070 }
0071
0072 bool operator==(const BaseCountedInstance& x) const {
0073 ++num_comparisons_;
0074 return value_ == x.value_;
0075 }
0076
0077 bool operator!=(const BaseCountedInstance& x) const {
0078 ++num_comparisons_;
0079 return value_ != x.value_;
0080 }
0081
0082 bool operator<(const BaseCountedInstance& x) const {
0083 ++num_comparisons_;
0084 return value_ < x.value_;
0085 }
0086
0087 bool operator>(const BaseCountedInstance& x) const {
0088 ++num_comparisons_;
0089 return value_ > x.value_;
0090 }
0091
0092 bool operator<=(const BaseCountedInstance& x) const {
0093 ++num_comparisons_;
0094 return value_ <= x.value_;
0095 }
0096
0097 bool operator>=(const BaseCountedInstance& x) const {
0098 ++num_comparisons_;
0099 return value_ >= x.value_;
0100 }
0101
0102 absl::weak_ordering compare(const BaseCountedInstance& x) const {
0103 ++num_comparisons_;
0104 return value_ < x.value_
0105 ? absl::weak_ordering::less
0106 : value_ == x.value_ ? absl::weak_ordering::equivalent
0107 : absl::weak_ordering::greater;
0108 }
0109
0110 int value() const {
0111 if (!is_live_) std::abort();
0112 return value_;
0113 }
0114
0115 friend std::ostream& operator<<(std::ostream& o,
0116 const BaseCountedInstance& v) {
0117 return o << "[value:" << v.value() << "]";
0118 }
0119
0120
0121 static void SwapImpl(
0122 BaseCountedInstance& lhs,
0123 BaseCountedInstance& rhs) {
0124 using std::swap;
0125 swap(lhs.value_, rhs.value_);
0126 swap(lhs.is_live_, rhs.is_live_);
0127 ++BaseCountedInstance::num_swaps_;
0128 }
0129
0130 private:
0131 friend class InstanceTracker;
0132
0133 int value_;
0134
0135
0136 bool is_live_ = true;
0137
0138
0139 static int num_instances_;
0140
0141
0142 static int num_live_instances_;
0143
0144
0145 static int num_moves_;
0146
0147
0148 static int num_copies_;
0149
0150
0151 static int num_swaps_;
0152
0153
0154 static int num_comparisons_;
0155 };
0156
0157
0158
0159
0160 class InstanceTracker {
0161 public:
0162 InstanceTracker()
0163 : start_instances_(BaseCountedInstance::num_instances_),
0164 start_live_instances_(BaseCountedInstance::num_live_instances_) {
0165 ResetCopiesMovesSwaps();
0166 }
0167 ~InstanceTracker() {
0168 if (instances() != 0) std::abort();
0169 if (live_instances() != 0) std::abort();
0170 }
0171
0172
0173
0174
0175 int instances() const {
0176 return BaseCountedInstance::num_instances_ - start_instances_;
0177 }
0178
0179
0180
0181 int live_instances() const {
0182 return BaseCountedInstance::num_live_instances_ - start_live_instances_;
0183 }
0184
0185
0186
0187 int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; }
0188
0189
0190
0191 int copies() const {
0192 return BaseCountedInstance::num_copies_ - start_copies_;
0193 }
0194
0195
0196
0197 int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; }
0198
0199
0200
0201 int comparisons() const {
0202 return BaseCountedInstance::num_comparisons_ - start_comparisons_;
0203 }
0204
0205
0206
0207
0208
0209 void ResetCopiesMovesSwaps() {
0210 start_moves_ = BaseCountedInstance::num_moves_;
0211 start_copies_ = BaseCountedInstance::num_copies_;
0212 start_swaps_ = BaseCountedInstance::num_swaps_;
0213 start_comparisons_ = BaseCountedInstance::num_comparisons_;
0214 }
0215
0216 private:
0217 int start_instances_;
0218 int start_live_instances_;
0219 int start_moves_;
0220 int start_copies_;
0221 int start_swaps_;
0222 int start_comparisons_;
0223 };
0224
0225
0226 class CopyableOnlyInstance : public BaseCountedInstance {
0227 public:
0228 explicit CopyableOnlyInstance(int x) : BaseCountedInstance(x) {}
0229 CopyableOnlyInstance(const CopyableOnlyInstance& rhs) = default;
0230 CopyableOnlyInstance& operator=(const CopyableOnlyInstance& rhs) = default;
0231
0232 friend void swap(CopyableOnlyInstance& lhs, CopyableOnlyInstance& rhs) {
0233 BaseCountedInstance::SwapImpl(lhs, rhs);
0234 }
0235
0236 static bool supports_move() { return false; }
0237 };
0238
0239
0240 class CopyableMovableInstance : public BaseCountedInstance {
0241 public:
0242 explicit CopyableMovableInstance(int x) : BaseCountedInstance(x) {}
0243 CopyableMovableInstance(const CopyableMovableInstance& rhs) = default;
0244 CopyableMovableInstance(CopyableMovableInstance&& rhs) = default;
0245 CopyableMovableInstance& operator=(const CopyableMovableInstance& rhs) =
0246 default;
0247 CopyableMovableInstance& operator=(CopyableMovableInstance&& rhs) = default;
0248
0249 friend void swap(CopyableMovableInstance& lhs, CopyableMovableInstance& rhs) {
0250 BaseCountedInstance::SwapImpl(lhs, rhs);
0251 }
0252
0253 static bool supports_move() { return true; }
0254 };
0255
0256
0257 class MovableOnlyInstance : public BaseCountedInstance {
0258 public:
0259 explicit MovableOnlyInstance(int x) : BaseCountedInstance(x) {}
0260 MovableOnlyInstance(MovableOnlyInstance&& other) = default;
0261 MovableOnlyInstance& operator=(MovableOnlyInstance&& other) = default;
0262
0263 friend void swap(MovableOnlyInstance& lhs, MovableOnlyInstance& rhs) {
0264 BaseCountedInstance::SwapImpl(lhs, rhs);
0265 }
0266
0267 static bool supports_move() { return true; }
0268 };
0269
0270 }
0271 ABSL_NAMESPACE_END
0272 }
0273
0274 #endif