1 | #pragma once |
2 | |
3 | #include <type_traits> |
4 | #include <utility> |
5 | |
6 | template <auto Val, decltype(Val)... List> |
7 | inline constexpr bool static_in_v = std::disjunction_v<std::bool_constant<Val == List>...>; |
8 | |
9 | template <typename Func, typename Arg> |
10 | bool 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 | |
21 | template <typename T, T Begin, typename Func, T... Is> |
22 | constexpr 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 | |
27 | template <auto Begin, decltype(Begin) End, typename Func> |
28 | constexpr 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 | |