Last active
May 9, 2023 16:53
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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 | |
}, | |
)* | |
} | |
}; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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