<commit_before>pub struct HNil;
 
pub struct HCons<H, T> {
    pub head: H,
    pub tail: T
}

pub trait Contains<A> {
    fn get(&self) -> &A;
    fn get_mut(&mut self) -> &mut A;
}

macro_rules! hlist_type_internal {
    ($hlist_name:ident, $hlist_current:ty, $th:ty, $($tr:ty,)*) => {
       hlist_type_internal!($hlist_name, HCons<$th, $hlist_current>, $($tr,)*);
    };
    ($hlist_name:ident, $hlist_current:ty,) => {
        type $hlist_name = $hlist_current;
    }
}

#[macro_export]
macro_rules! hlist_type {
    ($hlist:ident) => {hlist_type_internal!($hlist, HNil,)};
    ($hlist:ident, $($types:ty),* ) => {hlist_type_internal!($hlist, $crate::HNil, $($types,)*);}
}

macro_rules! generate_hlist_contains {
    
    ($hlist:ty) => {{}};
    ($hlist:ty,) => {{}};
    
    ($hlist:ty, $last:ty, $($init:ty,)*) => {{
    
        impl $crate::Contains<$last> for $hlist {
        
            #[allow(unused_variables)]
            fn get(&self) -> &$last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head; // Only used to refer to $init 
                    let cur_cell = &cur_cell.tail;
                )*
                &cur_cell.head
            }
            
            #[allow(unused_variables)]
            fn get_mut(&mut self) -> &mut $last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head;
                    let cur_cell = &mut cur_cell.tail;
                )*
                &mut cur_cell.head
            }
        }
        
        generate_hlist_contains!($hlist, $($init,)*);
    }}
}

/// Test comment
#[macro_export]
macro_rules! generate_contains_impls {
    ($($types:ty),*) => {{
        hlist_type!(TheHList, $($types),*); 
        generate_hlist_contains!(TheHList, $($types,)*);
    }}
}

pub trait HList: Sized {
    fn insert<A: Sized>(self, a: A) -> HCons<A, Self> {
        HCons { head: a, tail: self }
    }
}


 
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}

#[test]
fn it_works() {
}<commit_msg>empty_hlist_type test<commit_after>pub struct HNil;
 
pub struct HCons<H, T> {
    pub head: H,
    pub tail: T
}

pub trait Contains<A> {
    fn get(&self) -> &A;
    fn get_mut(&mut self) -> &mut A;
}

macro_rules! hlist_type_internal {
    ($hlist_name:ident, $hlist_current:ty, $th:ty, $($tr:ty,)*) => {
       hlist_type_internal!($hlist_name, HCons<$th, $hlist_current>, $($tr,)*);
    };
    ($hlist_name:ident, $hlist_current:ty,) => {
        type $hlist_name = $hlist_current;
    }
}

#[macro_export]
macro_rules! hlist_type {
    ($hlist:ident) => {hlist_type_internal!($hlist, HNil,)};
    ($hlist:ident, $($types:ty),* ) => {hlist_type_internal!($hlist, $crate::HNil, $($types,)*);}
}

macro_rules! generate_hlist_contains {
    
    ($hlist:ty) => {{}};
    ($hlist:ty,) => {{}};
    
    ($hlist:ty, $last:ty, $($init:ty,)*) => {{
    
        impl $crate::Contains<$last> for $hlist {
        
            #[allow(unused_variables)]
            fn get(&self) -> &$last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head; // Only used to refer to $init 
                    let cur_cell = &cur_cell.tail;
                )*
                &cur_cell.head
            }
            
            #[allow(unused_variables)]
            fn get_mut(&mut self) -> &mut $last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head;
                    let cur_cell = &mut cur_cell.tail;
                )*
                &mut cur_cell.head
            }
        }
        
        generate_hlist_contains!($hlist, $($init,)*);
    }}
}

/// Test comment
#[macro_export]
macro_rules! generate_contains_impls {
    ($($types:ty),*) => {{
        hlist_type!(TheHList, $($types),*); 
        generate_hlist_contains!(TheHList, $($types,)*);
    }}
}

pub trait HList: Sized {
    fn insert<A: Sized>(self, a: A) -> HCons<A, Self> {
        HCons { head: a, tail: self }
    }
}


 
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}

#[test]
fn empty_hlist_type() {
    hlist_type!(Empty);
    let empty: Empty = HNil;
    drop(empty);
}
{'fraction_non_alphanumeric': 0.1738519212746017, 'fraction_numerical': 0.0, 'mean_word_length': 2.0084566596194504, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2295098', 'n_tokens_mistral': 1576, 'n_tokens_neox': 1529, 'n_words': 293}