| #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 |