Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:31:40

0001 // Copyright 2017 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
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 // A type that counts number of occurrences of the type, the live occurrences of
0028 // the type, as well as the number of copies, moves, swaps, and comparisons that
0029 // have occurred on the type. This is used as a base class for the copyable,
0030 // copyable+movable, and movable types below that are used in actual tests. Use
0031 // InstanceTracker in tests to track the number of instances.
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   // Implementation of efficient swap() that counts swaps.
0121   static void SwapImpl(
0122       BaseCountedInstance& lhs,    // NOLINT(runtime/references)
0123       BaseCountedInstance& rhs) {  // NOLINT(runtime/references)
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   // Indicates if the value is live, ie it hasn't been moved away from.
0136   bool is_live_ = true;
0137 
0138   // Number of instances.
0139   static int num_instances_;
0140 
0141   // Number of live instances (those that have not been moved away from.)
0142   static int num_live_instances_;
0143 
0144   // Number of times that BaseCountedInstance objects were moved.
0145   static int num_moves_;
0146 
0147   // Number of times that BaseCountedInstance objects were copied.
0148   static int num_copies_;
0149 
0150   // Number of times that BaseCountedInstance objects were swapped.
0151   static int num_swaps_;
0152 
0153   // Number of times that BaseCountedInstance objects were compared.
0154   static int num_comparisons_;
0155 };
0156 
0157 // Helper to track the BaseCountedInstance instance counters. Expects that the
0158 // number of instances and live_instances are the same when it is constructed
0159 // and when it is destructed.
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   // Returns the number of BaseCountedInstance instances both containing valid
0173   // values and those moved away from compared to when the InstanceTracker was
0174   // constructed
0175   int instances() const {
0176     return BaseCountedInstance::num_instances_ - start_instances_;
0177   }
0178 
0179   // Returns the number of live BaseCountedInstance instances compared to when
0180   // the InstanceTracker was constructed
0181   int live_instances() const {
0182     return BaseCountedInstance::num_live_instances_ - start_live_instances_;
0183   }
0184 
0185   // Returns the number of moves on BaseCountedInstance objects since
0186   // construction or since the last call to ResetCopiesMovesSwaps().
0187   int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; }
0188 
0189   // Returns the number of copies on BaseCountedInstance objects since
0190   // construction or the last call to ResetCopiesMovesSwaps().
0191   int copies() const {
0192     return BaseCountedInstance::num_copies_ - start_copies_;
0193   }
0194 
0195   // Returns the number of swaps on BaseCountedInstance objects since
0196   // construction or the last call to ResetCopiesMovesSwaps().
0197   int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; }
0198 
0199   // Returns the number of comparisons on BaseCountedInstance objects since
0200   // construction or the last call to ResetCopiesMovesSwaps().
0201   int comparisons() const {
0202     return BaseCountedInstance::num_comparisons_ - start_comparisons_;
0203   }
0204 
0205   // Resets the base values for moves, copies, comparisons, and swaps to the
0206   // current values, so that subsequent Get*() calls for moves, copies,
0207   // comparisons, and swaps will compare to the situation at the point of this
0208   // call.
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 // Copyable, not movable.
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 // Copyable and movable.
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 // Only movable, not default-constructible.
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 }  // namespace test_internal
0271 ABSL_NAMESPACE_END
0272 }  // namespace absl
0273 
0274 #endif  // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_