abseil-cpp/absl/base/internal/exception_safety_testing.h
Go to the documentation of this file.
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 // Utilities for testing exception-safety
16 
17 #ifndef ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_
18 #define ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_
19 
20 #include "absl/base/config.h"
21 
22 #ifdef ABSL_HAVE_EXCEPTIONS
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <functional>
27 #include <initializer_list>
28 #include <iosfwd>
29 #include <string>
30 #include <tuple>
31 #include <unordered_map>
32 
33 #include "gtest/gtest.h"
34 #include "absl/base/internal/pretty_function.h"
35 #include "absl/memory/memory.h"
36 #include "absl/meta/type_traits.h"
37 #include "absl/strings/string_view.h"
38 #include "absl/strings/substitute.h"
39 #include "absl/utility/utility.h"
40 
41 namespace testing {
42 
43 enum class TypeSpec;
44 enum class AllocSpec;
45 
46 constexpr TypeSpec operator|(TypeSpec a, TypeSpec b) {
48  return static_cast<TypeSpec>(static_cast<T>(a) | static_cast<T>(b));
49 }
50 
51 constexpr TypeSpec operator&(TypeSpec a, TypeSpec b) {
53  return static_cast<TypeSpec>(static_cast<T>(a) & static_cast<T>(b));
54 }
55 
56 constexpr AllocSpec operator|(AllocSpec a, AllocSpec b) {
58  return static_cast<AllocSpec>(static_cast<T>(a) | static_cast<T>(b));
59 }
60 
61 constexpr AllocSpec operator&(AllocSpec a, AllocSpec b) {
63  return static_cast<AllocSpec>(static_cast<T>(a) & static_cast<T>(b));
64 }
65 
66 namespace exceptions_internal {
67 
68 std::string GetSpecString(TypeSpec);
69 std::string GetSpecString(AllocSpec);
70 
71 struct NoThrowTag {};
72 struct StrongGuaranteeTagType {};
73 
74 // A simple exception class. We throw this so that test code can catch
75 // exceptions specifically thrown by ThrowingValue.
76 class TestException {
77  public:
78  explicit TestException(absl::string_view msg) : msg_(msg) {}
79  virtual ~TestException() {}
80  virtual const char* what() const noexcept { return msg_.c_str(); }
81 
82  private:
83  std::string msg_;
84 };
85 
86 // TestBadAllocException exists because allocation functions must throw an
87 // exception which can be caught by a handler of std::bad_alloc. We use a child
88 // class of std::bad_alloc so we can customise the error message, and also
89 // derive from TestException so we don't accidentally end up catching an actual
90 // bad_alloc exception in TestExceptionSafety.
91 class TestBadAllocException : public std::bad_alloc, public TestException {
92  public:
93  explicit TestBadAllocException(absl::string_view msg) : TestException(msg) {}
94  using TestException::what;
95 };
96 
97 extern int countdown;
98 
99 // Allows the countdown variable to be set manually (defaulting to the initial
100 // value of 0)
101 inline void SetCountdown(int i = 0) { countdown = i; }
102 // Sets the countdown to the terminal value -1
103 inline void UnsetCountdown() { SetCountdown(-1); }
104 
105 void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false);
106 
107 testing::AssertionResult FailureMessage(const TestException& e,
108  int countdown) noexcept;
109 
110 struct TrackedAddress {
111  bool is_alive;
113 };
114 
115 // Inspects the constructions and destructions of anything inheriting from
116 // TrackedObject. This allows us to safely "leak" TrackedObjects, as
117 // ConstructorTracker will destroy everything left over in its destructor.
118 class ConstructorTracker {
119  public:
120  explicit ConstructorTracker(int count) : countdown_(count) {
121  assert(current_tracker_instance_ == nullptr);
122  current_tracker_instance_ = this;
123  }
124 
125  ~ConstructorTracker() {
126  assert(current_tracker_instance_ == this);
127  current_tracker_instance_ = nullptr;
128 
129  for (auto& it : address_map_) {
130  void* address = it.first;
131  TrackedAddress& tracked_address = it.second;
132  if (tracked_address.is_alive) {
133  ADD_FAILURE() << ErrorMessage(address, tracked_address.description,
134  countdown_, "Object was not destroyed.");
135  }
136  }
137  }
138 
139  static void ObjectConstructed(void* address, std::string description) {
140  if (!CurrentlyTracking()) return;
141 
142  TrackedAddress& tracked_address =
143  current_tracker_instance_->address_map_[address];
144  if (tracked_address.is_alive) {
145  ADD_FAILURE() << ErrorMessage(
146  address, tracked_address.description,
147  current_tracker_instance_->countdown_,
148  "Object was re-constructed. Current object was constructed by " +
149  description);
150  }
151  tracked_address = {true, std::move(description)};
152  }
153 
154  static void ObjectDestructed(void* address) {
155  if (!CurrentlyTracking()) return;
156 
157  auto it = current_tracker_instance_->address_map_.find(address);
158  // Not tracked. Ignore.
159  if (it == current_tracker_instance_->address_map_.end()) return;
160 
161  TrackedAddress& tracked_address = it->second;
162  if (!tracked_address.is_alive) {
163  ADD_FAILURE() << ErrorMessage(address, tracked_address.description,
164  current_tracker_instance_->countdown_,
165  "Object was re-destroyed.");
166  }
167  tracked_address.is_alive = false;
168  }
169 
170  private:
171  static bool CurrentlyTracking() {
172  return current_tracker_instance_ != nullptr;
173  }
174 
175  static std::string ErrorMessage(void* address,
176  const std::string& address_description,
177  int countdown,
178  const std::string& error_description) {
179  return absl::Substitute(
180  "With coundtown at $0:\n"
181  " $1\n"
182  " Object originally constructed by $2\n"
183  " Object address: $3\n",
184  countdown, error_description, address_description, address);
185  }
186 
187  std::unordered_map<void*, TrackedAddress> address_map_;
188  int countdown_;
189 
190  static ConstructorTracker* current_tracker_instance_;
191 };
192 
193 class TrackedObject {
194  public:
195  TrackedObject(const TrackedObject&) = delete;
196  TrackedObject(TrackedObject&&) = delete;
197 
198  protected:
199  explicit TrackedObject(std::string description) {
200  ConstructorTracker::ObjectConstructed(this, std::move(description));
201  }
202 
203  ~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); }
204 };
205 } // namespace exceptions_internal
206 
207 extern exceptions_internal::NoThrowTag nothrow_ctor;
208 
209 extern exceptions_internal::StrongGuaranteeTagType strong_guarantee;
210 
211 // A test class which is convertible to bool. The conversion can be
212 // instrumented to throw at a controlled time.
213 class ThrowingBool {
214  public:
215  ThrowingBool(bool b) noexcept : b_(b) {} // NOLINT(runtime/explicit)
216  operator bool() const { // NOLINT
217  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
218  return b_;
219  }
220 
221  private:
222  bool b_;
223 };
224 
225 /*
226  * Configuration enum for the ThrowingValue type that defines behavior for the
227  * lifetime of the instance. Use testing::nothrow_ctor to prevent the integer
228  * constructor from throwing.
229  *
230  * kEverythingThrows: Every operation can throw an exception
231  * kNoThrowCopy: Copy construction and copy assignment will not throw
232  * kNoThrowMove: Move construction and move assignment will not throw
233  * kNoThrowNew: Overloaded operators new and new[] will not throw
234  */
235 enum class TypeSpec {
236  kEverythingThrows = 0,
237  kNoThrowCopy = 1,
238  kNoThrowMove = 1 << 1,
239  kNoThrowNew = 1 << 2,
240 };
241 
242 /*
243  * A testing class instrumented to throw an exception at a controlled time.
244  *
245  * ThrowingValue implements a slightly relaxed version of the Regular concept --
246  * that is it's a value type with the expected semantics. It also implements
247  * arithmetic operations. It doesn't implement member and pointer operators
248  * like operator-> or operator[].
249  *
250  * ThrowingValue can be instrumented to have certain operations be noexcept by
251  * using compile-time bitfield template arguments. That is, to make an
252  * ThrowingValue which has noexcept move construction/assignment and noexcept
253  * copy construction/assignment, use the following:
254  * ThrowingValue<testing::kNoThrowMove | testing::kNoThrowCopy> my_thrwr{val};
255  */
256 template <TypeSpec Spec = TypeSpec::kEverythingThrows>
257 class ThrowingValue : private exceptions_internal::TrackedObject {
258  static constexpr bool IsSpecified(TypeSpec spec) {
259  return static_cast<bool>(Spec & spec);
260  }
261 
262  static constexpr int kDefaultValue = 0;
263  static constexpr int kBadValue = 938550620;
264 
265  public:
266  ThrowingValue() : TrackedObject(GetInstanceString(kDefaultValue)) {
267  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
268  dummy_ = kDefaultValue;
269  }
270 
271  ThrowingValue(const ThrowingValue& other) noexcept(
272  IsSpecified(TypeSpec::kNoThrowCopy))
273  : TrackedObject(GetInstanceString(other.dummy_)) {
274  if (!IsSpecified(TypeSpec::kNoThrowCopy)) {
275  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
276  }
277  dummy_ = other.dummy_;
278  }
279 
280  ThrowingValue(ThrowingValue&& other) noexcept(
281  IsSpecified(TypeSpec::kNoThrowMove))
282  : TrackedObject(GetInstanceString(other.dummy_)) {
283  if (!IsSpecified(TypeSpec::kNoThrowMove)) {
284  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
285  }
286  dummy_ = other.dummy_;
287  }
288 
289  explicit ThrowingValue(int i) : TrackedObject(GetInstanceString(i)) {
290  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
291  dummy_ = i;
292  }
293 
294  ThrowingValue(int i, exceptions_internal::NoThrowTag) noexcept
295  : TrackedObject(GetInstanceString(i)), dummy_(i) {}
296 
297  // absl expects nothrow destructors
298  ~ThrowingValue() noexcept = default;
299 
300  ThrowingValue& operator=(const ThrowingValue& other) noexcept(
301  IsSpecified(TypeSpec::kNoThrowCopy)) {
302  dummy_ = kBadValue;
303  if (!IsSpecified(TypeSpec::kNoThrowCopy)) {
304  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
305  }
306  dummy_ = other.dummy_;
307  return *this;
308  }
309 
310  ThrowingValue& operator=(ThrowingValue&& other) noexcept(
311  IsSpecified(TypeSpec::kNoThrowMove)) {
312  dummy_ = kBadValue;
313  if (!IsSpecified(TypeSpec::kNoThrowMove)) {
314  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
315  }
316  dummy_ = other.dummy_;
317  return *this;
318  }
319 
320  // Arithmetic Operators
321  ThrowingValue operator+(const ThrowingValue& other) const {
322  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
323  return ThrowingValue(dummy_ + other.dummy_, nothrow_ctor);
324  }
325 
326  ThrowingValue operator+() const {
327  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
328  return ThrowingValue(dummy_, nothrow_ctor);
329  }
330 
331  ThrowingValue operator-(const ThrowingValue& other) const {
332  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
333  return ThrowingValue(dummy_ - other.dummy_, nothrow_ctor);
334  }
335 
336  ThrowingValue operator-() const {
337  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
338  return ThrowingValue(-dummy_, nothrow_ctor);
339  }
340 
341  ThrowingValue& operator++() {
342  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
343  ++dummy_;
344  return *this;
345  }
346 
347  ThrowingValue operator++(int) {
348  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
349  auto out = ThrowingValue(dummy_, nothrow_ctor);
350  ++dummy_;
351  return out;
352  }
353 
354  ThrowingValue& operator--() {
355  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
356  --dummy_;
357  return *this;
358  }
359 
360  ThrowingValue operator--(int) {
361  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
362  auto out = ThrowingValue(dummy_, nothrow_ctor);
363  --dummy_;
364  return out;
365  }
366 
367  ThrowingValue operator*(const ThrowingValue& other) const {
368  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
369  return ThrowingValue(dummy_ * other.dummy_, nothrow_ctor);
370  }
371 
372  ThrowingValue operator/(const ThrowingValue& other) const {
373  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
374  return ThrowingValue(dummy_ / other.dummy_, nothrow_ctor);
375  }
376 
377  ThrowingValue operator%(const ThrowingValue& other) const {
378  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
379  return ThrowingValue(dummy_ % other.dummy_, nothrow_ctor);
380  }
381 
382  ThrowingValue operator<<(int shift) const {
383  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
384  return ThrowingValue(dummy_ << shift, nothrow_ctor);
385  }
386 
387  ThrowingValue operator>>(int shift) const {
388  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
389  return ThrowingValue(dummy_ >> shift, nothrow_ctor);
390  }
391 
392  // Comparison Operators
393  // NOTE: We use `ThrowingBool` instead of `bool` because most STL
394  // types/containers requires T to be convertible to bool.
395  friend ThrowingBool operator==(const ThrowingValue& a,
396  const ThrowingValue& b) {
397  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
398  return a.dummy_ == b.dummy_;
399  }
400  friend ThrowingBool operator!=(const ThrowingValue& a,
401  const ThrowingValue& b) {
402  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
403  return a.dummy_ != b.dummy_;
404  }
405  friend ThrowingBool operator<(const ThrowingValue& a,
406  const ThrowingValue& b) {
407  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
408  return a.dummy_ < b.dummy_;
409  }
410  friend ThrowingBool operator<=(const ThrowingValue& a,
411  const ThrowingValue& b) {
412  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
413  return a.dummy_ <= b.dummy_;
414  }
415  friend ThrowingBool operator>(const ThrowingValue& a,
416  const ThrowingValue& b) {
417  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
418  return a.dummy_ > b.dummy_;
419  }
420  friend ThrowingBool operator>=(const ThrowingValue& a,
421  const ThrowingValue& b) {
422  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
423  return a.dummy_ >= b.dummy_;
424  }
425 
426  // Logical Operators
427  ThrowingBool operator!() const {
428  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
429  return !dummy_;
430  }
431 
432  ThrowingBool operator&&(const ThrowingValue& other) const {
433  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
434  return dummy_ && other.dummy_;
435  }
436 
437  ThrowingBool operator||(const ThrowingValue& other) const {
438  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
439  return dummy_ || other.dummy_;
440  }
441 
442  // Bitwise Logical Operators
443  ThrowingValue operator~() const {
444  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
445  return ThrowingValue(~dummy_, nothrow_ctor);
446  }
447 
448  ThrowingValue operator&(const ThrowingValue& other) const {
449  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
450  return ThrowingValue(dummy_ & other.dummy_, nothrow_ctor);
451  }
452 
453  ThrowingValue operator|(const ThrowingValue& other) const {
454  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
455  return ThrowingValue(dummy_ | other.dummy_, nothrow_ctor);
456  }
457 
458  ThrowingValue operator^(const ThrowingValue& other) const {
459  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
460  return ThrowingValue(dummy_ ^ other.dummy_, nothrow_ctor);
461  }
462 
463  // Compound Assignment operators
464  ThrowingValue& operator+=(const ThrowingValue& other) {
465  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
466  dummy_ += other.dummy_;
467  return *this;
468  }
469 
470  ThrowingValue& operator-=(const ThrowingValue& other) {
471  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
472  dummy_ -= other.dummy_;
473  return *this;
474  }
475 
476  ThrowingValue& operator*=(const ThrowingValue& other) {
477  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
478  dummy_ *= other.dummy_;
479  return *this;
480  }
481 
482  ThrowingValue& operator/=(const ThrowingValue& other) {
483  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
484  dummy_ /= other.dummy_;
485  return *this;
486  }
487 
488  ThrowingValue& operator%=(const ThrowingValue& other) {
489  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
490  dummy_ %= other.dummy_;
491  return *this;
492  }
493 
494  ThrowingValue& operator&=(const ThrowingValue& other) {
495  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
496  dummy_ &= other.dummy_;
497  return *this;
498  }
499 
500  ThrowingValue& operator|=(const ThrowingValue& other) {
501  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
502  dummy_ |= other.dummy_;
503  return *this;
504  }
505 
506  ThrowingValue& operator^=(const ThrowingValue& other) {
507  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
508  dummy_ ^= other.dummy_;
509  return *this;
510  }
511 
512  ThrowingValue& operator<<=(int shift) {
513  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
514  dummy_ <<= shift;
515  return *this;
516  }
517 
518  ThrowingValue& operator>>=(int shift) {
519  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
520  dummy_ >>= shift;
521  return *this;
522  }
523 
524  // Pointer operators
525  void operator&() const = delete; // NOLINT(runtime/operator)
526 
527  // Stream operators
528  friend std::ostream& operator<<(std::ostream& os, const ThrowingValue& tv) {
529  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
530  return os << GetInstanceString(tv.dummy_);
531  }
532 
533  friend std::istream& operator>>(std::istream& is, const ThrowingValue&) {
534  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
535  return is;
536  }
537 
538  // Memory management operators
539  static void* operator new(size_t s) noexcept(
540  IsSpecified(TypeSpec::kNoThrowNew)) {
541  if (!IsSpecified(TypeSpec::kNoThrowNew)) {
542  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
543  }
544  return ::operator new(s);
545  }
546 
547  static void* operator new[](size_t s) noexcept(
548  IsSpecified(TypeSpec::kNoThrowNew)) {
549  if (!IsSpecified(TypeSpec::kNoThrowNew)) {
550  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
551  }
552  return ::operator new[](s);
553  }
554 
555  template <typename... Args>
556  static void* operator new(size_t s, Args&&... args) noexcept(
557  IsSpecified(TypeSpec::kNoThrowNew)) {
558  if (!IsSpecified(TypeSpec::kNoThrowNew)) {
559  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
560  }
561  return ::operator new(s, std::forward<Args>(args)...);
562  }
563 
564  template <typename... Args>
565  static void* operator new[](size_t s, Args&&... args) noexcept(
566  IsSpecified(TypeSpec::kNoThrowNew)) {
567  if (!IsSpecified(TypeSpec::kNoThrowNew)) {
568  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
569  }
570  return ::operator new[](s, std::forward<Args>(args)...);
571  }
572 
573  // Abseil doesn't support throwing overloaded operator delete. These are
574  // provided so a throwing operator-new can clean up after itself.
575  void operator delete(void* p) noexcept { ::operator delete(p); }
576 
577  template <typename... Args>
578  void operator delete(void* p, Args&&... args) noexcept {
579  ::operator delete(p, std::forward<Args>(args)...);
580  }
581 
582  void operator delete[](void* p) noexcept { return ::operator delete[](p); }
583 
584  template <typename... Args>
585  void operator delete[](void* p, Args&&... args) noexcept {
586  return ::operator delete[](p, std::forward<Args>(args)...);
587  }
588 
589  // Non-standard access to the actual contained value. No need for this to
590  // throw.
591  int& Get() noexcept { return dummy_; }
592  const int& Get() const noexcept { return dummy_; }
593 
594  private:
595  static std::string GetInstanceString(int dummy) {
596  return absl::StrCat("ThrowingValue<",
597  exceptions_internal::GetSpecString(Spec), ">(", dummy,
598  ")");
599  }
600 
601  int dummy_;
602 };
603 // While not having to do with exceptions, explicitly delete comma operator, to
604 // make sure we don't use it on user-supplied types.
605 template <TypeSpec Spec, typename T>
606 void operator,(const ThrowingValue<Spec>&, T&&) = delete;
607 template <TypeSpec Spec, typename T>
608 void operator,(T&&, const ThrowingValue<Spec>&) = delete;
609 
610 /*
611  * Configuration enum for the ThrowingAllocator type that defines behavior for
612  * the lifetime of the instance.
613  *
614  * kEverythingThrows: Calls to the member functions may throw
615  * kNoThrowAllocate: Calls to the member functions will not throw
616  */
617 enum class AllocSpec {
618  kEverythingThrows = 0,
619  kNoThrowAllocate = 1,
620 };
621 
622 /*
623  * An allocator type which is instrumented to throw at a controlled time, or not
624  * to throw, using AllocSpec. The supported settings are the default of every
625  * function which is allowed to throw in a conforming allocator possibly
626  * throwing, or nothing throws, in line with the ABSL_ALLOCATOR_THROWS
627  * configuration macro.
628  */
629 template <typename T, AllocSpec Spec = AllocSpec::kEverythingThrows>
630 class ThrowingAllocator : private exceptions_internal::TrackedObject {
631  static constexpr bool IsSpecified(AllocSpec spec) {
632  return static_cast<bool>(Spec & spec);
633  }
634 
635  public:
636  using pointer = T*;
637  using const_pointer = const T*;
638  using reference = T&;
639  using const_reference = const T&;
640  using void_pointer = void*;
641  using const_void_pointer = const void*;
642  using value_type = T;
643  using size_type = size_t;
644  using difference_type = ptrdiff_t;
645 
646  using is_nothrow =
647  std::integral_constant<bool, Spec == AllocSpec::kNoThrowAllocate>;
648  using propagate_on_container_copy_assignment = std::true_type;
649  using propagate_on_container_move_assignment = std::true_type;
650  using propagate_on_container_swap = std::true_type;
651  using is_always_equal = std::false_type;
652 
653  ThrowingAllocator() : TrackedObject(GetInstanceString(next_id_)) {
654  exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
655  dummy_ = std::make_shared<const int>(next_id_++);
656  }
657 
658  template <typename U>
659  ThrowingAllocator(const ThrowingAllocator<U, Spec>& other) noexcept // NOLINT
660  : TrackedObject(GetInstanceString(*other.State())),
661  dummy_(other.State()) {}
662 
663  // According to C++11 standard [17.6.3.5], Table 28, the move/copy ctors of
664  // allocator shall not exit via an exception, thus they are marked noexcept.
665  ThrowingAllocator(const ThrowingAllocator& other) noexcept
666  : TrackedObject(GetInstanceString(*other.State())),
667  dummy_(other.State()) {}
668 
669  template <typename U>
670  ThrowingAllocator(ThrowingAllocator<U, Spec>&& other) noexcept // NOLINT
671  : TrackedObject(GetInstanceString(*other.State())),
672  dummy_(std::move(other.State())) {}
673 
674  ThrowingAllocator(ThrowingAllocator&& other) noexcept
675  : TrackedObject(GetInstanceString(*other.State())),
676  dummy_(std::move(other.State())) {}
677 
678  ~ThrowingAllocator() noexcept = default;
679 
680  ThrowingAllocator& operator=(const ThrowingAllocator& other) noexcept {
681  dummy_ = other.State();
682  return *this;
683  }
684 
685  template <typename U>
686  ThrowingAllocator& operator=(
687  const ThrowingAllocator<U, Spec>& other) noexcept {
688  dummy_ = other.State();
689  return *this;
690  }
691 
692  template <typename U>
693  ThrowingAllocator& operator=(ThrowingAllocator<U, Spec>&& other) noexcept {
694  dummy_ = std::move(other.State());
695  return *this;
696  }
697 
698  template <typename U>
699  struct rebind {
700  using other = ThrowingAllocator<U, Spec>;
701  };
702 
703  pointer allocate(size_type n) noexcept(
704  IsSpecified(AllocSpec::kNoThrowAllocate)) {
705  ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION);
706  return static_cast<pointer>(::operator new(n * sizeof(T)));
707  }
708 
709  pointer allocate(size_type n, const_void_pointer) noexcept(
710  IsSpecified(AllocSpec::kNoThrowAllocate)) {
711  return allocate(n);
712  }
713 
714  void deallocate(pointer ptr, size_type) noexcept {
715  ReadState();
716  ::operator delete(static_cast<void*>(ptr));
717  }
718 
719  template <typename U, typename... Args>
720  void construct(U* ptr, Args&&... args) noexcept(
721  IsSpecified(AllocSpec::kNoThrowAllocate)) {
722  ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION);
723  ::new (static_cast<void*>(ptr)) U(std::forward<Args>(args)...);
724  }
725 
726  template <typename U>
727  void destroy(U* p) noexcept {
728  ReadState();
729  p->~U();
730  }
731 
732  size_type max_size() const noexcept {
734  }
735 
736  ThrowingAllocator select_on_container_copy_construction() noexcept(
737  IsSpecified(AllocSpec::kNoThrowAllocate)) {
738  ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION);
739  return *this;
740  }
741 
742  template <typename U>
743  bool operator==(const ThrowingAllocator<U, Spec>& other) const noexcept {
744  return dummy_ == other.dummy_;
745  }
746 
747  template <typename U>
748  bool operator!=(const ThrowingAllocator<U, Spec>& other) const noexcept {
749  return dummy_ != other.dummy_;
750  }
751 
752  template <typename, AllocSpec>
753  friend class ThrowingAllocator;
754 
755  private:
756  static std::string GetInstanceString(int dummy) {
757  return absl::StrCat("ThrowingAllocator<",
758  exceptions_internal::GetSpecString(Spec), ">(", dummy,
759  ")");
760  }
761 
762  const std::shared_ptr<const int>& State() const { return dummy_; }
763  std::shared_ptr<const int>& State() { return dummy_; }
764 
765  void ReadState() {
766  // we know that this will never be true, but the compiler doesn't, so this
767  // should safely force a read of the value.
768  if (*dummy_ < 0) std::abort();
769  }
770 
771  void ReadStateAndMaybeThrow(absl::string_view msg) const {
772  if (!IsSpecified(AllocSpec::kNoThrowAllocate)) {
773  exceptions_internal::MaybeThrow(
774  absl::Substitute("Allocator id $0 threw from $1", *dummy_, msg));
775  }
776  }
777 
778  static int next_id_;
779  std::shared_ptr<const int> dummy_;
780 };
781 
782 template <typename T, AllocSpec Spec>
783 int ThrowingAllocator<T, Spec>::next_id_ = 0;
784 
785 // Tests for resource leaks by attempting to construct a T using args repeatedly
786 // until successful, using the countdown method. Side effects can then be
787 // tested for resource leaks.
788 template <typename T, typename... Args>
789 void TestThrowingCtor(Args&&... args) {
790  struct Cleanup {
791  ~Cleanup() { exceptions_internal::UnsetCountdown(); }
792  } c;
793  for (int count = 0;; ++count) {
794  exceptions_internal::ConstructorTracker ct(count);
795  exceptions_internal::SetCountdown(count);
796  try {
797  T temp(std::forward<Args>(args)...);
798  static_cast<void>(temp);
799  break;
800  } catch (const exceptions_internal::TestException&) {
801  }
802  }
803 }
804 
805 // Tests the nothrow guarantee of the provided nullary operation. If the an
806 // exception is thrown, the result will be AssertionFailure(). Otherwise, it
807 // will be AssertionSuccess().
808 template <typename Operation>
809 testing::AssertionResult TestNothrowOp(const Operation& operation) {
810  struct Cleanup {
811  Cleanup() { exceptions_internal::SetCountdown(); }
812  ~Cleanup() { exceptions_internal::UnsetCountdown(); }
813  } c;
814  try {
815  operation();
816  return testing::AssertionSuccess();
817  } catch (const exceptions_internal::TestException&) {
819  << "TestException thrown during call to operation() when nothrow "
820  "guarantee was expected.";
821  } catch (...) {
823  << "Unknown exception thrown during call to operation() when "
824  "nothrow guarantee was expected.";
825  }
826 }
827 
828 namespace exceptions_internal {
829 
830 // Dummy struct for ExceptionSafetyTestBuilder<> partial state.
831 struct UninitializedT {};
832 
833 template <typename T>
834 class DefaultFactory {
835  public:
836  explicit DefaultFactory(const T& t) : t_(t) {}
837  std::unique_ptr<T> operator()() const { return absl::make_unique<T>(t_); }
838 
839  private:
840  T t_;
841 };
842 
843 template <size_t LazyContractsCount, typename LazyFactory,
844  typename LazyOperation>
845 using EnableIfTestable = typename absl::enable_if_t<
846  LazyContractsCount != 0 &&
849 
850 template <typename Factory = UninitializedT,
851  typename Operation = UninitializedT, typename... Contracts>
852 class ExceptionSafetyTestBuilder;
853 
854 } // namespace exceptions_internal
855 
856 /*
857  * Constructs an empty ExceptionSafetyTestBuilder. All
858  * ExceptionSafetyTestBuilder objects are immutable and all With[thing] mutation
859  * methods return new instances of ExceptionSafetyTestBuilder.
860  *
861  * In order to test a T for exception safety, a factory for that T, a testable
862  * operation, and at least one contract callback returning an assertion
863  * result must be applied using the respective methods.
864  */
865 exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester();
866 
867 namespace exceptions_internal {
868 template <typename T>
869 struct IsUniquePtr : std::false_type {};
870 
871 template <typename T, typename D>
872 struct IsUniquePtr<std::unique_ptr<T, D>> : std::true_type {};
873 
874 template <typename Factory>
875 struct FactoryPtrTypeHelper {
876  using type = decltype(std::declval<const Factory&>()());
877 
878  static_assert(IsUniquePtr<type>::value, "Factories must return a unique_ptr");
879 };
880 
881 template <typename Factory>
882 using FactoryPtrType = typename FactoryPtrTypeHelper<Factory>::type;
883 
884 template <typename Factory>
885 using FactoryElementType = typename FactoryPtrType<Factory>::element_type;
886 
887 template <typename T>
888 class ExceptionSafetyTest {
889  using Factory = std::function<std::unique_ptr<T>()>;
890  using Operation = std::function<void(T*)>;
891  using Contract = std::function<AssertionResult(T*)>;
892 
893  public:
894  template <typename... Contracts>
895  explicit ExceptionSafetyTest(const Factory& f, const Operation& op,
896  const Contracts&... contracts)
897  : factory_(f), operation_(op), contracts_{WrapContract(contracts)...} {}
898 
899  AssertionResult Test() const {
900  for (int count = 0;; ++count) {
901  exceptions_internal::ConstructorTracker ct(count);
902 
903  for (const auto& contract : contracts_) {
904  auto t_ptr = factory_();
905  try {
906  SetCountdown(count);
907  operation_(t_ptr.get());
908  // Unset for the case that the operation throws no exceptions, which
909  // would leave the countdown set and break the *next* exception safety
910  // test after this one.
911  UnsetCountdown();
912  return AssertionSuccess();
913  } catch (const exceptions_internal::TestException& e) {
914  if (!contract(t_ptr.get())) {
915  return AssertionFailure() << e.what() << " failed contract check";
916  }
917  }
918  }
919  }
920  }
921 
922  private:
923  template <typename ContractFn>
924  Contract WrapContract(const ContractFn& contract) {
925  return [contract](T* t_ptr) { return AssertionResult(contract(t_ptr)); };
926  }
927 
928  Contract WrapContract(StrongGuaranteeTagType) {
929  return [this](T* t_ptr) { return AssertionResult(*factory_() == *t_ptr); };
930  }
931 
932  Factory factory_;
933  Operation operation_;
934  std::vector<Contract> contracts_;
935 };
936 
937 /*
938  * Builds a tester object that tests if performing a operation on a T follows
939  * exception safety guarantees. Verification is done via contract assertion
940  * callbacks applied to T instances post-throw.
941  *
942  * Template parameters for ExceptionSafetyTestBuilder:
943  *
944  * - Factory: The factory object (passed in via tester.WithFactory(...) or
945  * tester.WithInitialValue(...)) must be invocable with the signature
946  * `std::unique_ptr<T> operator()() const` where T is the type being tested.
947  * It is used for reliably creating identical T instances to test on.
948  *
949  * - Operation: The operation object (passsed in via tester.WithOperation(...)
950  * or tester.Test(...)) must be invocable with the signature
951  * `void operator()(T*) const` where T is the type being tested. It is used
952  * for performing steps on a T instance that may throw and that need to be
953  * checked for exception safety. Each call to the operation will receive a
954  * fresh T instance so it's free to modify and destroy the T instances as it
955  * pleases.
956  *
957  * - Contracts...: The contract assertion callback objects (passed in via
958  * tester.WithContracts(...)) must be invocable with the signature
959  * `testing::AssertionResult operator()(T*) const` where T is the type being
960  * tested. Contract assertion callbacks are provided T instances post-throw.
961  * They must return testing::AssertionSuccess when the type contracts of the
962  * provided T instance hold. If the type contracts of the T instance do not
963  * hold, they must return testing::AssertionFailure. Execution order of
964  * Contracts... is unspecified. They will each individually get a fresh T
965  * instance so they are free to modify and destroy the T instances as they
966  * please.
967  */
968 template <typename Factory, typename Operation, typename... Contracts>
969 class ExceptionSafetyTestBuilder {
970  public:
971  /*
972  * Returns a new ExceptionSafetyTestBuilder with an included T factory based
973  * on the provided T instance. The existing factory will not be included in
974  * the newly created tester instance. The created factory returns a new T
975  * instance by copy-constructing the provided const T& t.
976  *
977  * Preconditions for tester.WithInitialValue(const T& t):
978  *
979  * - The const T& t object must be copy-constructible where T is the type
980  * being tested. For non-copy-constructible objects, use the method
981  * tester.WithFactory(...).
982  */
983  template <typename T>
984  ExceptionSafetyTestBuilder<DefaultFactory<T>, Operation, Contracts...>
985  WithInitialValue(const T& t) const {
986  return WithFactory(DefaultFactory<T>(t));
987  }
988 
989  /*
990  * Returns a new ExceptionSafetyTestBuilder with the provided T factory
991  * included. The existing factory will not be included in the newly-created
992  * tester instance. This method is intended for use with types lacking a copy
993  * constructor. Types that can be copy-constructed should instead use the
994  * method tester.WithInitialValue(...).
995  */
996  template <typename NewFactory>
997  ExceptionSafetyTestBuilder<absl::decay_t<NewFactory>, Operation, Contracts...>
998  WithFactory(const NewFactory& new_factory) const {
999  return {new_factory, operation_, contracts_};
1000  }
1001 
1002  /*
1003  * Returns a new ExceptionSafetyTestBuilder with the provided testable
1004  * operation included. The existing operation will not be included in the
1005  * newly created tester.
1006  */
1007  template <typename NewOperation>
1008  ExceptionSafetyTestBuilder<Factory, absl::decay_t<NewOperation>, Contracts...>
1009  WithOperation(const NewOperation& new_operation) const {
1010  return {factory_, new_operation, contracts_};
1011  }
1012 
1013  /*
1014  * Returns a new ExceptionSafetyTestBuilder with the provided MoreContracts...
1015  * combined with the Contracts... that were already included in the instance
1016  * on which the method was called. Contracts... cannot be removed or replaced
1017  * once added to an ExceptionSafetyTestBuilder instance. A fresh object must
1018  * be created in order to get an empty Contracts... list.
1019  *
1020  * In addition to passing in custom contract assertion callbacks, this method
1021  * accepts `testing::strong_guarantee` as an argument which checks T instances
1022  * post-throw against freshly created T instances via operator== to verify
1023  * that any state changes made during the execution of the operation were
1024  * properly rolled back.
1025  */
1026  template <typename... MoreContracts>
1027  ExceptionSafetyTestBuilder<Factory, Operation, Contracts...,
1029  WithContracts(const MoreContracts&... more_contracts) const {
1030  return {
1031  factory_, operation_,
1032  std::tuple_cat(contracts_, std::tuple<absl::decay_t<MoreContracts>...>(
1033  more_contracts...))};
1034  }
1035 
1036  /*
1037  * Returns a testing::AssertionResult that is the reduced result of the
1038  * exception safety algorithm. The algorithm short circuits and returns
1039  * AssertionFailure after the first contract callback returns an
1040  * AssertionFailure. Otherwise, if all contract callbacks return an
1041  * AssertionSuccess, the reduced result is AssertionSuccess.
1042  *
1043  * The passed-in testable operation will not be saved in a new tester instance
1044  * nor will it modify/replace the existing tester instance. This is useful
1045  * when each operation being tested is unique and does not need to be reused.
1046  *
1047  * Preconditions for tester.Test(const NewOperation& new_operation):
1048  *
1049  * - May only be called after at least one contract assertion callback and a
1050  * factory or initial value have been provided.
1051  */
1052  template <
1053  typename NewOperation,
1054  typename = EnableIfTestable<sizeof...(Contracts), Factory, NewOperation>>
1055  testing::AssertionResult Test(const NewOperation& new_operation) const {
1056  return TestImpl(new_operation, absl::index_sequence_for<Contracts...>());
1057  }
1058 
1059  /*
1060  * Returns a testing::AssertionResult that is the reduced result of the
1061  * exception safety algorithm. The algorithm short circuits and returns
1062  * AssertionFailure after the first contract callback returns an
1063  * AssertionFailure. Otherwise, if all contract callbacks return an
1064  * AssertionSuccess, the reduced result is AssertionSuccess.
1065  *
1066  * Preconditions for tester.Test():
1067  *
1068  * - May only be called after at least one contract assertion callback, a
1069  * factory or initial value and a testable operation have been provided.
1070  */
1071  template <
1072  typename LazyOperation = Operation,
1073  typename = EnableIfTestable<sizeof...(Contracts), Factory, LazyOperation>>
1074  testing::AssertionResult Test() const {
1075  return Test(operation_);
1076  }
1077 
1078  private:
1079  template <typename, typename, typename...>
1080  friend class ExceptionSafetyTestBuilder;
1081 
1082  friend ExceptionSafetyTestBuilder<> testing::MakeExceptionSafetyTester();
1083 
1084  ExceptionSafetyTestBuilder() {}
1085 
1086  ExceptionSafetyTestBuilder(const Factory& f, const Operation& o,
1087  const std::tuple<Contracts...>& i)
1088  : factory_(f), operation_(o), contracts_(i) {}
1089 
1090  template <typename SelectedOperation, size_t... Indices>
1091  testing::AssertionResult TestImpl(SelectedOperation selected_operation,
1093  return ExceptionSafetyTest<FactoryElementType<Factory>>(
1094  factory_, selected_operation, std::get<Indices>(contracts_)...)
1095  .Test();
1096  }
1097 
1098  Factory factory_;
1099  Operation operation_;
1100  std::tuple<Contracts...> contracts_;
1101 };
1102 
1103 } // namespace exceptions_internal
1104 
1105 } // namespace testing
1106 
1107 #endif // ABSL_HAVE_EXCEPTIONS
1108 
1109 #endif // ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_
absl::decay_t
typename std::decay< T >::type decay_t
Definition: abseil-cpp/absl/meta/type_traits.h:628
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
testing
Definition: aws_request_signer_test.cc:25
testing::AssertionFailure
AssertionResult AssertionFailure()
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:1028
fix_build_deps.temp
temp
Definition: fix_build_deps.py:488
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
regen-readme.it
it
Definition: regen-readme.py:15
Test
void Test(StringPiece pattern, const RE2::Options &options, StringPiece text)
Definition: bloaty/third_party/re2/re2/fuzzing/re2_fuzzer.cc:20
grpc_event_engine::experimental::slice_detail::operator==
bool operator==(const BaseSlice &a, const BaseSlice &b)
Definition: include/grpc/event_engine/slice.h:117
absl::operator~
constexpr uint128 operator~(uint128 val)
Definition: abseil-cpp/absl/numeric/int128.h:848
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
bool
bool
Definition: setup_once.h:312
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::operator^=
StatusToStringMode & operator^=(StatusToStringMode &lhs, StatusToStringMode rhs)
Definition: third_party/abseil-cpp/absl/status/status.h:332
asyncio_get_stats.default
default
Definition: asyncio_get_stats.py:38
fix_build_deps.c
list c
Definition: fix_build_deps.py:490
google::protobuf::operator%=
Duration & operator%=(Duration &d1, const Duration &d2)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/util/time_util.cc:462
grpc_core::operator+
Duration operator+(Duration lhs, Duration rhs)
Definition: src/core/lib/gprpp/time.h:229
setup.description
description
Definition: setup.py:544
google::protobuf.internal::true_type
integral_constant< bool, true > true_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:89
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
google::protobuf.internal::false_type
integral_constant< bool, false > false_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:90
google::protobuf::operator+=
Duration & operator+=(Duration &d1, const Duration &d2)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/util/time_util.cc:406
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
testing::Args
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:12951
absl::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: abseil-cpp/absl/meta/type_traits.h:631
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
env.new
def new
Definition: env.py:51
TestImpl
static void TestImpl(const char *name, bssl::Span< const uint8_t > der, const char *password, const char *friendly_name)
Definition: pkcs12_test.cc:44
run_interop_tests.spec
def spec
Definition: run_interop_tests.py:1394
T
#define T(upbtypeconst, upbtype, ctype, default_value)
absl::operator%
uint128 operator%(uint128 lhs, uint128 rhs)
Definition: abseil-cpp/absl/numeric/int128.cc:149
grpc::operator>=
bool operator>=(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:143
testing::operator<<
std::ostream & operator<<(std::ostream &os, const Message &sb)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-message.h:198
absl::synchronization_internal::Get
static GraphId Get(const IdMap &id, int num)
Definition: abseil-cpp/absl/synchronization/internal/graphcycles_test.cc:44
o
UnboundConversion o
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:97
grpc::operator<
bool operator<(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:140
absl::operator^
constexpr uint128 operator^(uint128 lhs, uint128 rhs)
Definition: abseil-cpp/absl/numeric/int128.h:876
grpc_core::operator-
Duration operator-(Duration lhs, Duration rhs)
Definition: src/core/lib/gprpp/time.h:234
grpc::operator<=
bool operator<=(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:141
absl::FormatConversionChar::e
@ e
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
absl::operator!
constexpr bool operator!(uint128 val)
Definition: abseil-cpp/absl/numeric/int128.h:838
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
absl::integer_sequence
Definition: abseil-cpp/absl/utility/utility.h:76
grpc::operator>
bool operator>(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:142
testing::AssertionResult
Definition: cares/cares/test/gmock-1.8.0/gtest/gtest.h:18855
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
operator!=
bool operator!=(const Bytes &a, const Bytes &b)
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:58
testing::AssertionSuccess
AssertionResult AssertionSuccess()
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:1023
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::operator&=
StatusToStringMode & operator&=(StatusToStringMode &lhs, StatusToStringMode rhs)
Definition: third_party/abseil-cpp/absl/status/status.h:322
ADD_FAILURE
#define ADD_FAILURE()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1911
absl::operator|
constexpr uint128 operator|(uint128 lhs, uint128 rhs)
Definition: abseil-cpp/absl/numeric/int128.h:856
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
re2::operator++
static void operator++(Engine &e, int unused)
Definition: bloaty/third_party/re2/re2/testing/tester.h:39
absl::index_sequence_for
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: abseil-cpp/absl/utility/utility.h:158
value
const char * value
Definition: hpack_parser_table.cc:165
google::protobuf::operator/=
Duration & operator/=(Duration &d, int64 r)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/util/time_util.cc:444
absl::operator>>
constexpr uint128 operator>>(uint128 lhs, int amount)
Definition: abseil-cpp/absl/numeric/int128.h:917
construct
static std::function< void(void *, Slot *, Slot)> construct
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:41
grpc_core::operator*
Duration operator*(Duration lhs, double rhs)
Definition: src/core/lib/gprpp/time.h:257
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
absl::str_format_internal::LengthMod::t
@ t
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
absl::underlying_type_t
typename std::underlying_type< T >::type underlying_type_t
Definition: abseil-cpp/absl/meta/type_traits.h:640
absl::ABSL_NAMESPACE_BEGIN::dummy
int dummy
Definition: function_type_benchmark.cc:28
absl::Substitute
ABSL_MUST_USE_RESULT std::string Substitute(absl::string_view format)
Definition: abseil-cpp/absl/strings/substitute.h:506
b_
const char * b_
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc:194
google::protobuf::operator*=
Duration & operator*=(Duration &d, int64 r)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/util/time_util.cc:418
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
absl::operator|=
StatusToStringMode & operator|=(StatusToStringMode &lhs, StatusToStringMode rhs)
Definition: third_party/abseil-cpp/absl/status/status.h:327
const_reference
const typedef T & const_reference
Definition: cxa_demangle.cpp:4831
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
google::protobuf::operator-=
Duration & operator-=(Duration &d1, const Duration &d2)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/util/time_util.cc:412
absl::operator&
constexpr uint128 operator&(uint128 lhs, uint128 rhs)
Definition: abseil-cpp/absl/numeric/int128.h:866
framework.infrastructure.gcp.api.Operation
Operation
Definition: api.py:60
destroy
static std::function< void(void *, Slot *)> destroy
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:42
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
const_pointer
const typedef T * const_pointer
Definition: cxa_demangle.cpp:4833
grpc_core::operator/
Duration operator/(Duration lhs, int64_t rhs)
Definition: src/core/lib/gprpp/time.h:269


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:20