| 40 | |
| 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]>>> && ...); |
| 45 | |
| 46 | if constexpr (has_void_return) { |
| 47 | (f(enum_constant<values_v<E, S>[I]>{}), ...); |
| 48 | } else if constexpr (all_same_return) { |
| 49 | return std::array{f(enum_constant<values_v<E, S>[I]>{})...}; |
| 50 | } else { |
| 51 | return std::tuple{f(enum_constant<values_v<E, S>[I]>{})...}; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | template <typename E, enum_subtype S, typename F,std::size_t... I> |
| 56 | constexpr bool all_invocable(std::index_sequence<I...>) { |
nothing calls this directly
no outgoing calls
no test coverage detected