7#include <initializer_list> 
   12USERVER_NAMESPACE_BEGIN
 
   24class AnyMovable 
final {
 
   31  AnyMovable& operator=(AnyMovable&&) 
noexcept = 
default;
 
   40  template <
typename ValueType, 
typename... Args>
 
   41  explicit AnyMovable(std::in_place_type_t<ValueType> tag, Args&&... args);
 
   44  template <
typename ValueType, 
typename Item, 
typename... Args>
 
   45  explicit AnyMovable(std::in_place_type_t<ValueType> tag,
 
   46                      std::initializer_list<Item> list, Args&&... args);
 
   50  template <
typename ValueType>
 
   51  AnyMovable& 
operator=(ValueType&& rhs);
 
   60  template <
typename ValueType, 
typename... Args>
 
   61  ValueType& 
Emplace(Args&&... args);
 
   64  template <
typename ValueType, 
typename Item, 
typename... Args>
 
   65  ValueType& 
Emplace(std::initializer_list<Item> list, Args&&... args);
 
   70  template <
typename ValueType>
 
   73  struct HolderDeleter {
 
   77  template <
typename ValueType>
 
   78  friend ValueType* 
AnyCast(AnyMovable*) 
noexcept;
 
   80  template <
typename ValueType>
 
   81  friend const ValueType* 
AnyCast(
const AnyMovable*) 
noexcept;
 
   83  std::unique_ptr<
HolderBase, HolderDeleter> content_;
 
   87class BadAnyMovableCast 
final : 
public std::bad_any_cast {
 
   89  const char* what() 
const noexcept override;
 
   94template <
typename ValueType>
 
   95ValueType* 
AnyCast(AnyMovable* operand) 
noexcept;
 
   99template <
typename ValueType>
 
  100const ValueType* 
AnyCast(
const AnyMovable* operand) 
noexcept;
 
  105template <
typename ValueType>
 
  106ValueType 
AnyCast(AnyMovable& operand);
 
  111template <
typename ValueType>
 
  112ValueType 
AnyCast(
const AnyMovable& operand);
 
  117template <
typename ValueType>
 
  118ValueType 
AnyCast(AnyMovable&& operand);
 
  121  using DeleterType = 
void (*)(
HolderBase&) 
noexcept;
 
  126template <
typename ValueType>
 
  127struct AnyMovable::Holder 
final : 
public HolderBase {
 
  128  static_assert(std::is_same_v<ValueType, std::decay_t<ValueType>>,
 
  129                "The requested type can't be stored in an AnyMovable");
 
  133  static void Deleter(
HolderBase& holder) 
noexcept {
 
  134    delete &
static_cast<Holder&>(holder);
 
  137  template <
typename... Args>
 
  138  static std::unique_ptr<
HolderBase, HolderDeleter> Make(Args&&... args) {
 
  139    return std::unique_ptr<HolderBase, HolderDeleter>{
 
  142        new Holder{{&Deleter}, ValueType(std::forward<Args>(args)...)}};
 
  145  static ValueType* GetIf(
const AnyMovable* any) 
noexcept {
 
  146    return (any && any->content_ && any->content_->deleter == &Deleter)
 
  147               ? &
static_cast<Holder&>(*any->content_).held
 
  152template <
typename ValueType, 
typename>
 
  157      !std::is_same_v<AnyMovable*, std::decay_t<ValueType>> &&
 
  158          !std::is_same_v<
const AnyMovable*, std::decay_t<ValueType>>,
 
  159      "AnyMovable misuse detected: trying to wrap AnyMovable* in another " 
  160      "AnyMovable. The pointer was probably meant to be dereferenced.");
 
  163template <
typename ValueType, 
typename... Args>
 
  164AnyMovable::
AnyMovable(std::in_place_type_t<ValueType> , Args&&... args)
 
  167template <
typename ValueType, 
typename Item, 
typename... Args>
 
  169                       std::initializer_list<Item> list, Args&&... args)
 
  172template <
typename ValueType>
 
  173AnyMovable& AnyMovable::
operator=(ValueType&& rhs) {
 
  174  *
this = AnyMovable(std::forward<ValueType>(rhs));
 
  178template <
typename ValueType, 
typename... Args>
 
  179ValueType& AnyMovable::
Emplace(Args&&... args) {
 
  180  content_ = Holder<ValueType>::Make(std::forward<Args>(args)...);
 
  181  return static_cast<Holder<ValueType>&>(*content_).held;
 
  184template <
typename ValueType, 
typename Item, 
typename... Args>
 
  185ValueType& AnyMovable::
Emplace(std::initializer_list<Item> list,
 
  187  content_ = Holder<ValueType>::Make(list, std::forward<Args>(args)...);
 
  188  return static_cast<Holder<ValueType>&>(*content_).held;
 
  191template <
typename ValueType>
 
  192ValueType* 
AnyCast(AnyMovable* operand) 
noexcept {
 
  193  return AnyMovable::Holder<ValueType>::GetIf(operand);
 
  196template <
typename ValueType>
 
  197const ValueType* 
AnyCast(
const AnyMovable* operand) 
noexcept {
 
  198  return AnyMovable::Holder<ValueType>::GetIf(operand);
 
  201template <
typename ValueType>
 
  205  using NonRef = std::remove_cv_t<std::remove_reference_t<ValueType>>;
 
  206  auto* result = AnyCast<NonRef>(&operand);
 
  207  if (!result) 
throw BadAnyMovableCast();
 
  208  return static_cast<ValueType>(*result);
 
  211template <
typename ValueType>
 
  215  using NonRef = std::remove_cv_t<std::remove_reference_t<ValueType>>;
 
  216  auto* result = AnyCast<NonRef>(&operand);
 
  217  if (!result) 
throw BadAnyMovableCast();
 
  218  return static_cast<ValueType>(*result);
 
  221template <
typename ValueType>
 
  223  using NonRef = std::remove_cv_t<std::remove_reference_t<ValueType>>;
 
  224  auto* result = AnyCast<NonRef>(&operand);
 
  225  if (!result) 
throw BadAnyMovableCast();
 
  226  return static_cast<ValueType>(std::move(*result));