macro_rules! impl_accept_upper_bound {
{
$(#[$meta:meta])*
impl{$($params:tt)*} $Self:ty $({ $($where_bounds:tt)* })?;
const DESIRED_GENERIC: $usize_d:ty = $DESIRED_GENERIC:expr;
const EVAL<const $UPPER:ident: $usize_e:ty>: $Output:ty = $EVAL:expr;
} => { ... };
}Expand description
Implements AcceptUpperBound by generating a hidden Const implementor.
Generic parameters are passed in braces ({...}) after impl and cannot have a trailing
comma. Where bounds are optionally passed in braces after the implementing type.
The example from the crate level documentation can be written manually like this:
use generic_upper_bound as gub;
pub trait MyTrait {
const SOME_STR: &'static str;
}
impl<A: MyTrait, B: MyTrait> MyTrait for (A, B) {
const SOME_STR: &'static str = match core::str::from_utf8(
gub::eval_with_upper_bound::<Concat<A, B>>()
.split_at(gub::desired_generic::<Concat<A, B>>())
.0,
) {
Ok(s) => s,
_ => unreachable!(),
};
}
struct Concat<A, B>(A, B);
impl<A: MyTrait, B: MyTrait> gub::AcceptUpperBound for Concat<A, B> {
type Output = &'static [u8];
// Want to be passed at least the total length of the strings
const DESIRED_GENERIC: usize = A::SOME_STR.len() + B::SOME_STR.len();
// Decide on what to do with each generic const
type Eval<const UPPER: usize> = ConcatImpl<A, B, UPPER>;
}
struct ConcatImpl<A, B, const N: usize>(A, B);
impl<A: MyTrait, B: MyTrait, const N: usize> gub::Const for ConcatImpl<A, B, N> {
type Type = &'static [u8];
const VALUE: Self::Type = panic!("...");
}