File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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>
Original file line number Diff line number Diff 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}
Original file line number Diff line number Diff 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}
Original file line number Diff line number Diff 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}
You can’t perform that action at this time.
0 commit comments