"ScL Feature"/
ScL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
wrapper_guard.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 <type_traits>
11#include <utility>
12
13namespace scl::feature::detail
14{
15 enum class wrapper_guard_case : bool
16 {
17 value = false,
18 wrapper = true,
19 };
20
21 template <::scl::concepts::reference Refer,
22 wrapper_guard_case Case = ::scl::feature::is_wrapper_v<Refer> ? wrapper_guard_case::wrapper : wrapper_guard_case::value>
23 class wrapper_guard;
24
25 template <::scl::concepts::reference Refer>
26 class wrapper_guard<Refer, wrapper_guard_case::value>
27 {
28 public:
29 wrapper_guard(wrapper_guard &&) = delete;
30 wrapper_guard(wrapper_guard const &) = delete;
31 wrapper_guard & operator=(wrapper_guard &&) = delete;
32 wrapper_guard & operator=(wrapper_guard const &) = delete;
33 ~wrapper_guard() = default;
34
35 constexpr explicit wrapper_guard(Refer v) noexcept
36 : m_value{::std::forward<Refer>(v)}
37 {}
38
39 [[nodiscard]]
40 constexpr decltype(auto) value() const noexcept
41 {
42 return ::std::forward<Refer>(m_value);
43 }
44
45 private:
46 Refer m_value;
47 };
48
49 template <concepts::wrapper_reference WrapperRefer>
50 class wrapper_guard<WrapperRefer, wrapper_guard_case::wrapper>
51 {
52 using wrapper_type = ::std::remove_cvref_t<WrapperRefer>;
53 using executor_type = typename wrapper_type::executor_type;
54 using executor_refer = scl::forward_like_t<WrapperRefer, executor_type>;
55
56 public:
57 wrapper_guard(wrapper_guard &&) = delete;
58 wrapper_guard(wrapper_guard const &) = delete;
59 wrapper_guard & operator=(wrapper_guard &&) = delete;
60 wrapper_guard & operator=(wrapper_guard const &) = delete;
61
62 constexpr explicit wrapper_guard(WrapperRefer w)
64 : m_executor{executor_access::get(::std::forward<WrapperRefer>(w))}
65 {
67 executor_type::guard(::std::forward<executor_refer>(m_executor));
68 }
69
70 constexpr ~wrapper_guard() noexcept(::scl::feature::is_unguard_noexcept_v<executor_type, executor_refer>)
71 {
73 executor_type::unguard(::std::forward<executor_refer>(m_executor));
74 }
75
76 [[nodiscard]]
77 constexpr decltype(auto) value() const noexcept
78 requires requires {
79 executor_type::template access<executor_refer>(::std::declval<executor_refer>());
80 }
81 {
82 return executor_type::template access<executor_refer>(::std::forward<executor_refer>(m_executor));
83 }
84
85 private:
86 executor_refer m_executor;
87 };
88} // 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.