From 8e634dd27dc1b93d278c436dca6783402855a9fc Mon Sep 17 00:00:00 2001 From: Morgan Caron Date: Sun, 20 Sep 2026 05:09:43 +0200 Subject: [PATCH] feat(thread): add move constructor and move assignment to UniqueLocker --- modules/Thread/UniqueLocker.mpp | 17 +++++++++++++++++ tests/Thread/UniqueLocker.mpp | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/modules/Thread/UniqueLocker.mpp b/modules/Thread/UniqueLocker.mpp index 6668b927..15de710f 100644 --- a/modules/Thread/UniqueLocker.mpp +++ b/modules/Thread/UniqueLocker.mpp @@ -99,6 +99,23 @@ export namespace CppUtils::Thread m_value{std::forward(args)...} {} + UniqueLocker(const UniqueLocker&) = delete; + auto operator=(const UniqueLocker&) -> UniqueLocker& = delete; + + inline UniqueLocker(UniqueLocker&& other) noexcept(std::is_nothrow_move_constructible_v): + m_value{std::move(other.access().value())} + {} + + inline auto operator=(UniqueLocker&& other) noexcept(std::is_nothrow_move_assignable_v) -> UniqueLocker& + { + if (this != std::addressof(other)) + { + auto guard = std::scoped_lock{m_mutex, other.m_mutex}; + m_value = std::move(other.m_value); + } + return *this; + } + [[nodiscard]] inline auto access() & -> Accessor { return Accessor{m_mutex, m_value}; diff --git a/tests/Thread/UniqueLocker.mpp b/tests/Thread/UniqueLocker.mpp index d1295f91..1944d5ee 100644 --- a/tests/Thread/UniqueLocker.mpp +++ b/tests/Thread/UniqueLocker.mpp @@ -62,5 +62,25 @@ namespace CppUtils::UnitTest::Thread::UniqueLocker suite.expectEqual(std::get<1>(accessor.values), "Bar"); } }); + + suite.addTest("Move constructor", [&] { + auto source = CppUtils::Thread::UniqueLocker>{std::make_unique(42)}; + auto destination = CppUtils::Thread::UniqueLocker>{std::move(source)}; + + suite.expect(source.access().value() == nullptr); + suite.expect(destination.access().value() != nullptr); + suite.expectEqual(*destination.access().value(), 42); + }); + + suite.addTest("Move assignment", [&] { + auto source = CppUtils::Thread::UniqueLocker>{std::make_unique(100)}; + auto destination = CppUtils::Thread::UniqueLocker>{std::make_unique(200)}; + + destination = std::move(source); + + suite.expect(source.access().value() == nullptr); + suite.expect(destination.access().value() != nullptr); + suite.expectEqual(*destination.access().value(), 100); + }); }}; }