15template <
typename Lock,
typename Data>
18 using Mutex =
typename Lock::mutex_type;
20 LockedPtr(Mutex& mutex, Data& data) : lock_(mutex), data_(data) {}
21 LockedPtr(Lock&& lock, Data& data) : lock_(std::move(lock)), data_(data) {}
23 Data& operator*() & {
return data_; }
24 const Data& operator*()
const& {
return data_; }
29 Data* operator->() & {
return &data_; }
30 const Data* operator->() const& {
return &data_; }
35 Lock& GetLock() {
return lock_; }
38 const Data* GetOnRvalue() {
39 static_assert(!
sizeof(Data),
40 "Don't use temporary LockedPtr, store it to a variable");
57template <
typename Data,
typename Mutex = engine::Mutex>
60 template <
typename... Arg>
61 Variable(Arg&&... arg) : data_(std::forward<Arg>(arg)...) {}
64 return {mutex_, data_};
68 return {mutex_, data_};
71 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(
72 std::try_to_lock_t)
const {
73 return DoUniqueLock(*
this, std::try_to_lock);
76 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(
78 return DoUniqueLock(*
this, std::try_to_lock);
81 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(
82 std::chrono::milliseconds try_duration)
const {
83 return DoUniqueLock(*
this, try_duration);
86 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(
87 std::chrono::milliseconds try_duration) {
88 return DoUniqueLock(*
this, try_duration);
92 return {mutex_, data_};
98 return {mutex_, data_};
114 mutable Mutex mutex_;
121 template <
typename VariableType,
typename... StdUniqueLockArgs>
122 static auto DoUniqueLock(VariableType& concurrent_variable,
123 StdUniqueLockArgs&&... args) {
124 std::unique_lock<Mutex> lock(concurrent_variable.mutex_,
125 std::forward<StdUniqueLockArgs>(args)...);
126 return lock ? std::optional{LockedPtr{std::move(lock),
127 concurrent_variable.data_}}