Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
AnyStopToken.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
25#include <boost/asio/spawn.hpp>
26
27#include <chrono>
28#include <memory>
29#include <type_traits>
30#include <utility>
31
32namespace util::async {
33
38public:
45 template <SomeStopToken TokenType>
47 /* implicit */ AnyStopToken(TokenType&& token)
48 : pimpl_{std::make_unique<Model<TokenType>>(std::forward<TokenType>(token))}
49 {
50 }
51
53 ~AnyStopToken() = default;
54
55 AnyStopToken(AnyStopToken const& other) : pimpl_{other.pimpl_->clone()}
56 {
57 }
58
60 operator=(AnyStopToken const& rhs)
61 {
62 AnyStopToken copy{rhs};
63 pimpl_.swap(copy.pimpl_);
64 return *this;
65 }
66
67 AnyStopToken(AnyStopToken&&) = default;
68
70 operator=(AnyStopToken&&) = default;
78 [[nodiscard]] bool
79 isStopRequested() const noexcept
80 {
81 return pimpl_->isStopRequested();
82 }
83
89 [[nodiscard]]
90 operator bool() const noexcept
91 {
92 return isStopRequested();
93 }
94
101 [[nodiscard]]
102 operator boost::asio::yield_context() const
103 {
104 return pimpl_->yieldContext();
105 }
106
107private:
108 struct Concept {
109 virtual ~Concept() = default;
110
111 [[nodiscard]] virtual bool
112 isStopRequested() const noexcept = 0;
113
114 [[nodiscard]] virtual std::unique_ptr<Concept>
115 clone() const = 0;
116
117 [[nodiscard]] virtual boost::asio::yield_context
118 yieldContext() const = 0;
119 };
120
121 template <SomeStopToken TokenType>
122 struct Model : Concept {
123 TokenType token;
124
125 Model(TokenType&& token) : token{std::move(token)}
126 {
127 }
128
129 [[nodiscard]] bool
130 isStopRequested() const noexcept override
131 {
132 return token.isStopRequested();
133 }
134
135 [[nodiscard]] std::unique_ptr<Concept>
136 clone() const override
137 {
138 return std::make_unique<Model>(*this);
139 }
140
141 [[nodiscard]] boost::asio::yield_context
142 yieldContext() const override
143 {
144 if constexpr (std::is_convertible_v<TokenType, boost::asio::yield_context>) {
145 return token;
146 }
147
148 ASSERT(false, "Token type does not support conversion to boost::asio::yield_context");
149 std::unreachable();
150 }
151 };
152
153private:
154 std::unique_ptr<Concept> pimpl_;
155};
156
157} // namespace util::async
A type-erased stop token.
Definition AnyStopToken.hpp:37
bool isStopRequested() const noexcept
Check if stop is requested.
Definition AnyStopToken.hpp:79
operator boost::asio::yield_context() const
Get the underlying boost::asio::yield_context.
Definition AnyStopToken.hpp:102
AnyStopToken(TokenType &&token)
Construct a new type-erased Stop Token object.
Definition AnyStopToken.hpp:47
Checks that decayed T s not of the same type as Erased.
Definition Concepts.hpp:198
Specifies the interface for a stop token.
Definition Concepts.hpp:110
This namespace implements an async framework built on top of execution contexts.
Definition AnyExecutionContext.hpp:36