variant.h 1.6 KB

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