EnumReflection.h 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. #pragma once
  2. #include <magic_enum.hpp>
  3. #include <fmt/format.h>
  4. template <class T> concept is_enum = std::is_enum_v<T>;
  5. namespace detail
  6. {
  7. template <is_enum E, class F, size_t ...I>
  8. constexpr void static_for(F && f, std::index_sequence<I...>)
  9. {
  10. (std::forward<F>(f)(std::integral_constant<E, magic_enum::enum_value<E>(I)>()) , ...);
  11. }
  12. }
  13. /**
  14. * Iterate over enum values in compile-time (compile-time switch/case, loop unrolling).
  15. *
  16. * @example static_for<E>([](auto enum_value) { return template_func<enum_value>(); }
  17. * ^ enum_value can be used as a template parameter
  18. */
  19. template <is_enum E, class F>
  20. constexpr void static_for(F && f)
  21. {
  22. constexpr size_t count = magic_enum::enum_count<E>();
  23. detail::static_for<E>(std::forward<F>(f), std::make_index_sequence<count>());
  24. }
  25. /// Enable printing enum values as strings via fmt + magic_enum
  26. template <is_enum T>
  27. struct fmt::formatter<T> : fmt::formatter<std::string_view>
  28. {
  29. constexpr auto format(T value, auto& format_context)
  30. {
  31. return formatter<string_view>::format(magic_enum::enum_name(value), format_context);
  32. }
  33. };