2021-09-06 14:24:03 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-09-06 15:59:46 +00:00
|
|
|
#include <magic_enum.hpp>
|
2021-09-06 14:24:03 +00:00
|
|
|
#include <fmt/format.h>
|
2021-09-10 11:49:22 +00:00
|
|
|
|
2021-09-10 21:28:43 +00:00
|
|
|
template <class T> concept is_enum = std::is_enum_v<T>;
|
2021-09-10 11:49:22 +00:00
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
2021-09-10 21:28:43 +00:00
|
|
|
template <is_enum E, class F, size_t ...I>
|
2021-09-10 11:49:22 +00:00
|
|
|
constexpr void static_for(F && f, std::index_sequence<I...>)
|
|
|
|
{
|
|
|
|
(std::forward<F>(f)(std::integral_constant<E, magic_enum::enum_value<E>(I)>()) , ...);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Iterate over enum values in compile-time (compile-time switch/case, loop unrolling).
|
|
|
|
*
|
|
|
|
* @example static_for<E>([](auto enum_value) { return template_func<enum_value>(); }
|
|
|
|
* ^ enum_value can be used as a template parameter
|
|
|
|
*/
|
2021-09-10 21:28:43 +00:00
|
|
|
template <is_enum E, class F>
|
2021-09-10 11:49:22 +00:00
|
|
|
constexpr void static_for(F && f)
|
|
|
|
{
|
|
|
|
constexpr size_t count = magic_enum::enum_count<E>();
|
|
|
|
detail::static_for<E>(std::forward<F>(f), std::make_index_sequence<count>());
|
|
|
|
}
|
2021-09-06 14:24:03 +00:00
|
|
|
|
2021-09-06 15:59:46 +00:00
|
|
|
/// Enable printing enum values as strings via fmt + magic_enum
|
2021-09-10 21:28:43 +00:00
|
|
|
template <is_enum T>
|
2021-09-06 15:59:46 +00:00
|
|
|
struct fmt::formatter<T> : fmt::formatter<std::string_view>
|
|
|
|
{
|
2021-09-10 21:28:43 +00:00
|
|
|
constexpr auto format(T value, auto& format_context)
|
2021-09-06 15:59:46 +00:00
|
|
|
{
|
2021-09-10 21:28:43 +00:00
|
|
|
return formatter<string_view>::format(magic_enum::enum_name(value), format_context);
|
2021-09-06 14:24:03 +00:00
|
|
|
}
|
|
|
|
};
|