aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-04-15 22:29:34 +0300
committerarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-04-15 22:38:53 +0300
commit522b983401ad0e6aec915a0be5d69685e9ed188a (patch)
tree2a64df44c05c943d998eb3e882ea80ddda5b6c64 /library/cpp
parent2a00aa371a6061ce6f5cb034a1f6c430a469a6f3 (diff)
downloadydb-522b983401ad0e6aec915a0be5d69685e9ed188a.tar.gz
Move FunctionView to library/cpp/yt/memory and add unit tests
0f22987a2824410add2233f4434e26c9e1903da1
Diffstat (limited to 'library/cpp')
-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
4 files changed, 195 insertions, 0 deletions
diff --git a/library/cpp/yt/misc/function_view-inl.h b/library/cpp/yt/memory/function_view-inl.h
index ececfdf335..ececfdf335 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 259238521f..259238521f 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 0000000000..99af41793c
--- /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 3658eefce1..4c3e4d5303 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