| #include "quiche/common/quiche_callbacks.h" | 
 |  | 
 | #include <memory> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "quiche/common/platform/api/quiche_test.h" | 
 |  | 
 | namespace quiche { | 
 | namespace { | 
 |  | 
 | void Apply(const std::vector<int>& container, | 
 |            UnretainedCallback<void(int)> function) { | 
 |   for (int n : container) { | 
 |     function(n); | 
 |   } | 
 | } | 
 |  | 
 | TEST(QuicheCallbacksTest, UnretainedCallback) { | 
 |   std::vector<int> nums = {1, 2, 3, 4}; | 
 |   int sum = 0; | 
 |   Apply(nums, [&sum](int n) { sum += n; }); | 
 |   EXPECT_EQ(sum, 10); | 
 | } | 
 |  | 
 | TEST(QuicheCallbacksTest, SingleUseCallback) { | 
 |   int called = 0; | 
 |   SingleUseCallback<void()> callback = [&called]() { called++; }; | 
 |   EXPECT_EQ(called, 0); | 
 |  | 
 |   SingleUseCallback<void()> new_callback = std::move(callback); | 
 |   EXPECT_EQ(called, 0); | 
 |  | 
 |   std::move(new_callback)(); | 
 |   EXPECT_EQ(called, 1); | 
 |   EXPECT_QUICHE_DEBUG_DEATH( | 
 |       std::move(new_callback)(),  // NOLINT(bugprone-use-after-move) | 
 |       "AnyInvocable"); | 
 | } | 
 |  | 
 | class SetFlagOnDestruction { | 
 |  public: | 
 |   SetFlagOnDestruction(bool* flag) : flag_(flag) {} | 
 |   ~SetFlagOnDestruction() { *flag_ = true; } | 
 |  | 
 |  private: | 
 |   bool* flag_; | 
 | }; | 
 |  | 
 | TEST(QuicheCallbacksTest, SingleUseCallbackOwnership) { | 
 |   bool deleted = false; | 
 |   auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted); | 
 |   { | 
 |     SingleUseCallback<void()> callback = [setter = std::move(flag_setter)]() {}; | 
 |     EXPECT_FALSE(deleted); | 
 |   } | 
 |   EXPECT_TRUE(deleted); | 
 | } | 
 |  | 
 | TEST(QuicheCallbacksTest, MultiUseCallback) { | 
 |   int called = 0; | 
 |   MultiUseCallback<void()> callback = [&called]() { called++; }; | 
 |   EXPECT_EQ(called, 0); | 
 |  | 
 |   callback(); | 
 |   EXPECT_EQ(called, 1); | 
 |  | 
 |   callback(); | 
 |   callback(); | 
 |   EXPECT_EQ(called, 3); | 
 | } | 
 |  | 
 | TEST(QuicheCallbacksTest, MultiUseCallbackOwnership) { | 
 |   bool deleted = false; | 
 |   auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted); | 
 |   { | 
 |     MultiUseCallback<void()> callback = [setter = std::move(flag_setter)]() {}; | 
 |     EXPECT_FALSE(deleted); | 
 |   } | 
 |   EXPECT_TRUE(deleted); | 
 | } | 
 |  | 
 | }  // namespace | 
 | }  // namespace quiche |