@@ -991,6 +991,12 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
991991 }
992992 } ) . collect :: < Vec < _ > > ( ) ;
993993
994+ // Helper identifiers for `extend_from_self` local variables.
995+ let len_idents = & names. iter ( ) . map ( |n| syn:: Ident :: new ( & format ! ( "len_{}" , n) , n. span ( ) ) ) . collect :: < Vec < _ > > ( ) ;
996+ let count_idents = & names. iter ( ) . map ( |n| syn:: Ident :: new ( & format ! ( "count_{}" , n) , n. span ( ) ) ) . collect :: < Vec < _ > > ( ) ;
997+ let start_idents = & names. iter ( ) . map ( |n| syn:: Ident :: new ( & format ! ( "start_{}" , n) , n. span ( ) ) ) . collect :: < Vec < _ > > ( ) ;
998+ let variant_indices = & ( 0 ..variants. len ( ) ) . map ( |i| i as u8 ) . collect :: < Vec < _ > > ( ) ;
999+
9941000 quote ! {
9951001 impl #impl_gen :: columnar:: Columnar for #name #ty_gen #where_clause2 {
9961002 #[ inline( always) ]
@@ -1034,8 +1040,33 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
10341040 }
10351041 }
10361042
1037- impl < #( #container_names : :: columnar:: Container ) , * > :: columnar:: Container for #c_ident < #( #container_names) , * > {
1038- // TODO: implement `extend_from_self`.
1043+ impl < #( #container_names : :: columnar:: Container + :: columnar:: Len ) , * > :: columnar:: Container for #c_ident < #( #container_names) , * > {
1044+ #[ inline( always) ]
1045+ fn extend_from_self( & mut self , other: Self :: Borrowed <' _>, range: std:: ops:: Range <usize >) {
1046+ if !range. is_empty( ) {
1047+ #( let #len_idents = :: columnar:: Len :: len( & self . #names) ; ) *
1048+ #( let mut #count_idents = 0usize ; ) *
1049+ #( let mut #start_idents = 0u64 ; ) *
1050+ for index in range. clone( ) {
1051+ let ( variant, offset) = other. indexes. get( index) ;
1052+ match variant {
1053+ #(
1054+ #variant_indices => {
1055+ if #count_idents == 0 { #start_idents = offset; }
1056+ self . indexes. push( #variant_indices, ( #len_idents + #count_idents) as u64 ) ;
1057+ #count_idents += 1 ;
1058+ }
1059+ ) *
1060+ _ => unreachable!( ) ,
1061+ }
1062+ }
1063+ #(
1064+ if #count_idents > 0 {
1065+ self . #names. extend_from_self( other. #names, #start_idents as usize .. #start_idents as usize + #count_idents) ;
1066+ }
1067+ ) *
1068+ }
1069+ }
10391070
10401071 fn reserve_for<' a, I >( & mut self , selves: I ) where Self : ' a, I : Iterator <Item = Self :: Borrowed <' a>> + Clone {
10411072 #( self . #names. reserve_for( selves. clone( ) . map( |x| x. #names) ) ; ) *
@@ -1227,7 +1258,10 @@ fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::Da
12271258 }
12281259
12291260 impl <CV : :: columnar:: common:: PushIndexAs <u8 >> :: columnar:: Container for #c_ident <CV > {
1230- // TODO: implement `extend_from_self`.
1261+ #[ inline( always) ]
1262+ fn extend_from_self( & mut self , other: Self :: Borrowed <' _>, range: std:: ops:: Range <usize >) {
1263+ self . variant. extend_from_self( other. variant, range) ;
1264+ }
12311265
12321266 fn reserve_for<' a, I >( & mut self , selves: I ) where Self : ' a, I : Iterator <Item = Self :: Borrowed <' a>> + Clone {
12331267 self . variant. reserve_for( selves. map( |x| x. variant) ) ;
0 commit comments