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>
108 impl::InternalRequestContext& GetInternalContext();
111 utils::AnyMovable& SetUserAnyData(
utils::AnyMovable&& data);
112 utils::AnyMovable& GetUserAnyData();
113 utils::AnyMovable* GetUserAnyDataOptional();
114 void EraseUserAnyData();
116 utils::AnyMovable& SetAnyData(std::string&& name,
utils::AnyMovable&& data);
117 utils::AnyMovable& GetAnyData(std::string_view name);
118 utils::AnyMovable* GetAnyDataOptional(std::string_view name);
119 void EraseAnyData(std::string_view name);
122 static constexpr std::size_t kPimplSize = 112;
123 utils::FastPimpl<Impl, kPimplSize,
alignof(
void*)> impl_;
126template <
typename Data>
129 !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"
135 !std::is_reference_v<Data>,
136 "Data in RequestContext is stored by copy. Remove the reference "
137 "from the template parameter of SetUserData as it makes no sense"
139 return utils::AnyCast<Data&>(SetUserAnyData(std::move(data)));
142template <
typename Data,
typename... Args>
145 auto& data = SetUserAnyData(Data(std::forward<Args>(args)...));
146 return utils::AnyCast<Data&>(data);
149template <
typename Data>
151 return utils::AnyCast<Data&>(GetUserAnyData());
154template <
typename Data>
157 return const_cast<RequestContext*>(
this)->GetUserData<Data>();
160template <
typename Data>
162 auto* data = GetUserAnyDataOptional();
163 return data ? &
utils::AnyCast<Data&>(*data) :
nullptr;
166template <
typename Data>
169 return const_cast<RequestContext*>(
this)->GetUserDataOptional<Data>();
174template <
typename Data>
175Data& RequestContext::SetData(std::string name, Data data) {
177 !std::is_const_v<Data>,
178 "Data stored in RequestContext is mutable if RequestContext is "
179 "not `const`. Remove the `const` from the template parameter "
180 "of SetData as it makes no sense"
183 !std::is_reference_v<Data>,
184 "Data in RequestContext is stored by copy. Remove the reference "
185 "from the template parameter of SetData as it makes no sense"
187 return utils::AnyCast<Data&>(SetAnyData(std::move(name), std::move(data)));
190template <
typename Data,
typename... Args>
191Data& RequestContext::EmplaceData(std::string name, Args&&... args) {
193 auto& data = SetAnyData(std::move(name), Data(std::forward<Args>(args)...));
194 return utils::AnyCast<Data&>(data);
197template <
typename Data>
198Data& RequestContext::
GetData(std::string_view name) {
199 return utils::AnyCast<Data&>(GetAnyData(name));
202template <
typename Data>
203const Data& RequestContext::
GetData(std::string_view name)
const {
205 return const_cast<RequestContext*>(
this)->GetData<Data>(name);
208template <
typename Data>
210 auto* data = GetAnyDataOptional(name);
211 return data ? &utils::AnyCast<Data&>(*data) :
nullptr;
214template <
typename Data>
217 return const_cast<RequestContext*>(
this)->GetDataOptional<Data>(name);
220inline void RequestContext::
EraseData(std::string_view name) { EraseAnyData(name); }