Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
ErasedOperation.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2024, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Assert.hpp"
23#include "util/async/Concepts.hpp"
24#include "util/async/Error.hpp"
25
26#include <any>
27#include <expected>
28#include <memory>
29#include <type_traits>
30#include <utility>
31
32namespace util::async::impl {
33
35public:
36 template <SomeOperation OpType>
37 requires(not std::is_same_v<std::decay_t<OpType>, ErasedOperation>)
38 /* implicit */ ErasedOperation(OpType&& operation)
39 : pimpl_{std::make_unique<Model<OpType>>(std::forward<OpType>(operation))}
40 {
41 }
42
43 ~ErasedOperation() = default;
44
45 ErasedOperation(ErasedOperation const&) = delete;
47
49 operator=(ErasedOperation const&) = delete;
51 operator=(ErasedOperation&&) = default;
52
53 void
54 wait() noexcept
55 {
56 pimpl_->wait();
57 }
58
59 std::expected<std::any, ExecutionError>
60 get()
61 {
62 return pimpl_->get();
63 }
64
68 void
70 {
71 pimpl_->abort();
72 }
73
74 void
75 invoke()
76 {
77 pimpl_->invoke();
78 }
79
80private:
81 struct Concept {
82 virtual ~Concept() = default;
83
84 virtual void
85 wait() noexcept = 0;
86 virtual std::expected<std::any, ExecutionError>
87 get() = 0;
88 virtual void
89 abort() = 0;
90 virtual void
91 invoke() = 0;
92 };
93
94 template <SomeOperation OpType>
95 struct Model : Concept {
96 OpType operation;
97
98 template <typename OType>
99 requires std::is_same_v<OType, OpType>
100 Model(OType&& operation) : operation{std::forward<OType>(operation)}
101 {
102 }
103
104 void
105 wait() noexcept override
106 {
107 if constexpr (not SomeAwaitable<OpType>) {
108 ASSERT(false, "Called wait() on an operation that does not support it");
109 std::unreachable();
110 } else {
111 operation.wait();
112 }
113 }
114
115 std::expected<std::any, ExecutionError>
116 get() override
117 {
118 if constexpr (not SomeOperationWithData<OpType>) {
119 ASSERT(false, "Called get() on an operation that does not support it");
120 std::unreachable();
121 } else {
122 // Note: return type of the operation was already wrapped to std::any by AnyExecutionContext
123 return operation.get();
124 }
125 }
126
127 void
128 abort() override
129 {
130 if constexpr (not SomeCancellableOperation<OpType> and not SomeStoppableOperation<OpType> and
131 not SomeAbortable<OpType>) {
132 ASSERT(false, "Called abort() on an operation that can't be aborted, cancelled nor stopped");
133 } else {
134 if constexpr (SomeAbortable<OpType>) {
135 operation.abort();
136 } else {
137 if constexpr (SomeCancellableOperation<OpType>)
138 operation.cancel();
139 if constexpr (SomeStoppableOperation<OpType>)
140 operation.requestStop();
141 }
142 }
143 }
144
145 void
146 invoke() override
147 {
148 if constexpr (not SomeForceInvocableOperation<OpType>) {
149 ASSERT(false, "Called invoke() on an operation that can't be force-invoked");
150 } else {
151 operation.invoke();
152 }
153 }
154 };
155
156private:
157 std::unique_ptr<Concept> pimpl_;
158};
159
160} // namespace util::async::impl
Definition ErasedOperation.hpp:34
void abort()
Cancel if needed and request stop as soon as possible.
Definition ErasedOperation.hpp:69
Specifies the interface for an operation.
Definition Concepts.hpp:68
Error channel type for async operation of any ExecutionContext.
Definition Error.hpp:39