use crate::core;
use proc_macro2::TokenStream;
use quote::quote;
use std::ops::RangeInclusive;
pub fn impl_ougi(range: &RangeInclusive<u32>) -> TokenStream {
let mut impls = Vec::new();
let max = *range.end();
for n_1 in range.clone() {
for is_signed in [false, true] {
let struct_name_1 = core::struct_name(n_1, is_signed);
let flag_name_1 = core::feature_name(n_1, is_signed);
if n_1 * 2 < max {
let n_2 = n_1 * 2;
let struct_name_2 = core::struct_name(n_2, is_signed);
let flag_name_2 = core::feature_name(n_2, is_signed);
impls.push(quote! {
#[cfg(all(feature = #flag_name_1, feature = #flag_name_2))]
impl ougi::BitDouble for #struct_name_1 {
type Double = #struct_name_2;
fn double(&self) -> Self::Double {
(*self).into()
}
}
});
}
if n_1 % 2 == 0 {
let n_2 = n_1 / 2;
let struct_name_2 = core::struct_name(n_2, is_signed);
let flag_name_2 = core::feature_name(n_2, is_signed);
impls.push(quote! {
#[cfg(all(feature = #flag_name_1, feature = #flag_name_2))]
impl ougi::BitHalf for #struct_name_1 {
type Half = #struct_name_2;
fn half(&self) -> Option<Self::Half> {
(*self).try_into().ok()
}
}
});
}
}
}
impls.into_iter().collect()
}