function_view: Add a lightweight span equivalent for functions
Change-Id: I887f844276d618297f9861e64d269dfa4e8062fd
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/function_view.cpp b/test/function_view.cpp
new file mode 100644
index 0000000..ff95f46
--- /dev/null
+++ b/test/function_view.cpp
@@ -0,0 +1,123 @@
+#include <function2/function2.hpp>
+#include <stdplus/function_view.hpp>
+
+#include <functional>
+
+#include <gtest/gtest.h>
+
+namespace stdplus
+{
+
+int add(int a, int b)
+{
+ return a + b;
+}
+
+int mul(int a, int b) noexcept
+{
+ return a * b;
+}
+
+struct Funcy
+{
+ int a = 0;
+
+ int operator()(float y) noexcept
+ {
+ return a += (int)y;
+ }
+
+ int operator()(int b) noexcept
+ {
+ return a += b;
+ }
+};
+
+struct FuncyPriv : private Funcy
+{
+ using Funcy::operator();
+};
+
+int callFv(stdplus::function_view<int(int, int)> fv)
+{
+ return fv(3, 5);
+}
+
+TEST(FunctionView, Ptr)
+{
+ function_view<int(int, int)> fv = add;
+ EXPECT_EQ(3, fv(1, 2));
+ EXPECT_EQ(14, fv(5, 9));
+ fv = mul;
+ EXPECT_EQ(14, fv(7, 2));
+ EXPECT_EQ(0, fv(0, 10));
+ function_view fv2 = add;
+ EXPECT_EQ(1, fv2(1, 0));
+
+ EXPECT_EQ(8, callFv(add));
+}
+
+TEST(FunctionView, Obj)
+{
+ Funcy f;
+ function_view<int(int)> fv = f;
+ EXPECT_EQ(2, fv(2));
+ EXPECT_EQ(5, fv(3));
+
+ FuncyPriv fp;
+ fv = fp;
+ EXPECT_EQ(2, fv(2));
+ EXPECT_EQ(5, fv(3));
+}
+
+TEST(FunctionView, Lambda)
+{
+ auto addl = [](int a, int b) { return a + b; };
+ function_view<int(int, int)> fv = addl;
+ EXPECT_EQ(3, fv(1, 2));
+ EXPECT_EQ(14, fv(5, 9));
+ function_view fv2 = addl;
+ EXPECT_EQ(1, fv2(1, 0));
+ fv = fv2;
+ EXPECT_EQ(1, fv(1, 0));
+ function_view<int(int, int) const> fv3 = addl;
+ EXPECT_EQ(1, fv3(1, 0));
+
+ auto mull = [old = 1](int a) mutable { return old *= a; };
+ function_view fvm = mull;
+ EXPECT_EQ(2, fvm(2));
+ EXPECT_EQ(4, fvm(2));
+
+ auto mula = [](auto a, auto b) { return a + b; };
+ fv = mula;
+ EXPECT_EQ(5, fv(3, 2));
+
+ EXPECT_EQ(8, callFv([](auto a, auto b) { return a + b; }));
+}
+
+TEST(FunctionView, StdFunction)
+{
+ std::function<int(int, int)> addf = add;
+ function_view<int(int, int)> fv = addf;
+ EXPECT_EQ(3, fv(1, 2));
+ EXPECT_EQ(14, fv(5, 9));
+ {
+ function_view fv2 = addf;
+ EXPECT_EQ(1, fv2(1, 0));
+ fv = fv2;
+ }
+ EXPECT_EQ(6, fv(3, 3));
+
+ fu2::unique_function<int(int, int) const noexcept> mulf = mul;
+ function_view<int(int, int) const> fv2 = mulf;
+ EXPECT_EQ(2, fv2(1, 2));
+
+ fu2::unique_function<int(int)> mulfa = [old = 1](auto a) mutable {
+ return old *= a;
+ };
+ function_view<int(int)> fva = mulfa;
+ EXPECT_EQ(3, fva(3));
+ EXPECT_EQ(9, fva(3));
+}
+
+} // namespace stdplus
diff --git a/test/meson.build b/test/meson.build
index fd62657..40ac624 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,6 +1,7 @@
gtests = {
'cancel': [stdplus_dep, gtest_main_dep],
'exception': [stdplus_dep, gtest_main_dep],
+ 'function_view': [stdplus_dep, gtest_main_dep],
'handle/copyable': [stdplus_dep, gtest_main_dep],
'handle/managed': [stdplus_dep, gtest_main_dep],
'hash': [stdplus_dep, gtest_main_dep],