Skip to content

Commit 6ade2d6

Browse files
committed
Thread: MultipleAccessor
1 parent adb53a8 commit 6ade2d6

4 files changed

Lines changed: 51 additions & 0 deletions

File tree

modules/Thread/SharedLocker.mpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ export namespace CppUtils::Thread
5858
private:
5959
mutable std::shared_mutex m_mutex;
6060
T m_value;
61+
62+
template<class... Lockers>
63+
friend struct MultipleAccessor;
6164
};
6265

6366
template<class T>

modules/Thread/UniqueLocker.mpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,26 @@ export namespace CppUtils::Thread
9191
private:
9292
mutable std::mutex m_mutex;
9393
T m_value;
94+
95+
template<class... Lockers>
96+
friend struct MultipleAccessor;
9497
};
9598

9699
template<class T>
97100
UniqueLocker(T) -> UniqueLocker<T>;
101+
102+
template<class... Lockers>
103+
struct MultipleAccessor final
104+
{
105+
MultipleAccessor(Lockers&... lockers):
106+
m_lockGuard{lockers.m_mutex...},
107+
values{std::tie(lockers.m_value...)}
108+
{}
109+
110+
private:
111+
std::scoped_lock<decltype(std::declval<Lockers>().m_mutex)...> m_lockGuard;
112+
113+
public:
114+
std::tuple<decltype(std::declval<Lockers>().m_value)&...> values;
115+
};
98116
}

tests/Thread/SharedLocker.mpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,25 @@ export namespace CppUtils::UnitTest::Thread::SharedLocker
4343
suite.expect(accessor1.value() == "Foo");
4444
}
4545
});
46+
47+
suite.addTest("MultipleAccessor", [&] {
48+
auto lockedString1 = CppUtils::Thread::SharedLocker<std::string>{"Foo"};
49+
auto lockedString2 = CppUtils::Thread::SharedLocker<std::string>{"Bar"};
50+
{
51+
auto accessor = CppUtils::Thread::MultipleAccessor{lockedString1, lockedString2};
52+
suite.expect(std::get<0>(accessor.values) == "Foo");
53+
suite.expect(std::get<1>(accessor.values) == "Bar");
54+
}
55+
});
56+
57+
suite.addTest("Mixed access", [&] {
58+
auto lockedString1 = CppUtils::Thread::UniqueLocker<std::string>{"Foo"};
59+
auto lockedString2 = CppUtils::Thread::SharedLocker<std::string>{"Bar"};
60+
{
61+
auto accessor = CppUtils::Thread::MultipleAccessor{lockedString1, lockedString2};
62+
suite.expect(std::get<0>(accessor.values) == "Foo");
63+
suite.expect(std::get<1>(accessor.values) == "Bar");
64+
}
65+
});
4666
}};
4767
}

tests/Thread/UniqueLocker.mpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,15 @@ export namespace CppUtils::UnitTest::Thread::UniqueLocker
4949
auto accessor = constLockedString.access();
5050
suite.expect(accessor.value() == "Test");
5151
});
52+
53+
suite.addTest("MultipleAccessor", [&] {
54+
auto lockedString1 = CppUtils::Thread::UniqueLocker<std::string>{"Foo"};
55+
auto lockedString2 = CppUtils::Thread::UniqueLocker<std::string>{"Bar"};
56+
{
57+
auto accessor = CppUtils::Thread::MultipleAccessor{lockedString1, lockedString2};
58+
suite.expect(std::get<0>(accessor.values) == "Foo");
59+
suite.expect(std::get<1>(accessor.values) == "Bar");
60+
}
61+
});
5262
}};
5363
}

0 commit comments

Comments
 (0)