variant.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #pragma once
  2. #include <util/generic/string.h>
  3. #include <util/generic/variant.h>
  4. namespace NYT {
  5. ////////////////////////////////////////////////////////////////////////////////
  6. class TStringBuilderBase;
  7. template <class... Ts>
  8. void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec);
  9. void FormatValue(TStringBuilderBase* builder, const std::monostate&, TStringBuf /*spec*/);
  10. ////////////////////////////////////////////////////////////////////////////////
  11. //! A concise way of creating a functor with an overloaded operator().
  12. /*!
  13. * Very useful for std::visit-ing variants. For example:
  14. *
  15. * std::visit(TOverloaded{
  16. * [] (int i) { printf("The variant holds an int: %d!", i); },
  17. * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); }
  18. * }, variantVariable);
  19. */
  20. template<class... Ts> struct TOverloaded : Ts... { using Ts::operator()...; };
  21. template<class... Ts> TOverloaded(Ts...) -> TOverloaded<Ts...>;
  22. ////////////////////////////////////////////////////////////////////////////////
  23. //! An alternative to std::visit that takes its variant argument first.
  24. /*!
  25. * This deprives it of being able to visit a Cartesian product of variants but
  26. * in exchange allows to receive multiple visitor functors. All of operator()s
  27. * these functors have are used to visit the variant after a single unified
  28. * overload resolution. For example:
  29. *
  30. * Visit(variantVariable,
  31. * [] (int i) { printf("The variant holds an int: %d!", i); },
  32. * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); });
  33. */
  34. template <class T, class... U>
  35. auto Visit(T&& variant, U&&... visitorOverloads)
  36. {
  37. return std::visit(TOverloaded{std::forward<U>(visitorOverloads)...}, std::forward<T>(variant));
  38. }
  39. ////////////////////////////////////////////////////////////////////////////////
  40. } // namespace NYT
  41. #define VARIANT_INL_H_
  42. #include "variant-inl.h"
  43. #undef VARIANT_INL_H_