summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarkady-e1ppa <[email protected]>2024-04-15 22:29:34 +0300
committerarkady-e1ppa <[email protected]>2024-04-15 22:38:53 +0300
commit522b983401ad0e6aec915a0be5d69685e9ed188a (patch)
tree2a64df44c05c943d998eb3e882ea80ddda5b6c64
parent2a00aa371a6061ce6f5cb034a1f6c430a469a6f3 (diff)
Move FunctionView to library/cpp/yt/memory and add unit tests
0f22987a2824410add2233f4434e26c9e1903da1
-rw-r--r--library/cpp/yt/memory/function_view-inl.h (renamed from library/cpp/yt/misc/function_view-inl.h)0
-rw-r--r--library/cpp/yt/memory/function_view.h (renamed from library/cpp/yt/misc/function_view.h)0
-rw-r--r--library/cpp/yt/memory/unittests/function_view_ut.cpp194
-rw-r--r--library/cpp/yt/memory/unittests/ya.make1
-rw-r--r--yt/yt/core/concurrency/fiber.h2
-rw-r--r--yt/yt/core/concurrency/fiber_scheduler_thread.cpp2
6 files changed, 197 insertions, 2 deletions
diff --git a/library/cpp/yt/misc/function_view-inl.h b/library/cpp/yt/memory/function_view-inl.h
index ececfdf3357..ececfdf3357 100644
--- a/library/cpp/yt/misc/function_view-inl.h
+++ b/library/cpp/yt/memory/function_view-inl.h
diff --git a/library/cpp/yt/misc/function_view.h b/library/cpp/yt/memory/function_view.h
index 259238521ff..259238521ff 100644
--- a/library/cpp/yt/misc/function_view.h
+++ b/library/cpp/yt/memory/function_view.h
diff --git a/library/cpp/yt/memory/unittests/function_view_ut.cpp b/library/cpp/yt/memory/unittests/function_view_ut.cpp
new file mode 100644
index 00000000000..99af41793cc
--- /dev/null
+++ b/library/cpp/yt/memory/unittests/function_view_ut.cpp
@@ -0,0 +1,194 @@
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/memory/function_view.h>
+
+#include <util/generic/string.h>
+#include <util/string/cast.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TNoCopy
+{
+ int Value = 42;
+
+ TNoCopy() = default;
+
+ TNoCopy(const TNoCopy&) = delete;
+
+ TNoCopy(TNoCopy&&)
+ { }
+};
+
+int Foo()
+{
+ return 42;
+}
+
+int& Bar()
+{
+ static int bar = 0;
+ return bar;
+}
+
+const TNoCopy& ImmutBar()
+{
+ static TNoCopy bar = {};
+ return bar;
+}
+
+TString Baz(const int& x)
+{
+ return ToString(x);
+}
+
+void NoExFoo() noexcept
+{ }
+
+struct TCallable
+{
+ int InvocationCount = 0;
+ mutable int ConstInvocationCount = 0;
+
+ void operator()() &
+ {
+ ++InvocationCount;
+ }
+
+ void operator()() const &
+ {
+ ++ConstInvocationCount;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TFunctionViewTest, JustWorks)
+{
+ auto stackLambda = [] (int val) {
+ return val + 1;
+ };
+
+ {
+ TFunctionView<int(int)> view(stackLambda);
+
+ EXPECT_EQ(view(42), 43);
+ }
+}
+
+TEST(TFunctionViewTest, FreeFunction)
+{
+ TFunctionView<int()> view(Foo);
+ EXPECT_EQ(view(), 42);
+}
+
+TEST(TFunctionViewTest, RefReturn)
+{
+ TFunctionView<int&()> view(Bar);
+ ++view();
+ EXPECT_EQ(view(), 1);
+
+ TFunctionView<const TNoCopy&()> immut_view(ImmutBar);
+ EXPECT_EQ(immut_view().Value, 42);
+}
+
+TEST(TFunctionViewTest, RefArgument)
+{
+ TFunctionView<TString(const int&)> view(Baz);
+ EXPECT_EQ(view(77), TString("77"));
+}
+
+TEST(TFunctionViewTest, NoExcept)
+{
+ TFunctionView<void() noexcept> view(NoExFoo);
+ static_assert(std::is_nothrow_invocable_r_v<void, decltype(view)>);
+
+ view();
+}
+
+TEST(TFunctionViewTest, CVOverloads)
+{
+ TCallable callable;
+
+ TFunctionView<void()> view(callable);
+ // NB: & overload overshadows every other overload.
+ // const auto& viewRef = view;
+ // viewRef();
+
+ view();
+ EXPECT_EQ(callable.InvocationCount, 1);
+ EXPECT_EQ(callable.ConstInvocationCount, 0);
+}
+
+TEST(TFunctionViewTest, CopyView)
+{
+ int counter = 0;
+ auto lambda = [&counter] {
+ ++counter;
+ };
+
+ TFunctionView<void()> view1(lambda);
+ TFunctionView<void()> view2 = view1;
+
+ view1();
+ EXPECT_EQ(counter, 1);
+ view2();
+ EXPECT_EQ(counter, 2);
+ view1();
+ EXPECT_EQ(counter, 3);
+}
+
+TEST(TFunctionViewTest, AssignView)
+{
+ int counter = 0;
+ auto lambda = [&counter] {
+ ++counter;
+ };
+
+ TFunctionView<void()> view(lambda);
+ view();
+ EXPECT_EQ(counter, 1);
+
+ {
+ auto innerCounter = 0;
+ auto lambda = [&innerCounter] {
+ ++innerCounter;
+ };
+
+ view = lambda;
+ view();
+ EXPECT_EQ(counter, 1);
+ EXPECT_EQ(innerCounter, 1);
+ }
+
+ // NB: Even though object is dead view will remain "valid".
+ // Be careful with lifetimes!
+ EXPECT_TRUE(view.IsValid());
+}
+
+TEST(TFunctionViewTest, ReleaseSemantics)
+{
+ int counter = 0;
+ auto lambda = [&counter] {
+ ++counter;
+ };
+
+ TFunctionView<void()> view1(lambda);
+ view1();
+ EXPECT_EQ(counter, 1);
+
+ TFunctionView view2 = view1.Release();
+ EXPECT_FALSE(view1.IsValid());
+
+ EXPECT_TRUE(view2.IsValid());
+
+ view2();
+ EXPECT_EQ(counter, 2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/memory/unittests/ya.make b/library/cpp/yt/memory/unittests/ya.make
index 3658eefce1f..4c3e4d53030 100644
--- a/library/cpp/yt/memory/unittests/ya.make
+++ b/library/cpp/yt/memory/unittests/ya.make
@@ -12,6 +12,7 @@ SRCS(
chunked_memory_pool_allocator_ut.cpp
chunked_memory_pool_output_ut.cpp
free_list_ut.cpp
+ function_view_ut.cpp
intrusive_ptr_ut.cpp
shared_range_ut.cpp
weak_ptr_ut.cpp
diff --git a/yt/yt/core/concurrency/fiber.h b/yt/yt/core/concurrency/fiber.h
index e42510b26a9..e08d72601ca 100644
--- a/yt/yt/core/concurrency/fiber.h
+++ b/yt/yt/core/concurrency/fiber.h
@@ -6,7 +6,7 @@
#include <yt/yt/core/misc/intrusive_mpsc_stack.h>
-#include <library/cpp/yt/misc/function_view.h>
+#include <library/cpp/yt/memory/function_view.h>
#include <util/system/context.h>
diff --git a/yt/yt/core/concurrency/fiber_scheduler_thread.cpp b/yt/yt/core/concurrency/fiber_scheduler_thread.cpp
index 62f8afd79ae..25e380d4a9c 100644
--- a/yt/yt/core/concurrency/fiber_scheduler_thread.cpp
+++ b/yt/yt/core/concurrency/fiber_scheduler_thread.cpp
@@ -17,7 +17,7 @@
#include <library/cpp/yt/memory/memory_tag.h>
-#include <library/cpp/yt/misc/function_view.h>
+#include <library/cpp/yt/memory/function_view.h>
#include <library/cpp/yt/threading/fork_aware_spin_lock.h>