1#pragma once
2
3#include <type_traits>
4#include <utility>
5
6template <auto Val, decltype(Val)... List>
7inline constexpr bool static_in_v = std::disjunction_v<std::bool_constant<Val == List>...>;
8
9template <typename Func, typename Arg>
10bool func_wrapper(Func && func, Arg && arg)
11{
12 if constexpr (std::is_void_v<std::invoke_result_t<Func, Arg>>)
13 {
14 func(arg);
15 return false;
16 }
17 else
18 return func(arg);
19}
20
21template <typename T, T Begin, typename Func, T... Is>
22constexpr bool static_for_impl(Func && f, std::integer_sequence<T, Is...>)
23{
24 return (func_wrapper(std::forward<Func>(f), std::integral_constant<T, Begin + Is>{}) || ...);
25}
26
27template <auto Begin, decltype(Begin) End, typename Func>
28constexpr bool static_for(Func && f)
29{
30 using T = decltype(Begin);
31 return static_for_impl<T, Begin>(std::forward<Func>(f), std::make_integer_sequence<T, End - Begin>{});
32}
33