userver: userver/engine/task/inherited_variable.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 /// @cond
60 // For internal use only
61 // inherits data to another storage
62 void InheritTo(impl::task_local::Storage& other,
63 impl::task_local::InternalTag) {
64 other.InheritNodeIfExists(Storage(), impl_.GetKey());
65 }
66 /// @endcond
67
68 private:
69 static constexpr auto kVariableKind =
70 impl::task_local::VariableKind::kInherited;
71
72 static impl::task_local::Storage& Storage() noexcept {
73 return impl::task_local::GetCurrentStorage();
74 }
75
76 impl::task_local::Variable impl_;
77};
78
79} // namespace engine
80
81USERVER_NAMESPACE_END