Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_
00016 #define ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_
00017
00018 #include <cstdlib>
00019 #include <ostream>
00020
00021 #include "absl/types/compare.h"
00022
00023 namespace absl {
00024 namespace test_internal {
00025
00026
00027
00028
00029
00030
00031 class BaseCountedInstance {
00032 public:
00033 explicit BaseCountedInstance(int x) : value_(x) {
00034 ++num_instances_;
00035 ++num_live_instances_;
00036 }
00037 BaseCountedInstance(const BaseCountedInstance& x)
00038 : value_(x.value_), is_live_(x.is_live_) {
00039 ++num_instances_;
00040 if (is_live_) ++num_live_instances_;
00041 ++num_copies_;
00042 }
00043 BaseCountedInstance(BaseCountedInstance&& x)
00044 : value_(x.value_), is_live_(x.is_live_) {
00045 x.is_live_ = false;
00046 ++num_instances_;
00047 ++num_moves_;
00048 }
00049 ~BaseCountedInstance() {
00050 --num_instances_;
00051 if (is_live_) --num_live_instances_;
00052 }
00053
00054 BaseCountedInstance& operator=(const BaseCountedInstance& x) {
00055 value_ = x.value_;
00056 if (is_live_) --num_live_instances_;
00057 is_live_ = x.is_live_;
00058 if (is_live_) ++num_live_instances_;
00059 ++num_copies_;
00060 return *this;
00061 }
00062 BaseCountedInstance& operator=(BaseCountedInstance&& x) {
00063 value_ = x.value_;
00064 if (is_live_) --num_live_instances_;
00065 is_live_ = x.is_live_;
00066 x.is_live_ = false;
00067 ++num_moves_;
00068 return *this;
00069 }
00070
00071 bool operator==(const BaseCountedInstance& x) const {
00072 ++num_comparisons_;
00073 return value_ == x.value_;
00074 }
00075
00076 bool operator!=(const BaseCountedInstance& x) const {
00077 ++num_comparisons_;
00078 return value_ != x.value_;
00079 }
00080
00081 bool operator<(const BaseCountedInstance& x) const {
00082 ++num_comparisons_;
00083 return value_ < x.value_;
00084 }
00085
00086 bool operator>(const BaseCountedInstance& x) const {
00087 ++num_comparisons_;
00088 return value_ > x.value_;
00089 }
00090
00091 bool operator<=(const BaseCountedInstance& x) const {
00092 ++num_comparisons_;
00093 return value_ <= x.value_;
00094 }
00095
00096 bool operator>=(const BaseCountedInstance& x) const {
00097 ++num_comparisons_;
00098 return value_ >= x.value_;
00099 }
00100
00101 absl::weak_ordering compare(const BaseCountedInstance& x) const {
00102 ++num_comparisons_;
00103 return value_ < x.value_
00104 ? absl::weak_ordering::less
00105 : value_ == x.value_ ? absl::weak_ordering::equivalent
00106 : absl::weak_ordering::greater;
00107 }
00108
00109 int value() const {
00110 if (!is_live_) std::abort();
00111 return value_;
00112 }
00113
00114 friend std::ostream& operator<<(std::ostream& o,
00115 const BaseCountedInstance& v) {
00116 return o << "[value:" << v.value() << "]";
00117 }
00118
00119
00120 static void SwapImpl(
00121 BaseCountedInstance& lhs,
00122 BaseCountedInstance& rhs) {
00123 using std::swap;
00124 swap(lhs.value_, rhs.value_);
00125 swap(lhs.is_live_, rhs.is_live_);
00126 ++BaseCountedInstance::num_swaps_;
00127 }
00128
00129 private:
00130 friend class InstanceTracker;
00131
00132 int value_;
00133
00134
00135 bool is_live_ = true;
00136
00137
00138 static int num_instances_;
00139
00140
00141 static int num_live_instances_;
00142
00143
00144 static int num_moves_;
00145
00146
00147 static int num_copies_;
00148
00149
00150 static int num_swaps_;
00151
00152
00153 static int num_comparisons_;
00154 };
00155
00156
00157
00158
00159 class InstanceTracker {
00160 public:
00161 InstanceTracker()
00162 : start_instances_(BaseCountedInstance::num_instances_),
00163 start_live_instances_(BaseCountedInstance::num_live_instances_) {
00164 ResetCopiesMovesSwaps();
00165 }
00166 ~InstanceTracker() {
00167 if (instances() != 0) std::abort();
00168 if (live_instances() != 0) std::abort();
00169 }
00170
00171
00172
00173
00174 int instances() const {
00175 return BaseCountedInstance::num_instances_ - start_instances_;
00176 }
00177
00178
00179
00180 int live_instances() const {
00181 return BaseCountedInstance::num_live_instances_ - start_live_instances_;
00182 }
00183
00184
00185
00186 int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; }
00187
00188
00189
00190 int copies() const {
00191 return BaseCountedInstance::num_copies_ - start_copies_;
00192 }
00193
00194
00195
00196 int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; }
00197
00198
00199
00200 int comparisons() const {
00201 return BaseCountedInstance::num_comparisons_ - start_comparisons_;
00202 }
00203
00204
00205
00206
00207
00208 void ResetCopiesMovesSwaps() {
00209 start_moves_ = BaseCountedInstance::num_moves_;
00210 start_copies_ = BaseCountedInstance::num_copies_;
00211 start_swaps_ = BaseCountedInstance::num_swaps_;
00212 start_comparisons_ = BaseCountedInstance::num_comparisons_;
00213 }
00214
00215 private:
00216 int start_instances_;
00217 int start_live_instances_;
00218 int start_moves_;
00219 int start_copies_;
00220 int start_swaps_;
00221 int start_comparisons_;
00222 };
00223
00224
00225 class CopyableOnlyInstance : public BaseCountedInstance {
00226 public:
00227 explicit CopyableOnlyInstance(int x) : BaseCountedInstance(x) {}
00228 CopyableOnlyInstance(const CopyableOnlyInstance& rhs) = default;
00229 CopyableOnlyInstance& operator=(const CopyableOnlyInstance& rhs) = default;
00230
00231 friend void swap(CopyableOnlyInstance& lhs, CopyableOnlyInstance& rhs) {
00232 BaseCountedInstance::SwapImpl(lhs, rhs);
00233 }
00234
00235 static bool supports_move() { return false; }
00236 };
00237
00238
00239 class CopyableMovableInstance : public BaseCountedInstance {
00240 public:
00241 explicit CopyableMovableInstance(int x) : BaseCountedInstance(x) {}
00242 CopyableMovableInstance(const CopyableMovableInstance& rhs) = default;
00243 CopyableMovableInstance(CopyableMovableInstance&& rhs) = default;
00244 CopyableMovableInstance& operator=(const CopyableMovableInstance& rhs) =
00245 default;
00246 CopyableMovableInstance& operator=(CopyableMovableInstance&& rhs) = default;
00247
00248 friend void swap(CopyableMovableInstance& lhs, CopyableMovableInstance& rhs) {
00249 BaseCountedInstance::SwapImpl(lhs, rhs);
00250 }
00251
00252 static bool supports_move() { return true; }
00253 };
00254
00255
00256 class MovableOnlyInstance : public BaseCountedInstance {
00257 public:
00258 explicit MovableOnlyInstance(int x) : BaseCountedInstance(x) {}
00259 MovableOnlyInstance(MovableOnlyInstance&& other) = default;
00260 MovableOnlyInstance& operator=(MovableOnlyInstance&& other) = default;
00261
00262 friend void swap(MovableOnlyInstance& lhs, MovableOnlyInstance& rhs) {
00263 BaseCountedInstance::SwapImpl(lhs, rhs);
00264 }
00265
00266 static bool supports_move() { return true; }
00267 };
00268
00269 }
00270 }
00271
00272 #endif // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_