test_instance_tracker.h
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
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 // A type that counts number of occurences of the type, the live occurrences of
00027 // the type, as well as the number of copies, moves, swaps, and comparisons that
00028 // have occurred on the type. This is used as a base class for the copyable,
00029 // copyable+movable, and movable types below that are used in actual tests. Use
00030 // InstanceTracker in tests to track the number of instances.
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   // Implementation of efficient swap() that counts swaps.
00120   static void SwapImpl(
00121       BaseCountedInstance& lhs,    // NOLINT(runtime/references)
00122       BaseCountedInstance& rhs) {  // NOLINT(runtime/references)
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   // Indicates if the value is live, ie it hasn't been moved away from.
00135   bool is_live_ = true;
00136 
00137   // Number of instances.
00138   static int num_instances_;
00139 
00140   // Number of live instances (those that have not been moved away from.)
00141   static int num_live_instances_;
00142 
00143   // Number of times that BaseCountedInstance objects were moved.
00144   static int num_moves_;
00145 
00146   // Number of times that BaseCountedInstance objects were copied.
00147   static int num_copies_;
00148 
00149   // Number of times that BaseCountedInstance objects were swapped.
00150   static int num_swaps_;
00151 
00152   // Number of times that BaseCountedInstance objects were compared.
00153   static int num_comparisons_;
00154 };
00155 
00156 // Helper to track the BaseCountedInstance instance counters. Expects that the
00157 // number of instances and live_instances are the same when it is constructed
00158 // and when it is destructed.
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   // Returns the number of BaseCountedInstance instances both containing valid
00172   // values and those moved away from compared to when the InstanceTracker was
00173   // constructed
00174   int instances() const {
00175     return BaseCountedInstance::num_instances_ - start_instances_;
00176   }
00177 
00178   // Returns the number of live BaseCountedInstance instances compared to when
00179   // the InstanceTracker was constructed
00180   int live_instances() const {
00181     return BaseCountedInstance::num_live_instances_ - start_live_instances_;
00182   }
00183 
00184   // Returns the number of moves on BaseCountedInstance objects since
00185   // construction or since the last call to ResetCopiesMovesSwaps().
00186   int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; }
00187 
00188   // Returns the number of copies on BaseCountedInstance objects since
00189   // construction or the last call to ResetCopiesMovesSwaps().
00190   int copies() const {
00191     return BaseCountedInstance::num_copies_ - start_copies_;
00192   }
00193 
00194   // Returns the number of swaps on BaseCountedInstance objects since
00195   // construction or the last call to ResetCopiesMovesSwaps().
00196   int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; }
00197 
00198   // Returns the number of comparisons on BaseCountedInstance objects since
00199   // construction or the last call to ResetCopiesMovesSwaps().
00200   int comparisons() const {
00201     return BaseCountedInstance::num_comparisons_ - start_comparisons_;
00202   }
00203 
00204   // Resets the base values for moves, copies, comparisons, and swaps to the
00205   // current values, so that subsequent Get*() calls for moves, copies,
00206   // comparisons, and swaps will compare to the situation at the point of this
00207   // call.
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 // Copyable, not movable.
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 // Copyable and movable.
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 // Only movable, not default-constructible.
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 }  // namespace test_internal
00270 }  // namespace absl
00271 
00272 #endif  // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15