userver: userver/engine/task/local_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
local_variable.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/task/local_variable.hpp
4/// @brief @copybrief engine::TaskLocalVariable
5
6#include <type_traits>
7
8#include <userver/engine/impl/task_local_storage.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace engine {
13
14/// @ingroup userver_concurrency
15///
16/// @brief TaskLocalVariable is a per-coroutine variable of arbitrary type.
17///
18/// It is an alternative to `thread_local`, but per-task instead of per-thread.
19///
20/// The order of destruction of task-local variables is inverse to the order of
21/// initialization.
22template <typename T>
23class TaskLocalVariable final {
24 static_assert(!std::is_reference_v<T>);
25 static_assert(!std::is_const_v<T>);
26
27 public:
28 /// @brief Get the instance of the variable for the current coroutine.
29 /// Initializes (default constructs) the variable if it was not previously
30 /// initialized.
31 /// @note Must be called from a coroutine, otherwise it is UB.
32 T& operator*();
33
34 /// @overload
35 T* operator->();
36
37 /// @brief Get the variable instance for the current task.
38 /// @returns the variable or `nullptr` if variable was not initialized.
39 T* GetOptional() noexcept {
40 return impl::task_local::GetCurrentStorage().GetOptional<T, kVariableKind>(
41 impl_.GetKey());
42 }
43
44 private:
45 static constexpr auto kVariableKind = impl::task_local::VariableKind::kNormal;
46
47 impl::task_local::Variable impl_;
48};
49
50template <typename T>
51T& TaskLocalVariable<T>::operator*() {
52 return impl::task_local::GetCurrentStorage().GetOrEmplace<T, kVariableKind>(
53 impl_.GetKey());
54}
55
56template <typename T>
57T* TaskLocalVariable<T>::operator->() {
58 return &(**this);
59}
60
61} // namespace engine
62
63USERVER_NAMESPACE_END