diff options
author | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-04-15 22:29:34 +0300 |
---|---|---|
committer | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-04-15 22:38:53 +0300 |
commit | 522b983401ad0e6aec915a0be5d69685e9ed188a (patch) | |
tree | 2a64df44c05c943d998eb3e882ea80ddda5b6c64 /library/cpp | |
parent | 2a00aa371a6061ce6f5cb034a1f6c430a469a6f3 (diff) | |
download | ydb-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.cpp | 194 | ||||
-rw-r--r-- | library/cpp/yt/memory/unittests/ya.make | 1 |
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 |