10#include <userver/utils/any_movable.hpp>
11#include <userver/utils/fast_pimpl.hpp>
13USERVER_NAMESPACE_BEGIN
18class InternalRequestContext;
25class RequestContext
final {
29 RequestContext(RequestContext&&)
noexcept;
31 RequestContext(
const RequestContext&) =
delete;
37 template <
typename Data>
42 template <
typename Data,
typename... Args>
48 template <
typename Data>
54 template <
typename Data>
59 template <
typename Data>
64 template <
typename Data>
73 template <
typename Data>
74 Data&
SetData(std::string name, Data data);
79 template <
typename Data,
typename... Args>
80 Data&
EmplaceData(std::string name, Args&&... args);
85 template <
typename Data>
86 Data&
GetData(std::string_view name);
91 template <
typename Data>
92 const Data&
GetData(std::string_view name)
const;
96 template <
typename Data>
101 template <
typename Data>
109 impl::InternalRequestContext& GetInternalContext();
112 utils::AnyMovable& SetUserAnyData(utils::AnyMovable&& data);
113 utils::AnyMovable& GetUserAnyData();
114 utils::AnyMovable* GetUserAnyDataOptional();
115 void EraseUserAnyData();
117 utils::AnyMovable& SetAnyData(std::string&& name, utils::AnyMovable&& data);
118 utils::AnyMovable& GetAnyData(std::string_view name);
119 utils::AnyMovable* GetAnyDataOptional(std::string_view name);
120 void EraseAnyData(std::string_view name);
123 static constexpr std::size_t kPimplSize = 112;
124 utils::FastPimpl<Impl, kPimplSize,
alignof(
void*)> impl_;
127template <
typename Data>
129 static_assert(!std::is_const_v<Data>,
130 "Data stored in RequestContext is mutable if RequestContext is "
131 "not `const`. Remove the `const` from the template parameter "
132 "of SetUserData as it makes no sense");
134 !std::is_reference_v<Data>,
135 "Data in RequestContext is stored by copy. Remove the reference "
136 "from the template parameter of SetUserData as it makes no sense");
137 return utils::AnyCast<Data&>(SetUserAnyData(std::move(data)));
140template <
typename Data,
typename... Args>
143 auto& data = SetUserAnyData(Data(std::forward<Args>(args)...));
144 return utils::AnyCast<Data&>(data);
147template <
typename Data>
149 return utils::AnyCast<Data&>(GetUserAnyData());
152template <
typename Data>
155 return const_cast<RequestContext*>(
this)->GetUserData<Data>();
158template <
typename Data>
160 auto* data = GetUserAnyDataOptional();
161 return data ? &utils::AnyCast<Data&>(*data) :
nullptr;
164template <
typename Data>
168 return const_cast<RequestContext*>(
this)->GetUserDataOptional<Data>();
173template <
typename Data>
174Data& RequestContext::
SetData(std::string name, Data data) {
175 static_assert(!std::is_const_v<Data>,
176 "Data stored in RequestContext is mutable if RequestContext is "
177 "not `const`. Remove the `const` from the template parameter "
178 "of SetData as it makes no sense");
180 !std::is_reference_v<Data>,
181 "Data in RequestContext is stored by copy. Remove the reference "
182 "from the template parameter of SetData as it makes no sense");
183 return utils::AnyCast<Data&>(SetAnyData(std::move(name), std::move(data)));
186template <
typename Data,
typename... Args>
187Data& RequestContext::
EmplaceData(std::string name, Args&&... args) {
189 auto& data = SetAnyData(std::move(name), Data(std::forward<Args>(args)...));
190 return utils::AnyCast<Data&>(data);
193template <
typename Data>
194Data& RequestContext::
GetData(std::string_view name) {
195 return utils::AnyCast<Data&>(GetAnyData(name));
198template <
typename Data>
199const Data& RequestContext::
GetData(std::string_view name)
const {
201 return const_cast<RequestContext*>(
this)->GetData<Data>(name);
204template <
typename Data>
207 auto* data = GetAnyDataOptional(name);
208 return data ? &utils::AnyCast<Data&>(*data) :
nullptr;
211template <
typename Data>
215 return const_cast<RequestContext*>(
this)->GetDataOptional<Data>(name);
218inline void RequestContext::
EraseData(std::string_view name) {