"ScL Feature"/
ScL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
wrapper_lock.h
1#pragma once
2
3#include <scl/feature/concepts/wrapper.h>
4#include <scl/feature/detail/executor_access.h>
6#include <scl/feature/type_traits/wrapper.h>
7#include <scl/utility/concepts/reference.h>
8#include <scl/utility/type_traits/forward_like.h>
9
10#include <cassert>
11#include <type_traits>
12#include <utility>
13
14namespace scl::feature::detail
15{
16 enum class wrapper_lock_case : bool
17 {
18 value = false,
19 wrapper = true,
20 };
21
22 template <::scl::concepts::reference Refer,
23 wrapper_lock_case Case = ::scl::feature::is_wrapper_v<Refer> ? wrapper_lock_case::wrapper : wrapper_lock_case::value>
24 class wrapper_lock;
25
26 template <::scl::concepts::reference Refer>
27 class wrapper_lock<Refer, wrapper_lock_case::value>
28 {
29 public:
30 wrapper_lock(wrapper_lock &&) = delete;
31 wrapper_lock(wrapper_lock const &) = delete;
32 wrapper_lock & operator=(wrapper_lock &&) = delete;
33 wrapper_lock & operator=(wrapper_lock const &) = delete;
34 ~wrapper_lock() = default;
35
36 constexpr explicit wrapper_lock(Refer ref) noexcept
37 : m_ref{::std::forward<Refer>(ref)}
38 {}
39
40 static constexpr void lock() noexcept {}
41
42 static constexpr void unlock() noexcept {}
43
44 [[nodiscard]]
45 constexpr Refer value() const noexcept
46 {
47 return ::std::forward<Refer>(m_ref);
48 }
49
50 private:
51 Refer m_ref;
52 };
53
54 template <concepts::wrapper_reference WrapperRefer>
55 class wrapper_lock<WrapperRefer, wrapper_lock_case::wrapper>
56 {
57 using wrapper_type = ::std::remove_cvref_t<WrapperRefer>;
58 using executor_type = typename wrapper_type::executor_type;
59 using executor_refer = ::scl::forward_like_t<WrapperRefer, executor_type>;
60 using value_type = typename wrapper_type::value_type;
61 using value_refer = ::scl::forward_like_t<WrapperRefer, value_type>;
62
63 public:
64 wrapper_lock(wrapper_lock &&) = delete;
65 wrapper_lock(wrapper_lock const &) = delete;
66 wrapper_lock & operator=(wrapper_lock &&) = delete;
67 wrapper_lock & operator=(wrapper_lock const &) = delete;
68
69 constexpr explicit wrapper_lock(WrapperRefer ref) noexcept
70 : m_ref{::std::forward<WrapperRefer>(ref)}
71 {}
72
73 constexpr ~wrapper_lock() noexcept(::scl::feature::is_unguard_noexcept_v<executor_type, executor_refer>)
74 {
75 unlock();
76 }
77
78 constexpr void lock() /**/
79 noexcept(::scl::feature::is_guard_noexcept_v<executor_type, executor_refer>)
80 {
81 if (!m_locked)
82 {
84 executor_type::guard(executor());
85 m_locked = true;
86 }
87 }
88
89 constexpr void unlock() /**/
90 noexcept(::scl::feature::is_unguard_noexcept_v<executor_type, executor_refer>)
91 {
92 if (m_locked)
93 {
95 executor_type::unguard(executor());
96 m_locked = false;
97 }
98 }
99
100 [[nodiscard]]
101 constexpr bool locked() const noexcept
102 {
103 return m_locked;
104 }
105
106 [[nodiscard]]
107 constexpr WrapperRefer wrapper_value() const noexcept
108 {
109 return ::std::forward<WrapperRefer>(m_ref);
110 }
111
112 [[nodiscard]]
113 constexpr value_refer value() const /**/
114 noexcept(noexcept(executor_type::template access<executor_refer>(::std::declval<executor_refer>())))
115 requires requires {
116 executor_type::template access<executor_refer>(::std::declval<executor_refer>());
117 }
118 {
120 "wrapper_lock::value() requires the lock to be held for a guarding executor");
121 return executor_type::template access<executor_refer>(executor());
122 }
123
124 private:
125 [[nodiscard]]
126 constexpr executor_refer executor() const noexcept
127 {
128 return executor_access::get(::std::forward<WrapperRefer>(m_ref));
129 }
130
131 private:
132 bool m_locked{false};
133 WrapperRefer m_ref;
134 };
135
136} // namespace scl::feature::detail
constexpr bool has_guard_v
true if ExecutorType has a guard() method whose first (and only) parameter type is exactly ExecutorRe...
Definition executor.h:93
constexpr bool has_unguard_v
true if ExecutorType has an unguard() method whose first (and only) parameter type is exactly Executo...
Definition executor.h:105
constexpr bool is_wrapper_v
Checks whether Type is a wrapper specialization.
Definition wrapper.h:32
constexpr bool is_unguard_noexcept_v
true if ExecutorType::unguard() for ExecutorRefer either does not exist or is noexcept.
Definition executor.h:194
constexpr bool is_guard_noexcept_v
true if ExecutorType::guard() for ExecutorRefer either does not exist or is noexcept.
Definition executor.h:182
Executor type traits: interface detection and noexcept helpers.