Skip to content

Instantly share code, notes, and snippets.

@griffi-gh
Last active May 9, 2023 16:53
Show Gist options
  • Save griffi-gh/4530078fd8bc394ac3b427c210d54c78 to your computer and use it in GitHub Desktop.
Save griffi-gh/4530078fd8bc394ac3b427c210d54c78 to your computer and use it in GitHub Desktop.
Use rutime `bool` variables in const generics;based on macro written by by Bruh#1794
/// based on macro written by by Bruh#1794
macro_rules! expand_bool {
(let $callback_var_name: ident: $($fn_name:ident ::)* <$($var_name:ident),+ $(,)?> => $callback: block) => {
expand_bool!([$($fn_name)::*] [$($var_name)+] [$($var_name)+] [()] [$callback_var_name] [$callback])
};
(
[$fn_name:path]
[$($all_names:ident)+]
[$_var_first:ident $($var_rest:ident)*]
[ $( ($($bool:literal)*) )* ]
[ $callback_var_name: ident ]
[ $callback: block ]
) => {
expand_bool!(
[$fn_name]
[$($all_names)+]
[$($var_rest)*]
[$(($($bool)* true) ($($bool)* false))*]
[$callback_var_name]
[$callback]
)
};
(
[$fn_name:path]
[$($all_names:ident)+]
[]
[$( ($($bool:literal)*) )*]
[$callback_var_name: ident]
[$callback: expr ]
) => {
#[allow(unreachable_code)]
match ($($all_names),+) {
$(
($($bool),*) => {
let $callback_var_name = {
use $fn_name as _fn;
_fn::<$($bool),*>
};
$callback
},
)*
}
};
}
fn foo_const<const A: bool, const B: bool, const C: bool>(arg: i32) {
dbg!(A, B, C, arg);
}
fn foo(a: bool, b: bool, c: bool) {
expand_bool!(let func: foo_const::<a, b, c> => {
func(5);
});
}
fn main() {
foo(true, false, true);
foo(false, false, false);
}
[src/main.rs:49] A = true
[src/main.rs:49] B = false
[src/main.rs:49] C = true
[src/main.rs:49] arg = 5
[src/main.rs:49] A = false
[src/main.rs:49] B = false
[src/main.rs:49] C = false
[src/main.rs:49] arg = 5
// Expansion of the expand_bool! call from usage.rs
// This macro is supposed to be used in const contexts
// or situations where the compiler can optimize all of these matches away
// ==========================================
// Recursive expansion of expand_bool! macro
// ==========================================
#[allow(unreachable_code)]
match (a, b, c) {
(true, true, true) => {
let func = {
use foo_const as _fn;
_fn::<true, true, true>
};
{
func(5);
}
}
(true, true, false) => {
let func = {
use foo_const as _fn;
_fn::<true, true, false>
};
{
func(5);
}
}
(true, false, true) => {
let func = {
use foo_const as _fn;
_fn::<true, false, true>
};
{
func(5);
}
}
(true, false, false) => {
let func = {
use foo_const as _fn;
_fn::<true, false, false>
};
{
func(5);
}
}
(false, true, true) => {
let func = {
use foo_const as _fn;
_fn::<false, true, true>
};
{
func(5);
}
}
(false, true, false) => {
let func = {
use foo_const as _fn;
_fn::<false, true, false>
};
{
func(5);
}
}
(false, false, true) => {
let func = {
use foo_const as _fn;
_fn::<false, false, true>
};
{
func(5);
}
}
(false, false, false) => {
let func = {
use foo_const as _fn;
_fn::<false, false, false>
};
{
func(5);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment