probe.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #pragma once
  2. #include <util/system/yassert.h>
  3. namespace NTesting {
  4. ////////////////////////////////////////////////////////////////////////////////
  5. // Below there is a serie of probe classes for testing construction/destruction copying/moving of class.
  6. // for examples see tests in probe_ut.cpp
  7. struct TProbeState {
  8. int Constructors = 0;
  9. int Destructors = 0;
  10. int ShadowDestructors = 0;
  11. int CopyConstructors = 0;
  12. int CopyAssignments = 0;
  13. int MoveConstructors = 0;
  14. int MoveAssignments = 0;
  15. int Touches = 0;
  16. TProbeState() = default;
  17. void Reset() {
  18. *this = TProbeState{};
  19. }
  20. };
  21. // Used for probing the number of copies that occur if a type must be coerced.
  22. class TCoercibleToProbe {
  23. public:
  24. TProbeState* State;
  25. TProbeState* ShadowState;
  26. public:
  27. explicit TCoercibleToProbe(TProbeState* state)
  28. : State(state)
  29. , ShadowState(state)
  30. {}
  31. private:
  32. TCoercibleToProbe(const TCoercibleToProbe&);
  33. TCoercibleToProbe(TCoercibleToProbe&&);
  34. TCoercibleToProbe& operator=(const TCoercibleToProbe&);
  35. TCoercibleToProbe& operator=(TCoercibleToProbe&&);
  36. };
  37. // Used for probing the number of copies in an argument.
  38. class TProbe {
  39. public:
  40. TProbeState* State;
  41. TProbeState* ShadowState;
  42. public:
  43. static TProbe ExplicitlyCreateInvalidProbe() {
  44. return TProbe();
  45. }
  46. explicit TProbe(TProbeState* state)
  47. : State(state)
  48. , ShadowState(state)
  49. {
  50. Y_ASSERT(State);
  51. ++State->Constructors;
  52. }
  53. ~TProbe() {
  54. if (State) {
  55. ++State->Destructors;
  56. }
  57. if (ShadowState) {
  58. ++ShadowState->ShadowDestructors;
  59. }
  60. }
  61. TProbe(const TProbe& other)
  62. : State(other.State)
  63. , ShadowState(other.ShadowState)
  64. {
  65. Y_ASSERT(State);
  66. ++State->CopyConstructors;
  67. }
  68. TProbe(TProbe&& other)
  69. : State(other.State)
  70. , ShadowState(other.ShadowState)
  71. {
  72. Y_ASSERT(State);
  73. other.State = nullptr;
  74. ++State->MoveConstructors;
  75. }
  76. TProbe(const TCoercibleToProbe& other)
  77. : State(other.State)
  78. , ShadowState(other.ShadowState)
  79. {
  80. Y_ASSERT(State);
  81. ++State->CopyConstructors;
  82. }
  83. TProbe(TCoercibleToProbe&& other)
  84. : State(other.State)
  85. , ShadowState(other.ShadowState)
  86. {
  87. Y_ASSERT(State);
  88. other.State = nullptr;
  89. ++State->MoveConstructors;
  90. }
  91. TProbe& operator=(const TProbe& other) {
  92. State = other.State;
  93. ShadowState = other.ShadowState;
  94. Y_ASSERT(State);
  95. ++State->CopyAssignments;
  96. return *this;
  97. }
  98. TProbe& operator=(TProbe&& other) {
  99. State = other.State;
  100. ShadowState = other.ShadowState;
  101. Y_ASSERT(State);
  102. other.State = nullptr;
  103. ++State->MoveAssignments;
  104. return *this;
  105. }
  106. void Touch() const {
  107. Y_ASSERT(State);
  108. ++State->Touches;
  109. }
  110. bool IsValid() const {
  111. return nullptr != State;
  112. }
  113. private:
  114. TProbe()
  115. : State(nullptr)
  116. {}
  117. };
  118. } // namespace NTesting