32 #ifndef NEARGYE_MAGIC_ENUM_UTILITY_HPP
33 #define NEARGYE_MAGIC_ENUM_UTILITY_HPP
41 template <
typename E,
enum_subtype S,
typename F, std::size_t... I>
42 constexpr
auto for_each(F&& f, std::index_sequence<I...>) {
43 constexpr
bool has_void_return = (std::is_void_v<std::invoke_result_t<F, enum_constant<values_v<E, S>[I]>>> || ...);
44 constexpr
bool all_same_return = (std::is_same_v<std::invoke_result_t<F, enum_constant<values_v<E, S>[0]>>, std::invoke_result_t<F, enum_constant<values_v<E, S>[I]>>> && ...);
46 if constexpr (has_void_return) {
48 }
else if constexpr (all_same_return) {
55 template <
typename E,
enum_subtype S,
typename F,std::size_t... I>
57 if constexpr (count_v<E, S> == 0) {
60 return (std::is_invocable_v<F,
enum_constant<values_v<E, S>[I]>> && ...);
66 template <
typename E, detail::enum_subtype S = detail::subtype_v<E>,
typename F, detail::enable_if_t<E,
int> = 0>
68 using D = std::decay_t<E>;
69 static_assert(std::is_enum_v<D>,
"magic_enum::enum_for_each requires enum type.");
70 static_assert(detail::is_reflected_v<D, S>,
"magic_enum requires enum implementation and valid max and min.");
71 constexpr
auto sep = std::make_index_sequence<detail::count_v<D, S>>{};
73 if constexpr (detail::all_invocable<D, S, F>(sep)) {
74 return detail::for_each<D, S>(std::forward<F>(f), sep);
76 static_assert(detail::always_false_v<D>,
"magic_enum::enum_for_each requires invocable of all enum value.");
80 template <
typename E, detail::enum_subtype S = detail::subtype_v<E>>
82 using D = std::decay_t<E>;
83 constexpr std::ptrdiff_t count = detail::count_v<D, S>;
85 if (
const auto i = enum_index<D, S>(
value)) {
86 const std::ptrdiff_t index = (
static_cast<std::ptrdiff_t
>(*i) +
n);
87 if (index >= 0 && index < count) {
88 return enum_value<D, S>(
static_cast<std::size_t
>(index));
94 template <
typename E, detail::enum_subtype S = detail::subtype_v<E>>
96 using D = std::decay_t<E>;
97 constexpr std::ptrdiff_t count = detail::count_v<D, S>;
99 if (
const auto i = enum_index<D, S>(
value)) {
100 const std::ptrdiff_t index = ((((
static_cast<std::ptrdiff_t
>(*i) +
n) % count) + count) % count);
101 if (index >= 0 && index < count) {
102 return enum_value<D, S>(
static_cast<std::size_t
>(index));
108 template <
typename E, detail::enum_subtype S = detail::subtype_v<E>>
110 using D = std::decay_t<E>;
111 constexpr std::ptrdiff_t count = detail::count_v<D, S>;
113 if (
const auto i = enum_index<D, S>(
value)) {
114 const std::ptrdiff_t index = (
static_cast<std::ptrdiff_t
>(*i) -
n);
115 if (index >= 0 && index < count) {
116 return enum_value<D, S>(
static_cast<std::size_t
>(index));
122 template <
typename E, detail::enum_subtype S = detail::subtype_v<E>>
124 using D = std::decay_t<E>;
125 constexpr std::ptrdiff_t count = detail::count_v<D, S>;
127 if (
const auto i = enum_index<D, S>(
value)) {
128 const std::ptrdiff_t index = ((((
static_cast<std::ptrdiff_t
>(*i) -
n) % count) + count) % count);
129 if (index >= 0 && index < count) {
130 return enum_value<D, S>(
static_cast<std::size_t
>(index));
138 #endif // NEARGYE_MAGIC_ENUM_UTILITY_HPP