cancel: Add utility for always running callback

This makes it possible to have a guaranteed callback, where an uncalled
callback will be called with a set of default parameters upon
destruction if it was not called at least once.

Change-Id: Id5b499e645adc9e23bf03158f10710f281bd7fd3
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/cancel.cpp b/test/cancel.cpp
index 82da693..d8c75a8 100644
--- a/test/cancel.cpp
+++ b/test/cancel.cpp
@@ -1,3 +1,4 @@
+#include <functional>
 #include <stdplus/cancel.hpp>
 
 #include <gtest/gtest.h>
@@ -25,4 +26,37 @@
     EXPECT_EQ(c.count, 1);
 }
 
+TEST(CancelTest, AlwaysCallOnceLambda)
+{
+    size_t ctr = 0;
+    {
+        auto i = std::make_unique<size_t>(1);
+        auto acb = alwaysCallOnce([&, i = std::move(i)]() { ctr += *i; });
+        EXPECT_EQ(ctr, 0);
+        acb();
+        EXPECT_EQ(ctr, 1);
+    }
+    EXPECT_EQ(ctr, 1);
+    {
+        auto acb = alwaysCallOnce([&](size_t i) { ctr += i; }, 3);
+        EXPECT_EQ(ctr, 1);
+    }
+    EXPECT_EQ(ctr, 4);
+}
+
+TEST(CanceTest, AlwaysCallOnceFunction)
+{
+    size_t ctr = 0;
+    {
+        auto acb = alwaysCallOnce(std::function<void()>(nullptr));
+    }
+    {
+        auto acb = alwaysCallOnce(std::function<void()>([&]() { ctr++; }));
+        EXPECT_EQ(ctr, 0);
+        acb = alwaysCallOnce(std::function<void()>([&]() { ctr += 2; }));
+        EXPECT_EQ(ctr, 1);
+    }
+    EXPECT_EQ(ctr, 3);
+}
+
 } // namespace stdplus