8#include <userver/compiler/select.hpp> 
    9#include <userver/utils/any_movable.hpp> 
   10#include <userver/utils/fast_pimpl.hpp> 
   12USERVER_NAMESPACE_BEGIN
 
   20class RequestContext 
final {
 
   24  RequestContext(RequestContext&&) 
noexcept;
 
   26  RequestContext(
const RequestContext&) = 
delete;
 
   32  template <
typename Data>
 
   37  template <
typename Data, 
typename... Args>
 
   43  template <
typename Data>
 
   49  template <
typename Data>
 
   54  template <
typename Data>
 
   59  template <
typename Data>
 
   68  template <
typename Data>
 
   69  Data& 
SetData(std::string name, Data data);
 
   74  template <
typename Data, 
typename... Args>
 
   75  Data& 
EmplaceData(std::string name, Args&&... args);
 
   80  template <
typename Data>
 
   81  Data& 
GetData(
const std::string& name);
 
   86  template <
typename Data>
 
   87  const Data& 
GetData(
const std::string& name) 
const;
 
   91  template <
typename Data>
 
   96  template <
typename Data>
 
  106  static constexpr std::size_t kPimplSize = compiler::SelectSize()  
 
  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(
const std::string& name);
 
  119  utils::AnyMovable* GetAnyDataOptional(
const std::string& name);
 
  120  void EraseAnyData(
const std::string& name);
 
  122  utils::FastPimpl<Impl, kPimplSize, 
alignof(
void*), utils::kStrictMatch> impl_;
 
  125template <
typename Data>
 
  127  return utils::AnyCast<Data&>(SetUserAnyData(std::move(data)));
 
  130template <
typename Data, 
typename... Args>
 
  132  return utils::AnyCast<Data&>(
 
  133      SetUserAnyData(Data(std::forward<Args>(args)...)));
 
  136template <
typename Data>
 
  138  return utils::AnyCast<Data&>(GetUserAnyData());
 
  141template <
typename Data>
 
  144  return const_cast<RequestContext*>(
this)->GetUserData<Data>();
 
  147template <
typename Data>
 
  149  auto* data = GetUserAnyDataOptional();
 
  150  return data ? &
utils::AnyCast<Data&>(*data) : 
nullptr;
 
  153template <
typename Data>
 
  157  return const_cast<RequestContext*>(
this)->GetUserDataOptional<Data>();
 
  162template <
typename Data>
 
  163Data& RequestContext::
SetData(std::string name, Data data) {
 
  164  return utils::AnyCast<Data&>(SetAnyData(std::move(name), std::move(data)));
 
  167template <
typename Data, 
typename... Args>
 
  168Data& RequestContext::
EmplaceData(std::string name, Args&&... args) {
 
  169  return utils::AnyCast<Data&>(
 
  170      SetAnyData(std::move(name), Data(std::forward<Args>(args)...)));
 
  173template <
typename Data>
 
  174Data& RequestContext::
GetData(
const std::string& name) {
 
  175  return utils::AnyCast<Data&>(GetAnyData(name));
 
  178template <
typename Data>
 
  179const Data& RequestContext::
GetData(
const std::string& name) 
const {
 
  181  return const_cast<RequestContext*>(
this)->GetData<Data>(name);
 
  184template <
typename Data>
 
  187  auto* data = GetAnyDataOptional(name);
 
  188  return data ? &
utils::AnyCast<Data&>(*data) : 
nullptr;
 
  191template <
typename Data>
 
  195  return const_cast<RequestContext*>(
this)->GetDataOptional<Data>(name);
 
  198inline void RequestContext::
EraseData(
const std::string& name) {