userver: userver/engine/awaitable.hpp Source File
Loading...
Searching...
No Matches
awaitable.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/awaitable.hpp
4/// @brief Utilities for integration with @ref engine::WaitAny and friends.
5
6#include <concepts>
7
8#include <userver/utils/assert.hpp>
9#include <userver/utils/impl/internal_tag.hpp>
10
11USERVER_NAMESPACE_BEGIN
12
13namespace engine::impl {
14class AwaitableBase;
15}
16
17namespace engine {
18
19/// @brief A lightweight token that exposes a view over an awaitable to @ref engine::WaitAny and friends.
20///
21/// User-facing awaitable types return this token from their `GetAwaitableToken` methods.
22/// Empty token means that the object cannot be awaited right now.
23class AwaitableToken final {
24public:
25 /// @brief Creates an empty token. It will be skipped in @ref engine::WaitAny and friends.
26 constexpr AwaitableToken() noexcept = default;
27
28 AwaitableToken(const AwaitableToken&) noexcept = default;
29 AwaitableToken(AwaitableToken&&) noexcept = default;
30 AwaitableToken& operator=(const AwaitableToken&) noexcept = default;
31 AwaitableToken& operator=(AwaitableToken&&) noexcept = default;
32 ~AwaitableToken() = default;
33
34 /// @brief Returns true if the token does not refer to an awaitable.
35 [[nodiscard]] constexpr bool IsEmpty() const noexcept { return awaitable_ == nullptr; }
36
37 /// @brief Compares referred awaitables.
38 [[nodiscard]] constexpr bool operator==(const AwaitableToken& other) const noexcept {
39 return awaitable_ == other.awaitable_;
40 }
41
42 /// @cond
43 // For internal use only.
44 constexpr AwaitableToken(utils::impl::InternalTag, impl::AwaitableBase* awaitable) noexcept : awaitable_(awaitable) {}
45
46 // For internal use only. Precondition: !IsEmpty().
47 [[nodiscard]] impl::AwaitableBase& GetAwaitable(utils::impl::InternalTag) const noexcept {
49 return *awaitable_;
50 }
51 /// @endcond
52
53private:
54 impl::AwaitableBase* awaitable_{nullptr};
55};
56
57/// @brief Returns a non-empty token that is always ready. Useful for mocking awaitables in tests.
58AwaitableToken MakeReadyAwaitableToken() noexcept;
59
60/// @brief A type that can expose an awaitable token for @ref engine::WaitAny and friends.
61template <typename T>
62concept Awaitable = requires(T& value) {
63 {
64 value.GetAwaitableToken()
65 } -> std::same_as<AwaitableToken>;
66};
67
68} // namespace engine
69
70USERVER_NAMESPACE_END