tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_instance_tracker.h (8913B)


      1 // Copyright 2017 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_TEST_INSTANCE_TRACKER_H_
     16 #define ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_
     17 
     18 #include <cstdlib>
     19 #include <ostream>
     20 
     21 #include "absl/types/compare.h"
     22 
     23 namespace absl {
     24 ABSL_NAMESPACE_BEGIN
     25 namespace test_internal {
     26 
     27 // A type that counts number of occurrences of the type, the live occurrences of
     28 // the type, as well as the number of copies, moves, swaps, and comparisons that
     29 // have occurred on the type. This is used as a base class for the copyable,
     30 // copyable+movable, and movable types below that are used in actual tests. Use
     31 // InstanceTracker in tests to track the number of instances.
     32 class BaseCountedInstance {
     33 public:
     34  explicit BaseCountedInstance(int x) : value_(x) {
     35    ++num_instances_;
     36    ++num_live_instances_;
     37  }
     38  BaseCountedInstance(const BaseCountedInstance& x)
     39      : value_(x.value_), is_live_(x.is_live_) {
     40    ++num_instances_;
     41    if (is_live_) ++num_live_instances_;
     42    ++num_copies_;
     43  }
     44  BaseCountedInstance(BaseCountedInstance&& x)
     45      : value_(x.value_), is_live_(x.is_live_) {
     46    x.is_live_ = false;
     47    ++num_instances_;
     48    ++num_moves_;
     49  }
     50  ~BaseCountedInstance() {
     51    --num_instances_;
     52    if (is_live_) --num_live_instances_;
     53  }
     54 
     55  BaseCountedInstance& operator=(const BaseCountedInstance& x) {
     56    value_ = x.value_;
     57    if (is_live_) --num_live_instances_;
     58    is_live_ = x.is_live_;
     59    if (is_live_) ++num_live_instances_;
     60    ++num_copies_;
     61    return *this;
     62  }
     63  BaseCountedInstance& operator=(BaseCountedInstance&& x) {
     64    value_ = x.value_;
     65    if (is_live_) --num_live_instances_;
     66    is_live_ = x.is_live_;
     67    x.is_live_ = false;
     68    ++num_moves_;
     69    return *this;
     70  }
     71 
     72  bool operator==(const BaseCountedInstance& x) const {
     73    ++num_comparisons_;
     74    return value_ == x.value_;
     75  }
     76 
     77  bool operator!=(const BaseCountedInstance& x) const {
     78    ++num_comparisons_;
     79    return value_ != x.value_;
     80  }
     81 
     82  bool operator<(const BaseCountedInstance& x) const {
     83    ++num_comparisons_;
     84    return value_ < x.value_;
     85  }
     86 
     87  bool operator>(const BaseCountedInstance& x) const {
     88    ++num_comparisons_;
     89    return value_ > x.value_;
     90  }
     91 
     92  bool operator<=(const BaseCountedInstance& x) const {
     93    ++num_comparisons_;
     94    return value_ <= x.value_;
     95  }
     96 
     97  bool operator>=(const BaseCountedInstance& x) const {
     98    ++num_comparisons_;
     99    return value_ >= x.value_;
    100  }
    101 
    102  absl::weak_ordering compare(const BaseCountedInstance& x) const {
    103    ++num_comparisons_;
    104    return value_ < x.value_
    105               ? absl::weak_ordering::less
    106               : value_ == x.value_ ? absl::weak_ordering::equivalent
    107                                    : absl::weak_ordering::greater;
    108  }
    109 
    110  int value() const {
    111    if (!is_live_) std::abort();
    112    return value_;
    113  }
    114 
    115  friend std::ostream& operator<<(std::ostream& o,
    116                                  const BaseCountedInstance& v) {
    117    return o << "[value:" << v.value() << "]";
    118  }
    119 
    120  // Implementation of efficient swap() that counts swaps.
    121  static void SwapImpl(
    122      BaseCountedInstance& lhs,    // NOLINT(runtime/references)
    123      BaseCountedInstance& rhs) {  // NOLINT(runtime/references)
    124    using std::swap;
    125    swap(lhs.value_, rhs.value_);
    126    swap(lhs.is_live_, rhs.is_live_);
    127    ++BaseCountedInstance::num_swaps_;
    128  }
    129 
    130 private:
    131  friend class InstanceTracker;
    132 
    133  int value_;
    134 
    135  // Indicates if the value is live, ie it hasn't been moved away from.
    136  bool is_live_ = true;
    137 
    138  // Number of instances.
    139  static int num_instances_;
    140 
    141  // Number of live instances (those that have not been moved away from.)
    142  static int num_live_instances_;
    143 
    144  // Number of times that BaseCountedInstance objects were moved.
    145  static int num_moves_;
    146 
    147  // Number of times that BaseCountedInstance objects were copied.
    148  static int num_copies_;
    149 
    150  // Number of times that BaseCountedInstance objects were swapped.
    151  static int num_swaps_;
    152 
    153  // Number of times that BaseCountedInstance objects were compared.
    154  static int num_comparisons_;
    155 };
    156 
    157 // Helper to track the BaseCountedInstance instance counters. Expects that the
    158 // number of instances and live_instances are the same when it is constructed
    159 // and when it is destructed.
    160 class InstanceTracker {
    161 public:
    162  InstanceTracker()
    163      : start_instances_(BaseCountedInstance::num_instances_),
    164        start_live_instances_(BaseCountedInstance::num_live_instances_) {
    165    ResetCopiesMovesSwaps();
    166  }
    167  ~InstanceTracker() {
    168    if (instances() != 0) std::abort();
    169    if (live_instances() != 0) std::abort();
    170  }
    171 
    172  // Returns the number of BaseCountedInstance instances both containing valid
    173  // values and those moved away from compared to when the InstanceTracker was
    174  // constructed
    175  int instances() const {
    176    return BaseCountedInstance::num_instances_ - start_instances_;
    177  }
    178 
    179  // Returns the number of live BaseCountedInstance instances compared to when
    180  // the InstanceTracker was constructed
    181  int live_instances() const {
    182    return BaseCountedInstance::num_live_instances_ - start_live_instances_;
    183  }
    184 
    185  // Returns the number of moves on BaseCountedInstance objects since
    186  // construction or since the last call to ResetCopiesMovesSwaps().
    187  int moves() const { return BaseCountedInstance::num_moves_ - start_moves_; }
    188 
    189  // Returns the number of copies on BaseCountedInstance objects since
    190  // construction or the last call to ResetCopiesMovesSwaps().
    191  int copies() const {
    192    return BaseCountedInstance::num_copies_ - start_copies_;
    193  }
    194 
    195  // Returns the number of swaps on BaseCountedInstance objects since
    196  // construction or the last call to ResetCopiesMovesSwaps().
    197  int swaps() const { return BaseCountedInstance::num_swaps_ - start_swaps_; }
    198 
    199  // Returns the number of comparisons on BaseCountedInstance objects since
    200  // construction or the last call to ResetCopiesMovesSwaps().
    201  int comparisons() const {
    202    return BaseCountedInstance::num_comparisons_ - start_comparisons_;
    203  }
    204 
    205  // Resets the base values for moves, copies, comparisons, and swaps to the
    206  // current values, so that subsequent Get*() calls for moves, copies,
    207  // comparisons, and swaps will compare to the situation at the point of this
    208  // call.
    209  void ResetCopiesMovesSwaps() {
    210    start_moves_ = BaseCountedInstance::num_moves_;
    211    start_copies_ = BaseCountedInstance::num_copies_;
    212    start_swaps_ = BaseCountedInstance::num_swaps_;
    213    start_comparisons_ = BaseCountedInstance::num_comparisons_;
    214  }
    215 
    216 private:
    217  int start_instances_;
    218  int start_live_instances_;
    219  int start_moves_;
    220  int start_copies_;
    221  int start_swaps_;
    222  int start_comparisons_;
    223 };
    224 
    225 // Copyable, not movable.
    226 class CopyableOnlyInstance : public BaseCountedInstance {
    227 public:
    228  explicit CopyableOnlyInstance(int x) : BaseCountedInstance(x) {}
    229  CopyableOnlyInstance(const CopyableOnlyInstance& rhs) = default;
    230  CopyableOnlyInstance& operator=(const CopyableOnlyInstance& rhs) = default;
    231 
    232  friend void swap(CopyableOnlyInstance& lhs, CopyableOnlyInstance& rhs) {
    233    BaseCountedInstance::SwapImpl(lhs, rhs);
    234  }
    235 
    236  static bool supports_move() { return false; }
    237 };
    238 
    239 // Copyable and movable.
    240 class CopyableMovableInstance : public BaseCountedInstance {
    241 public:
    242  explicit CopyableMovableInstance(int x) : BaseCountedInstance(x) {}
    243  CopyableMovableInstance(const CopyableMovableInstance& rhs) = default;
    244  CopyableMovableInstance(CopyableMovableInstance&& rhs) = default;
    245  CopyableMovableInstance& operator=(const CopyableMovableInstance& rhs) =
    246      default;
    247  CopyableMovableInstance& operator=(CopyableMovableInstance&& rhs) = default;
    248 
    249  friend void swap(CopyableMovableInstance& lhs, CopyableMovableInstance& rhs) {
    250    BaseCountedInstance::SwapImpl(lhs, rhs);
    251  }
    252 
    253  static bool supports_move() { return true; }
    254 };
    255 
    256 // Only movable, not default-constructible.
    257 class MovableOnlyInstance : public BaseCountedInstance {
    258 public:
    259  explicit MovableOnlyInstance(int x) : BaseCountedInstance(x) {}
    260  MovableOnlyInstance(MovableOnlyInstance&& other) = default;
    261  MovableOnlyInstance& operator=(MovableOnlyInstance&& other) = default;
    262 
    263  friend void swap(MovableOnlyInstance& lhs, MovableOnlyInstance& rhs) {
    264    BaseCountedInstance::SwapImpl(lhs, rhs);
    265  }
    266 
    267  static bool supports_move() { return true; }
    268 };
    269 
    270 }  // namespace test_internal
    271 ABSL_NAMESPACE_END
    272 }  // namespace absl
    273 
    274 #endif  // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_