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]] operator bool() const noexcept
90 {
91 return isStopRequested();
92 }
93
100 [[nodiscard]] operator boost::asio::yield_context() const
101 {
102 return pimpl_->yieldContext();
103 }
104
105private:
106 struct Concept {
107 virtual ~Concept() = default;
108
109 [[nodiscard]] virtual bool
110 isStopRequested() const noexcept = 0;
111
112 [[nodiscard]] virtual std::unique_ptr<Concept>
113 clone() const = 0;
114
115 [[nodiscard]] virtual boost::asio::yield_context
116 yieldContext() const = 0;
117 };
118
119 template <SomeStopToken TokenType>
120 struct Model : Concept {
121 TokenType token;
122
123 Model(TokenType&& token) : token{std::move(token)}
124 {
125 }
126
127 [[nodiscard]] bool
128 isStopRequested() const noexcept override
129 {
130 return token.isStopRequested();
131 }
132
133 [[nodiscard]] std::unique_ptr<Concept>
134 clone() const override
135 {
136 return std::make_unique<Model>(*this);
137 }
138
139 [[nodiscard]] boost::asio::yield_context
140 yieldContext() const override
141 {
142 if constexpr (std::is_convertible_v<TokenType, boost::asio::yield_context>) {
143 return token;
144 }
145
146 ASSERT(false, "Token type does not support conversion to boost::asio::yield_context");
147 std::unreachable();
148 }
149 };
150
151private:
152 std::unique_ptr<Concept> pimpl_;
153};
154
155} // 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:100
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:190
Specifies the interface for a stop token.
Definition Concepts.hpp:102
This namespace implements an async framework built on top of execution contexts.
Definition AnyExecutionContext.hpp:36