Skip to content

Commit a3a20d7

Browse files
committed
Thread/SafeShared
1 parent 945d9cc commit a3a20d7

7 files changed

Lines changed: 78 additions & 10 deletions

File tree

modules/Random/Random.mpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import std;
44

55
export namespace CppUtils::Random
66
{
7-
template<std::integral Int = std::size_t>
8-
inline auto getRandomNumberInInterval(Int min, Int max) -> Int
7+
template<std::integral Integer>
8+
inline auto getRandomNumberInInterval(Integer min, Integer max) -> Integer
99
{
1010
static auto randomDevice = std::random_device{};
1111
static auto engine = std::mt19937{randomDevice()};
12-
static auto distribution = std::uniform_int_distribution<Int>{min, max};
12+
static auto distribution = std::uniform_int_distribution<Integer>{min, max};
1313
auto randomNumber = distribution(engine);
1414
return randomNumber;
1515
}

modules/Thread/SafeShared.mpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export module CppUtils.Thread.SafeShared;
2+
3+
import std;
4+
import CppUtils.Thread.SharedLocker;
5+
6+
export namespace CppUtils::Thread
7+
{
8+
template<class T>
9+
class SafeShared final
10+
{
11+
public:
12+
inline explicit SafeShared(auto&&... args):
13+
m_locker{std::make_shared<SharedLocker<T>>(std::forward<decltype(args)>(args)...)}
14+
{}
15+
16+
[[nodiscard]] inline auto uniqueAccess() -> auto
17+
{
18+
return m_locker->uniqueAccess();
19+
}
20+
21+
[[nodiscard]] inline auto sharedAccess() const -> auto
22+
{
23+
return m_locker->sharedAccess();
24+
}
25+
26+
private:
27+
std::shared_ptr<SharedLocker<T>> m_locker;
28+
};
29+
}

modules/Thread/SharedLocker.mpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ export namespace CppUtils::Thread
1414
m_value{std::cref(value)}
1515
{}
1616

17-
[[nodiscard]] inline auto value() const noexcept -> decltype(auto)
17+
[[nodiscard]] inline auto value() const& noexcept -> decltype(auto)
1818
{
1919
return m_value.get();
2020
}
2121

22-
[[nodiscard]] inline auto operator->() const noexcept -> decltype(auto)
22+
[[nodiscard]] inline auto operator->() const& noexcept -> decltype(auto)
2323
{
2424
return &value();
2525
}
2626

27-
[[nodiscard]] inline auto getLockGuard() const noexcept -> auto&
27+
[[nodiscard]] inline auto getLockGuard() const& noexcept -> auto&
2828
{
2929
return m_lockGuard;
3030
}

modules/Thread/Thread.mpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export module CppUtils.Thread;
22

33
export import CppUtils.Thread.AsyncIStreamListener;
44
export import CppUtils.Thread.Event;
5+
export import CppUtils.Thread.SafeShared;
56
export import CppUtils.Thread.SharedLocker;
67
export import CppUtils.Thread.SharedPtr;
78
export import CppUtils.Thread.ThreadLoop;

modules/Thread/UniqueLocker.mpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ export namespace CppUtils::Thread
1313
m_value{std::ref(value)}
1414
{}
1515

16-
[[nodiscard]] inline auto value() noexcept -> decltype(auto)
16+
[[nodiscard]] inline auto value() & noexcept -> decltype(auto)
1717
{
1818
return m_value.get();
1919
}
2020

21-
[[nodiscard]] inline auto operator->() noexcept -> decltype(auto)
21+
[[nodiscard]] inline auto operator->() & noexcept -> decltype(auto)
2222
{
2323
return &value();
2424
}
2525

26-
[[nodiscard]] inline auto getLockGuard() noexcept -> auto&
26+
[[nodiscard]] inline auto getLockGuard() & noexcept -> auto&
2727
{
2828
return m_lockGuard;
2929
}

tests/Thread/SafeShared.mpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export module CppUtils.UnitTests.Thread.SafeShared;
2+
3+
import CppUtils;
4+
5+
export namespace CppUtils::UnitTest::Thread::SafeShared
6+
{
7+
inline auto _ = CppUtils::UnitTest::TestSuite{"Thread/SafeShared", {"UnitTest", "Thread/SharedLocker"}, [](auto& suite) {
8+
suite.addTest("Unique access", [&] {
9+
auto safeSharedString0 = CppUtils::Thread::SafeShared<std::string>{"Foo"};
10+
auto safeSharedString1 = safeSharedString0;
11+
{
12+
auto accessor = safeSharedString0.uniqueAccess();
13+
suite.expect(accessor.value() == "Foo");
14+
accessor.value() = "Bar";
15+
suite.expect(accessor.value() == "Bar");
16+
}
17+
{
18+
auto accessor = safeSharedString1.uniqueAccess();
19+
suite.expect(accessor.value() == "Bar");
20+
}
21+
});
22+
23+
suite.addTest("Shared access", [&] {
24+
auto safeSharedString0 = CppUtils::Thread::SafeShared<std::string>{"Foo"};
25+
auto safeSharedString1 = safeSharedString0;
26+
{
27+
auto accessor0 = safeSharedString0.sharedAccess();
28+
auto accessor1 = safeSharedString0.sharedAccess();
29+
auto accessor2 = safeSharedString1.sharedAccess();
30+
auto accessor3 = safeSharedString1.sharedAccess();
31+
suite.expect(accessor0.value() == "Foo");
32+
suite.expect(accessor1.value() == "Foo");
33+
suite.expect(accessor2.value() == "Foo");
34+
suite.expect(accessor3.value() == "Foo");
35+
}
36+
});
37+
}};
38+
}

tests/Thread/SharedLocker.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import CppUtils;
44

55
export namespace CppUtils::UnitTest::Thread::SharedLocker
66
{
7-
inline auto _ = CppUtils::UnitTest::TestSuite{"Thread/SharedLocker", {"UnitTest"}, [](auto& suite) {
7+
inline auto _ = CppUtils::UnitTest::TestSuite{"Thread/SharedLocker", {"UnitTest", "Thread/UniqueLocker"}, [](auto& suite) {
88
suite.addTest("Unique access", [&] {
99
auto lockedString = CppUtils::Thread::SharedLocker<std::string>{"Foo"};
1010
{

0 commit comments

Comments
 (0)