YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
guard.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <mutex>
7
8namespace yaclib {
9namespace detail {
10
11template <typename M, bool Shared>
12class Guard : protected detail::GuardState {
13 public:
16 }
17 explicit Guard(M& m, std::defer_lock_t) noexcept : GuardState{&m, false} {
18 }
19 explicit Guard(M& m, std::try_to_lock_t) noexcept : GuardState{&m, TryLockImpl(m)} {
20 }
21 explicit Guard(M& m, std::adopt_lock_t) noexcept : GuardState{&m, true} {
22 }
23
25 if (*this) {
26 UnlockHere();
27 }
28 }
29
30 Guard& operator=(Guard&& other) noexcept {
31 Swap(other);
32 return *this;
33 }
34
35 auto Lock() noexcept {
36 auto* m = static_cast<M*>(LockState());
37 if constexpr (Shared) {
38 return m->LockShared();
39 } else {
40 return m->Lock();
41 }
42 }
43
45 auto* m = static_cast<M*>(LockState());
46 if (TryLockImpl(*m)) {
47 return true;
48 }
50 return false;
51 }
52
54 auto* m = static_cast<M*>(UnlockState());
55 if constexpr (Shared) {
56 return m->UnlockShared();
57 } else {
58 return m->Unlock();
59 }
60 }
61
62 auto UnlockOn(IExecutor& e) noexcept {
63 auto* m = static_cast<M*>(UnlockState());
64 if constexpr (Shared) {
65 return m->UnlockOnShared(e);
66 } else {
67 return m->UnlockOn(e);
68 }
69 }
70
72 auto* m = static_cast<M*>(UnlockState());
73 if constexpr (Shared) {
74 m->UnlockHereShared();
75 } else {
76 m->UnlockHere();
77 }
78 }
79
80 void Swap(Guard& other) noexcept {
81 std::swap(_state, other._state);
82 }
83
85 return static_cast<M*>(ReleaseState());
86 }
87
89 return static_cast<M*>(Ptr());
90 }
91
93 return Owns();
94 }
95
96 [[nodiscard]] explicit operator bool() const noexcept {
97 return OwnsLock();
98 }
99
100 private:
101 static bool TryLockImpl(M& m) {
102 if constexpr (Shared) {
103 return m.TryLockShared();
104 } else {
105 return m.TryLock();
106 }
107 }
108};
109
110} // namespace detail
111
112template <typename M>
113class [[nodiscard]] UniqueGuard : public detail::Guard<M, false> {
114 public:
115 using MutexType = M;
116 using detail::Guard<M, false>::Guard;
117};
118
119template <typename M>
120class [[nodiscard]] SharedGuard : public detail::Guard<M, true> {
121 public:
122 using MutexType = M;
123 using detail::Guard<M, true>::Guard;
124};
125
126} // namespace yaclib
void * ReleaseState() noexcept
bool Owns() const noexcept
void * UnlockState() noexcept
void * LockState() noexcept
Guard() noexcept=default
Guard & operator=(Guard &&other) noexcept
Definition guard.hpp:30
bool TryLock() noexcept
Definition guard.hpp:44
Guard(M &m, std::try_to_lock_t) noexcept
Definition guard.hpp:19
~Guard() noexcept
Definition guard.hpp:24
auto UnlockOn(IExecutor &e) noexcept
Definition guard.hpp:62
bool OwnsLock() const noexcept
Definition guard.hpp:92
void UnlockHere() noexcept
Definition guard.hpp:71
Guard(M &m, std::defer_lock_t) noexcept
Definition guard.hpp:17
Guard(M &m, std::adopt_lock_t) noexcept
Definition guard.hpp:21
void Swap(Guard &other) noexcept
Definition guard.hpp:80
M * Release() noexcept
Definition guard.hpp:84
auto Lock() noexcept
Definition guard.hpp:35
M * Mutex() const noexcept
Definition guard.hpp:88
auto Unlock() noexcept
Definition guard.hpp:53
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25