userver: userver/engine/task/inherited_variable.hpp Source File
Loading...
Searching...
No Matches
inherited_variable.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/task/inherited_variable.hpp
4/// @brief @copybrief engine::TaskInheritedVariable
5
6#include <type_traits>
7#include <utility>
8
9#include <userver/engine/impl/task_local_storage.hpp>
10
11USERVER_NAMESPACE_BEGIN
12
13namespace engine {
14
15/// @ingroup userver_concurrency
16///
17/// @brief TaskInheritedVariable is a per-coroutine variable of arbitrary type.
18///
19/// These are like engine::TaskLocalVariable, but the variable instances are
20/// inherited by child tasks created via utils::Async.
21///
22/// The order of destruction of task-inherited variables is unspecified.
23template <typename T>
24class TaskInheritedVariable final {
25 static_assert(!std::is_reference_v<T>);
26 static_assert(!std::is_const_v<T>);
27
28 public:
29 /// @brief Get the variable instance for the current task.
30 /// @returns the variable or `nullptr` if variable was not set.
31 const T* GetOptional() const noexcept {
32 return Storage().GetOptional<T, kVariableKind>(impl_.GetKey());
33 }
34
35 /// @brief Get the variable instance for the current task.
36 /// @throws std::runtime_error if variable was not set.
37 const T& Get() const {
38 return Storage().Get<T, kVariableKind>(impl_.GetKey());
39 }
40
41 /// @brief Sets or replaces the T variable instance.
42 template <typename... Args>
43 void Emplace(Args&&... args) {
44 Storage().Emplace<T, kVariableKind>(impl_.GetKey(),
45 std::forward<Args>(args)...);
46 }
47
48 /// @overload
49 void Set(T&& value) { Emplace(std::move(value)); }
50
51 /// @overload
52 void Set(const T& value) { Emplace(value); }
53
54 /// @brief Hide the variable so that it is no longer accessible from the
55 /// current or new child tasks.
56 /// @note The variable might not actually be destroyed immediately.
57 void Erase() { Storage().Erase<T, kVariableKind>(impl_.GetKey()); }
58
59 private:
60 static constexpr auto kVariableKind =
61 impl::task_local::VariableKind::kInherited;
62
63 static impl::task_local::Storage& Storage() noexcept {
64 return impl::task_local::GetCurrentStorage();
65 }
66
67 impl::task_local::Variable impl_;
68};
69
70} // namespace engine
71
72USERVER_NAMESPACE_END