1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{parse_macro_input, Attribute, DeriveInput};
6
7#[proc_macro_derive(Columnar, attributes(columnar))]
8pub fn derive(input: TokenStream) -> TokenStream {
9
10 let ast = parse_macro_input!(input as DeriveInput);
11 let name = &ast.ident;
12
13 let attr = extract_attr(&ast.attrs);
14
15 match ast.data {
16 syn::Data::Struct(data_struct) => {
17 match data_struct.fields {
18 syn::Fields::Unit => derive_unit_struct(name, &ast.generics, ast.vis, attr),
19 _ => derive_struct(name, &ast.generics, data_struct, ast.vis, attr),
20 }
21 }
22 syn::Data::Enum(data_enum) => {
23 derive_enum(name, &ast.generics, data_enum, ast.vis, attr)
24 }
25 syn::Data::Union(_) => unimplemented!("Unions are unsupported by Columnar"),
26 }
27}
28
29fn extract_attr(attrs: &[Attribute]) -> Option<proc_macro2::TokenStream> {
30 for attr in attrs {
31 if attr.path().is_ident("columnar") {
32 return Some(attr.parse_args().unwrap());
33 }
34 }
35 None
36}
37
38fn derive_struct(name: &syn::Ident, generics: &syn::Generics, data_struct: syn::DataStruct, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
39
40 let c_name = format!("{}Container", name);
41 let c_ident = syn::Ident::new(&c_name, name.span());
42
43 let r_name = format!("{}Reference", name);
44 let r_ident = syn::Ident::new(&r_name, name.span());
45
46 let named = match &data_struct.fields {
47 syn::Fields::Named(_) => true,
48 syn::Fields::Unnamed(_) => false,
49 _ => unimplemented!(),
50 };
51
52 let names: &Vec<_> = &match &data_struct.fields {
53 syn::Fields::Named(fields) => fields.named.iter().map(|field| field.ident.clone().unwrap()).collect(),
54 syn::Fields::Unnamed(fields) => (0 .. fields.unnamed.len()).map(|index| syn::Ident::new(&format!("f{}", index), name.span())).collect(),
55 _ => unimplemented!(),
56 };
57
58 let types: &Vec<_> = &match &data_struct.fields {
59 syn::Fields::Named(fields) => fields.named.iter().map(|field| &field.ty).collect(),
60 syn::Fields::Unnamed(fields) => fields.unnamed.iter().map(|field| &field.ty).collect(),
61 _ => unimplemented!(),
62 };
63
64 let container_types = &names.iter().enumerate().map(|(index, name)| {
66 let new_name = format!("C{}", index);
67 syn::Ident::new(&new_name, name.span())
68 }).collect::<Vec<_>>();
69
70 #[cfg(feature = "serde")]
72 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
73 #[cfg(not(feature = "serde"))]
74 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
75
76 let container_struct = {
77 quote! {
78 #derive
80 #vis struct #c_ident < #(#container_types),* >{
81 #(
82 pub #names : #container_types,
84 )*
85 }
86 }
87 };
88
89 let reference_struct = {
90
91 let reference_types = &names.iter().enumerate().map(|(index, name)| {
92 let new_name = format!("R{}", index);
93 syn::Ident::new(&new_name, name.span())
94 }).collect::<Vec<_>>();
95
96 let ty_gen = quote! { < #(#reference_types),* > };
97
98 let attr = if let Some(attr) = attr {
99 quote! { #[#attr] }
100 } else {
101 quote! {}
102 };
103
104 quote! {
105 #[derive(Copy, Clone, Debug)]
107 #attr
108 #vis struct #r_ident #ty_gen {
109 #(
110 pub #names : #reference_types,
112 )*
113 }
114 }
115 };
116
117 let partial_eq = {
118
119 let reference_types = &names.iter().enumerate().map(|(index, name)| {
120 let new_name = format!("R{}", index);
121 syn::Ident::new(&new_name, name.span())
122 }).collect::<Vec<_>>();
123
124 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
125
126 let struct_generics = generics.params.iter();
127 let impl_gen = quote! { < #(#struct_generics,)* #(#reference_types),* > };
128
129 let where_clause = quote! { where #(#reference_types: PartialEq<#types>),* };
130
131 let destructure_self =
133 if named { quote! { let #name { #(#names),* } = other; } }
134 else { quote! { let #name ( #(#names),* ) = other; } };
135
136 quote! {
137 impl #impl_gen PartialEq<#name #ty_gen> for #r_ident < #(#reference_types),* > #where_clause {
138 #[inline(always)]
139 fn eq(&self, other: &#name #ty_gen) -> bool {
140 #destructure_self
141 #(self.#names == *#names) &&*
142 }
143 }
144 }
145
146 };
147
148 let push_own = {
149 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
150 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
151
152 let struct_generics = generics.params.iter();
153 let impl_gen = quote! { < #(#struct_generics,)* #(#container_types),* > };
154
155 let where_clause2 = quote! { where #(#container_types: ::columnar::Push<#types>),* };
156
157 let destructure_self =
159 if named { quote! { let #name { #(#names),* } = item; } }
160 else { quote! { let #name ( #(#names),* ) = item; } };
161
162 quote! {
163 impl #impl_gen ::columnar::Push<#name #ty_gen> for #c_ident < #(#container_types),* > #where_clause2 {
164 #[inline]
165 fn push(&mut self, item: #name #ty_gen) {
166 #destructure_self
167 #(#push)*
168 }
169 }
170 }
171 };
172
173 let push_ref = {
174 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
175 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
176
177 let struct_generics = generics.params.iter();
178 let impl_gen = quote! { < 'columnar, #(#struct_generics,)* #(#container_types),* > };
179
180 let where_clause2 = quote! { where #(#container_types: ::columnar::Push<&'columnar #types>),* };
181
182 let destructure_self =
183 if named { quote! { let #name { #(#names),* } = item; } }
184 else { quote! { let #name ( #(#names),* ) = item; } };
185
186 quote! {
187 impl #impl_gen ::columnar::Push<&'columnar #name #ty_gen> for #c_ident < #(#container_types),* > #where_clause2 {
188 #[inline]
189 fn push(&mut self, item: &'columnar #name #ty_gen) {
190 #destructure_self
191 #(#push)*
192 }
193 }
194 }
195 };
196
197 let push_new = {
199
200 let reference_types = &names.iter().enumerate().map(|(index, name)| {
201 let new_name = format!("R{}", index);
202 syn::Ident::new(&new_name, name.span())
203 }).collect::<Vec<_>>();
204
205 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
206
207 let impl_gen = quote! { < #(#container_types,)* #(#reference_types),* > };
208
209 let where_clause = quote! { where #(#container_types: ::columnar::Push<#reference_types>),* };
210
211 let index_type = quote! { #r_ident < #(#reference_types,)* > };
212 let destructure_self = quote! { let #r_ident { #(#names),* } = item; };
213
214 quote! {
215 impl #impl_gen ::columnar::Push<#index_type> for #c_ident < #(#container_types),* > #where_clause {
216 #[inline]
217 fn push(&mut self, item: #index_type) {
218 #destructure_self
219 #(#push)*
220 }
221 }
222 }
223 };
224
225 let index_own = {
226 let impl_gen = quote! { < #(#container_types),* > };
227 let ty_gen = quote! { < #(#container_types),* > };
228 let where_clause = quote! { where #(#container_types: ::columnar::Index),* };
229
230 let index_type = quote! { #r_ident < #(<#container_types as ::columnar::Index>::Ref,)* > };
231
232 quote! {
233 impl #impl_gen ::columnar::Index for #c_ident #ty_gen #where_clause {
234 type Ref = #index_type;
235 #[inline(always)]
236 fn get(&self, index: usize) -> Self::Ref {
237 #r_ident { #(#names: self.#names.get(index),)* }
238 }
239 }
240 }
241 };
242
243 let index_ref = {
244 let impl_gen = quote! { < 'columnar, #(#container_types),* > };
245 let ty_gen = quote! { < #(#container_types),* > };
246 let where_clause = quote! { where #(&'columnar #container_types: ::columnar::Index),* };
247
248 let index_type = quote! { #r_ident < #(<&'columnar #container_types as ::columnar::Index>::Ref,)* > };
249
250 quote! {
251 impl #impl_gen ::columnar::Index for &'columnar #c_ident #ty_gen #where_clause {
252 type Ref = #index_type;
253 #[inline(always)]
254 fn get(&self, index: usize) -> Self::Ref {
255 #r_ident { #(#names: (&self.#names).get(index),)* }
256 }
257 }
258 }
259 };
260
261 let clear = {
262
263 let impl_gen = quote! { < #(#container_types),* > };
264 let ty_gen = quote! { < #(#container_types),* > };
265 let where_clause = quote! { where #(#container_types: ::columnar::Clear),* };
266
267 quote! {
268 impl #impl_gen ::columnar::Clear for #c_ident #ty_gen #where_clause {
269 #[inline(always)]
270 fn clear(&mut self) { #(self.#names.clear());* }
271 }
272 }
273 };
274
275 let length = {
276
277 let impl_gen = quote! { < #(#container_types),* > };
278 let ty_gen = quote! { < #(#container_types),* > };
279 let where_clause = quote! { where #(#container_types: ::columnar::Len),* };
280
281 let first_name = &names[0];
282
283 quote! {
284 impl #impl_gen ::columnar::Len for #c_ident #ty_gen #where_clause {
285 #[inline(always)]
286 fn len(&self) -> usize {
287 self.#first_name.len()
288 }
289 }
290 }
291 };
292
293 let as_bytes = {
294
295 let impl_gen = quote! { <'a, #(#container_types),* > };
296 let ty_gen = quote! { < #(#container_types),* > };
297 let where_clause = quote! { where #(#container_types: ::columnar::AsBytes<'a>),* };
298
299 quote! {
300 impl #impl_gen ::columnar::AsBytes<'a> for #c_ident #ty_gen #where_clause {
301 #[inline(always)]
303 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
304 let iter = None.into_iter();
305 #( let iter = ::columnar::chain(iter, self.#names.as_bytes()); )*
306 iter
307 }
308 }
309 }
310 };
311
312 let from_bytes = {
313
314 let impl_gen = quote! { < 'columnar, #(#container_types),* > };
315 let ty_gen = quote! { < #(#container_types),* > };
316 let where_clause = quote! { where #(#container_types: ::columnar::FromBytes<'columnar>),* };
317
318 quote! {
319 impl #impl_gen ::columnar::FromBytes<'columnar> for #c_ident #ty_gen #where_clause {
320 const SLICE_COUNT: usize = 0 #(+ <#container_types>::SLICE_COUNT)*;
321 #[inline(always)]
322 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
323 Self { #(#names: ::columnar::FromBytes::from_bytes(bytes),)* }
324 }
325 #[inline(always)]
326 fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
327 Self { #(#names: ::columnar::FromBytes::from_store(store, offset),)* }
328 }
329 fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
330 #(<#container_types>::element_sizes(sizes)?;)*
331 Ok(())
332 }
333 }
334 }
335 };
336
337 let columnar_impl = {
338
339 let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
340
341 let where_clause2 = if let Some(struct_where) = where_clause {
342 let params = struct_where.predicates.iter();
343 quote! { where #(#types : ::columnar::Columnar,)* #(#params),* }
344 }
345 else {
346 quote! { where #(#types : ::columnar::Columnar,)* }
347 };
348
349 let destructure_self =
351 if named { quote! { let #name { #(#names),* } = self; } }
352 else { quote! { let #name ( #(#names),* ) = self; } };
353
354 let into_self =
356 if named { quote! { #name { #(#names: ::columnar::Columnar::into_owned(other.#names)),* } } }
357 else { quote! { #name ( #(::columnar::Columnar::into_owned(other.#names)),* ) } };
358
359 quote! {
360 impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
361 #[inline(always)]
362 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
363 #destructure_self
364 #( ::columnar::Columnar::copy_from(#names, other.#names); )*
365 }
366 #[inline(always)]
367 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
368 #into_self
369 }
370 type Container = #c_ident < #(<#types as ::columnar::Columnar>::Container ),* >;
371 }
372
373 impl < #( #container_types: ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #( #container_types ),* > {
374 type Ref<'a> = #r_ident < #(<#container_types as ::columnar::Borrow>::Ref<'a>,)* > where #(#container_types: 'a,)*;
375 type Borrowed<'a> = #c_ident < #(<#container_types as ::columnar::Borrow>::Borrowed<'a> ),* > where #(#container_types: 'a,)*;
376 #[inline(always)]
377 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
378 #c_ident {
379 #( #names: <#container_types as ::columnar::Borrow>::borrow(&self.#names), )*
380 }
381 }
382 #[inline(always)]
383 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
384 #c_ident {
385 #( #names: <#container_types as ::columnar::Borrow>::reborrow(thing.#names), )*
386 }
387 }
388 #[inline(always)]
389 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
390 #r_ident {
391 #( #names: <#container_types as ::columnar::Borrow>::reborrow_ref(thing.#names), )*
392 }
393 }
394 }
395
396 impl < #( #container_types: ::columnar::Container ),* > ::columnar::Container for #c_ident < #( #container_types ),* > {
397 #[inline(always)]
398 fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
399 #( self.#names.extend_from_self(other.#names, range.clone()); )*
400 }
401
402 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
403 #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
404 }
405 }
406 }
407 };
408
409
410 quote! {
411
412 #container_struct
413 #reference_struct
414
415 #partial_eq
416
417 #push_own
418 #push_ref
419 #push_new
420
421 #index_own
422 #index_ref
423 #length
424 #clear
425
426 #as_bytes
427 #from_bytes
428
429 #columnar_impl
430
431 }.into()
432}
433
434fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
436
437 let c_name = format!("{}Container", name);
438 let c_ident = syn::Ident::new(&c_name, name.span());
439
440 if attr.is_some() {
441 panic!("Unit structs do not support attributes");
442 }
443
444 #[cfg(feature = "serde")]
445 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
446 #[cfg(not(feature = "serde"))]
447 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
448
449 quote! {
450
451 #derive
453 #vis struct #c_ident<CW = u64> {
454 pub count: CW,
456 }
457
458 impl ::columnar::Push<#name> for #c_ident {
459 #[inline]
460 fn push(&mut self, _item: #name) {
461 self.count += 1;
462 }
463 }
464
465 impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
466 #[inline]
467 fn push(&mut self, _item: &'columnar #name) {
468 self.count += 1;
469 }
470 }
471
472 impl<CW> ::columnar::Index for #c_ident<CW> {
473 type Ref = #name;
474 #[inline(always)]
475 fn get(&self, index: usize) -> Self::Ref {
476 #name
477 }
478 }
479
480 impl<'columnar, CW> ::columnar::Index for &'columnar #c_ident<CW> {
481 type Ref = #name;
482 #[inline(always)]
483 fn get(&self, index: usize) -> Self::Ref {
484 #name
485 }
486 }
487
488 impl ::columnar::Clear for #c_ident {
489 #[inline(always)]
490 fn clear(&mut self) {
491 self.count = 0;
492 }
493 }
494
495 impl<CW: Copy+::columnar::common::index::CopyAs<u64>> ::columnar::Len for #c_ident<CW> {
496 #[inline(always)]
497 fn len(&self) -> usize {
498 use ::columnar::common::index::CopyAs;
499 self.count.copy_as() as usize
500 }
501 }
502
503 impl<'a> ::columnar::AsBytes<'a> for #c_ident <&'a u64> {
504 #[inline(always)]
506 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
507 ::core::iter::once((8, ::columnar::bytemuck::cast_slice(::core::slice::from_ref(self.count))))
508 }
509 }
510
511 impl<'columnar> ::columnar::FromBytes<'columnar> for #c_ident <&'columnar u64> {
512 const SLICE_COUNT: usize = 1;
513 #[inline(always)]
514 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
515 Self { count: &::columnar::bytemuck::try_cast_slice(bytes.next().unwrap()).unwrap()[0] }
516 }
517 #[inline(always)]
518 fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
519 let (w, _tail) = store.get(*offset);
520 *offset += 1;
521 Self { count: w.first().unwrap_or(&0) }
522 }
523 fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
524 sizes.push(8);
525 Ok(())
526 }
527 }
528
529 impl ::columnar::Columnar for #name {
530 #[inline(always)]
531 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
532 #[inline(always)]
533 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
534 type Container = #c_ident;
535 }
536
537 impl ::columnar::Borrow for #c_ident {
538 type Ref<'a> = #name;
539 type Borrowed<'a> = #c_ident < &'a u64 >;
540 #[inline(always)]
541 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
542 #c_ident { count: &self.count }
543 }
544 #[inline(always)]
545 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
546 #c_ident { count: thing.count }
547 }
548 #[inline(always)]
549 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
550 }
551
552 impl ::columnar::Container for #c_ident {
553 #[inline(always)]
554 fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
555 self.count += range.len() as u64;
556 }
557
558 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
559 }
560
561 }.into()
562}
563
564#[allow(unused)]
567fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
568
569 if data_enum.variants.iter().all(|variant| variant.fields.is_empty()) {
570 return derive_tags(name, generics, data_enum, vis);
571 }
572
573 let c_name = format!("{}Container", name);
574 let c_ident = syn::Ident::new(&c_name, name.span());
575
576 let r_name = format!("{}Reference", name);
577 let r_ident = syn::Ident::new(&r_name, name.span());
578
579 let variants: Vec<(&syn::Ident, Vec<_>)> =
581 data_enum
582 .variants
583 .iter()
584 .map(|variant| (
585 &variant.ident,
586 variant.fields.iter().map(|field| &field.ty).collect()
587 ))
588 .collect();
589
590 assert!(variants.len() <= 256, "Too many variants for enum");
592
593 let names = &variants.iter().map(|(ident, _)| ident).collect::<Vec<_>>();
594
595 let container_types = &names.iter().enumerate().map(|(index, name)| {
597 let new_name = format!("C{}", index);
598 syn::Ident::new(&new_name, name.span())
599 }).collect::<Vec<_>>();
600
601 #[cfg(feature = "serde")]
602 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
603 #[cfg(not(feature = "serde"))]
604 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
605
606 let container_struct = {
607 quote! {
608 #derive
610 #[allow(non_snake_case)]
611 #vis struct #c_ident < #(#container_types,)* CVar = Vec<u8>, COff = Vec<u64>, >{
612 #(
613 pub #names : #container_types,
615 )*
616 pub indexes: ::columnar::Discriminant<CVar, COff>,
618 }
619 }
620 };
621
622 let reference_struct = {
623
624 let reference_types = &names.iter().enumerate().map(|(index, name)| {
625 let new_name = format!("R{}", index);
626 syn::Ident::new(&new_name, name.span())
627 }).collect::<Vec<_>>();
628
629 let ty_gen = quote! { < #(#reference_types),* > };
630
631 let attr = if let Some(attr) = attr {
632 quote! { #[#attr] }
633 } else {
634 quote! {}
635 };
636
637
638 quote! {
639 #[derive(Copy, Clone, Debug)]
641 #attr
642 #vis enum #r_ident #ty_gen {
643 #(
644 #names(#reference_types),
646 )*
647 }
648 }
649 };
650
651 let push_own = {
652
653 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
654
655 let push = variants.iter().enumerate().map(|(index, (variant, types))| {
656
657 match &data_enum.variants[index].fields {
658 syn::Fields::Unit => {
659 quote! {
660 #name::#variant => {
661 self.indexes.push(#index as u8, self.#variant.len() as u64);
662 self.#variant.push(());
663 }
664 }
665 }
666 syn::Fields::Unnamed(_) => {
667 let temp_names = &types.iter().enumerate().map(|(index, _)| {
668 let new_name = format!("t{}", index);
669 syn::Ident::new(&new_name, variant.span())
670 }).collect::<Vec<_>>();
671
672 quote! {
673 #name::#variant( #(#temp_names),* ) => {
674 self.indexes.push(#index as u8, self.#variant.len() as u64);
675 self.#variant.push((#(#temp_names),*));
676 },
677 }
678 }
679 syn::Fields::Named(fields) => {
680 let field_names = &fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect::<Vec<_>>();
681
682 quote! {
683 #name::#variant { #(#field_names),* } => {
684 self.indexes.push(#index as u8, self.#variant.len() as u64);
685 self.#variant.push((#(#field_names),*));
686 },
687 }
688 }
689 }
690 });
691
692 let struct_generics = generics.params.iter();
693 let impl_gen = quote! { < #(#struct_generics,)* #(#container_types),* > };
694
695 let push_types = variants.iter().map(|(_, types)| quote! { (#(#types),*) });
696
697 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
698
699 quote! {
700 impl #impl_gen ::columnar::Push<#name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
701 #[inline]
702 fn push(&mut self, item: #name #ty_gen) {
703 match item {
704 #( #push )*
705 }
706 }
707 }
708 }
709 };
710
711 let push_ref = {
712
713 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
714
715 let push = variants.iter().enumerate().map(|(index, (variant, types))| {
716
717 match &data_enum.variants[index].fields {
718 syn::Fields::Unit => {
719 quote! {
720 #name::#variant => {
721 self.indexes.push(#index as u8, self.#variant.len() as u64);
722 self.#variant.push(());
723 }
724 }
725 }
726 syn::Fields::Unnamed(_) => {
727 let temp_names = &types.iter().enumerate().map(|(index, _)| {
728 let new_name = format!("t{}", index);
729 syn::Ident::new(&new_name, variant.span())
730 }).collect::<Vec<_>>();
731
732 quote! {
733 #name::#variant( #(#temp_names),* ) => {
734 self.indexes.push(#index as u8, self.#variant.len() as u64);
735 self.#variant.push((#(#temp_names),*));
736 },
737 }
738 }
739 syn::Fields::Named(fields) => {
740 let field_names = &fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect::<Vec<_>>();
741
742 quote! {
743 #name::#variant { #(#field_names),* } => {
744 self.indexes.push(#index as u8, self.#variant.len() as u64);
745 self.#variant.push((#(#field_names),*));
746 },
747 }
748 }
749 }
750 });
751
752 let struct_generics = generics.params.iter();
753 let impl_gen = quote! { < 'columnar, #(#struct_generics,)* #(#container_types),* > };
754
755 let push_types = variants.iter().map(|(_, types)| quote! { (#(&'columnar #types),*) });
756
757 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
758
759 quote! {
760 impl #impl_gen ::columnar::Push<&'columnar #name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
761 #[inline]
762 fn push(&mut self, item: &'columnar #name #ty_gen) {
763 match item {
764 #( #push )*
765 }
766 }
767 }
768 }
769 };
770
771 let push_new = {
773
774 let reference_types = &names.iter().enumerate().map(|(index, name)| {
775 let new_name = format!("R{}", index);
776 syn::Ident::new(&new_name, name.span())
777 }).collect::<Vec<_>>();
778
779 let impl_gen = quote! { < #(#container_types,)* #(#reference_types),* > };
780
781 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#reference_types>),* };
782
783 let index_type = quote! { #r_ident < #(#reference_types,)* > };
784 let numbers = (0 .. variants.len());
785
786 quote! {
787 impl #impl_gen ::columnar::Push<#index_type> for #c_ident < #(#container_types),* > #where_clause {
788 #[inline]
789 fn push(&mut self, item: #index_type) {
790 match item {
791 #(
792 #r_ident::#names(x) => {
793 self.indexes.push(#numbers as u8, self.#names.len() as u64);
794 self.#names.push(x);
795 },
796 )*
797 }
798 }
799 }
800 }
801 };
802
803 let index_own = {
804 let impl_gen = quote! { < #(#container_types,)* CVar, COff> };
805 let ty_gen = quote! { < #(#container_types,)* CVar, COff> };
806 let where_clause = quote! { where #(#container_types: ::columnar::Index,)* CVar: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64> };
807
808 let index_type = quote! { #r_ident < #(<#container_types as ::columnar::Index>::Ref,)* > };
809
810 let numbers = (0 .. variants.len());
812
813 quote! {
814 impl #impl_gen ::columnar::Index for #c_ident #ty_gen #where_clause {
815 type Ref = #index_type;
816 #[inline(always)]
817 fn get(&self, index: usize) -> Self::Ref {
818 let (variant, offset) = self.indexes.get(index);
819 match variant as usize {
820 #( #numbers => #r_ident::#names(self.#names.get(offset as usize)), )*
821 x => panic!("Unacceptable discriminant found: {:?}", x),
822 }
823 }
824 }
825 }
826 };
827
828 let index_ref = {
829 let impl_gen = quote! { < 'columnar, #(#container_types,)* CVar, COff> };
830 let ty_gen = quote! { < #(#container_types,)* CVar, COff> };
831 let where_clause = quote! { where #(&'columnar #container_types: ::columnar::Index,)* CVar: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64> };
832
833 let index_type = quote! { #r_ident < #(<&'columnar #container_types as ::columnar::Index>::Ref,)* > };
834
835 let numbers = (0 .. variants.len());
837
838 quote! {
839 impl #impl_gen ::columnar::Index for &'columnar #c_ident #ty_gen #where_clause {
840 type Ref = #index_type;
841 #[inline(always)]
842 fn get(&self, index: usize) -> Self::Ref {
843 let (variant, offset) = self.indexes.get(index);
844 match variant as usize {
845 #( #numbers => #r_ident::#names((&self.#names).get(offset as usize)), )*
846 x => panic!("Unacceptable discriminant found: {:?}", x),
847 }
848 }
849 }
850 }
851 };
852
853 let clear = {
854
855 let impl_gen = quote! { < #(#container_types),* > };
856 let ty_gen = quote! { < #(#container_types),* > };
857 let where_clause = quote! { where #(#container_types: ::columnar::Clear),* };
858
859 quote! {
860 impl #impl_gen ::columnar::Clear for #c_ident #ty_gen #where_clause {
861 #[inline(always)]
862 fn clear(&mut self) {
863 #(self.#names.clear();)*
864 self.indexes.clear();
865 }
866 }
867 }
868 };
869
870 let length = {
871
872 let impl_gen = quote! { < #(#container_types,)* CVar, COff> };
873 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
874
875 quote! {
876 impl #impl_gen ::columnar::Len for #c_ident #ty_gen where CVar: ::columnar::Len, COff: ::columnar::Len + ::columnar::IndexAs<u64> {
877 #[inline(always)]
878 fn len(&self) -> usize {
879 self.indexes.len()
880 }
881 }
882 }
883 };
884
885 let as_bytes = {
886
887 let impl_gen = quote! { < 'a, #(#container_types,)* CVar, COff> };
888 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
889 let where_clause = quote! { where #(#container_types: ::columnar::AsBytes<'a>,)* ::columnar::Discriminant<CVar, COff>: ::columnar::AsBytes<'a> };
890
891 quote! {
892 impl #impl_gen ::columnar::AsBytes<'a> for #c_ident #ty_gen #where_clause {
893 #[inline(always)]
894 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
895 let iter = None.into_iter();
896 #( let iter = ::columnar::chain(iter,self.#names.as_bytes()); )*
897 let iter = ::columnar::chain(iter, self.indexes.as_bytes());
898 iter
899 }
900 }
901 }
902 };
903
904 let from_bytes = {
905
906 let impl_gen = quote! { < 'columnar, #(#container_types,)* CVar, COff> };
907 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
908 let where_clause = quote! { where #(#container_types: ::columnar::FromBytes<'columnar>,)* ::columnar::Discriminant<CVar, COff>: ::columnar::FromBytes<'columnar> };
909
910 quote! {
911 #[allow(non_snake_case)]
912 impl #impl_gen ::columnar::FromBytes<'columnar> for #c_ident #ty_gen #where_clause {
913 const SLICE_COUNT: usize = 0 #(+ <#container_types>::SLICE_COUNT)* + <::columnar::Discriminant<CVar, COff>>::SLICE_COUNT;
914 #[inline(always)]
915 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
916 Self {
917 #(#names: ::columnar::FromBytes::from_bytes(bytes),)*
918 indexes: ::columnar::FromBytes::from_bytes(bytes),
919 }
920 }
921 #[inline(always)]
922 fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
923 Self {
924 #(#names: ::columnar::FromBytes::from_store(store, offset),)*
925 indexes: ::columnar::FromBytes::from_store(store, offset),
926 }
927 }
928 fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
929 #(<#container_types>::element_sizes(sizes)?;)*
930 <::columnar::Discriminant<CVar, COff>>::element_sizes(sizes)?;
931 Ok(())
932 }
933 }
934 }
935 };
936
937 let columnar_impl = {
938
939 let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
940
941 let types = &variants.iter().flat_map(|(_, types)| types).collect::<Vec<_>>();
942
943 let where_clause2 = if let Some(enum_where) = where_clause {
944 let params = enum_where.predicates.iter();
945 quote! { where #(#types : ::columnar::Columnar,)* #(#params),* }
946 }
947 else {
948 quote! { where #(#types : ::columnar::Columnar,)* }
949 };
950
951
952 let variant_types = &variants.iter().map(|(_, types)| quote! { (#(#types),*) }).collect::<Vec<_>>();
953
954 let container_types = &variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Container }).collect::<Vec<_>>();
955 let container_names = &names.iter().enumerate().map(|(index, name)| {
957 let new_name = format!("C{}", index);
958 syn::Ident::new(&new_name, name.span())
959 }).collect::<Vec<_>>();
960
961 let reference_args = variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Ref<'a> });
962 let reference_args2 = reference_args.clone();
963
964 let copy_from = variants.iter().enumerate().map(|(index, (variant, types))| {
966
967 if data_enum.variants[index].fields == syn::Fields::Unit {
968 quote! {
969 (#name::#variant, #r_ident::#variant(_)) => { }
970 (_, #r_ident::#variant(_)) => { *self = #name::#variant; }
971 }
972 }
973 else {
974 let temp_names1 = &types.iter().enumerate().map(|(index, _)| {
975 let new_name = format!("s{}", index);
976 syn::Ident::new(&new_name, variant.span())
977 }).collect::<Vec<_>>();
978 let temp_names2 = &types.iter().enumerate().map(|(index, _)| {
979 let new_name = format!("t{}", index);
980 syn::Ident::new(&new_name, variant.span())
981 }).collect::<Vec<_>>();
982
983 let destructure = match &data_enum.variants[index].fields {
984 syn::Fields::Named(fields) => {
985 let field_names: Vec<_> = fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect();
986 quote! { #name::#variant { #(#field_names: #temp_names1),* } }
987 }
988 _ => quote! { #name::#variant( #(#temp_names1),* ) }
989 };
990
991 quote! {
992 (#destructure, #r_ident::#variant( ( #( #temp_names2 ),* ) )) => {
993 #( ::columnar::Columnar::copy_from(#temp_names1, #temp_names2); )*
994 }
995 }
996 }
997 }).collect::<Vec<_>>();
998
999 let into_owned = variants.iter().enumerate().map(|(index, (variant, types))| {
1001
1002 if data_enum.variants[index].fields == syn::Fields::Unit {
1003 quote! { #r_ident::#variant(_) => #name::#variant, }
1004 }
1005 else {
1006 let temp_names = &types.iter().enumerate().map(|(index, _)| {
1007 let new_name = format!("t{}", index);
1008 syn::Ident::new(&new_name, variant.span())
1009 }).collect::<Vec<_>>();
1010
1011 let reconstruct = match &data_enum.variants[index].fields {
1012 syn::Fields::Named(fields) => {
1013 let field_names: Vec<_> = fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect();
1014 quote! { #name::#variant { #(#field_names: ::columnar::Columnar::into_owned(#temp_names)),* } }
1015 }
1016 _ => quote! { #name::#variant( #( ::columnar::Columnar::into_owned(#temp_names) ),* ) }
1017 };
1018
1019 quote! {
1020 #r_ident::#variant(( #( #temp_names ),* )) => {
1021 #reconstruct
1022 },
1023 }
1024 }
1025 }).collect::<Vec<_>>();
1026
1027 let reborrow_ref = variants.iter().enumerate().zip(container_names.iter()).map(|((index, (variant, types)), cname)| {
1029 quote! {
1030 #r_ident::#variant(( potato )) => {
1031 #r_ident::#variant(( < (#cname) as ::columnar::Borrow >::reborrow_ref::<'b, 'a>( potato ) ))
1032 },
1033 }
1034 }).collect::<Vec<_>>();
1035
1036 let len_idents = &names.iter().map(|n| syn::Ident::new(&format!("len_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1038 let count_idents = &names.iter().map(|n| syn::Ident::new(&format!("count_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1039 let start_idents = &names.iter().map(|n| syn::Ident::new(&format!("start_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1040 let variant_indices = &(0..variants.len()).map(|i| i as u8).collect::<Vec<_>>();
1041
1042 quote! {
1043 impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
1044 #[inline(always)]
1045 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
1046 match (&mut *self, other) {
1047 #( #copy_from )*
1048 (_, other) => { *self = Self::into_owned(other); }
1049 }
1050 }
1051 #[inline(always)]
1052 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
1053 match other {
1054 #( #into_owned )*
1055 }
1056 }
1057 type Container = #c_ident < #(#container_types),* >;
1058 }
1059
1060 impl < #(#container_names : ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #(#container_names),* > {
1061 type Ref<'a> = #r_ident < #( <#container_names as ::columnar::Borrow>::Ref<'a> ,)* > where Self: 'a, #(#container_names: 'a,)*;
1062 type Borrowed<'a> = #c_ident < #( < #container_names as ::columnar::Borrow >::Borrowed<'a>, )* &'a [u8], &'a [u64] > where #(#container_names: 'a,)*;
1063 #[inline(always)]
1064 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1065 #c_ident {
1066 #(#names: self.#names.borrow(),)*
1067 indexes: self.indexes.borrow(),
1068 }
1069 }
1070 #[inline(always)]
1071 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1072 #c_ident {
1073 #(#names: <#container_names as ::columnar::Borrow>::reborrow(thing.#names),)*
1074 indexes: <::columnar::Discriminant as ::columnar::Borrow>::reborrow(thing.indexes),
1075 }
1076 }
1077 #[inline(always)]
1078 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
1079 match thing {
1080 #( #reborrow_ref )*
1081 }
1082 }
1083 }
1084
1085 impl < #(#container_names : ::columnar::Container + ::columnar::Len),* > ::columnar::Container for #c_ident < #(#container_names),* > {
1086 #[inline(always)]
1087 fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
1088 if !range.is_empty() {
1089 #( let #len_idents = ::columnar::Len::len(&self.#names); )*
1090 #( let mut #count_idents = 0usize; )*
1091 #( let mut #start_idents = 0u64; )*
1092 for index in range.clone() {
1093 let (variant, offset) = other.indexes.get(index);
1094 match variant {
1095 #(
1096 #variant_indices => {
1097 if #count_idents == 0 { #start_idents = offset; }
1098 self.indexes.push(#variant_indices, (#len_idents + #count_idents) as u64);
1099 #count_idents += 1;
1100 }
1101 )*
1102 _ => unreachable!(),
1103 }
1104 }
1105 #(
1106 if #count_idents > 0 {
1107 self.#names.extend_from_self(other.#names, #start_idents as usize .. #start_idents as usize + #count_idents);
1108 }
1109 )*
1110 }
1111 }
1112
1113 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1114 #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
1115 self.indexes.reserve_for(selves.map(|x| x.indexes));
1116 }
1117 }
1118 }
1119 };
1120
1121 let try_unwrap = {
1122 let impl_gen = quote! { < #(#container_types),* > };
1123 let ty_gen = quote! { < #(#container_types),* > };
1124
1125 let numbers = (0u8 ..);
1126 let methods = names.iter().zip(container_types.iter()).zip(numbers).map(|((name, ctype), index)| {
1127 let try_name = syn::Ident::new(&format!("try_unwrap_{}", name), name.span());
1128 quote! {
1129 #[inline]
1131 pub fn #try_name(&self) -> Option<&#ctype> {
1132 if self.indexes.homogeneous() == Some(#index) { Some(&self.#name) } else { None }
1133 }
1134 }
1135 });
1136
1137 quote! {
1138 #[allow(non_snake_case)]
1139 impl #impl_gen #c_ident #ty_gen {
1140 #( #methods )*
1141 }
1142 }
1143 };
1144
1145 quote! {
1146
1147 #container_struct
1148 #reference_struct
1149
1150 #push_own
1151 #push_ref
1152 #push_new
1153
1154 #index_own
1155 #index_ref
1156 #length
1157 #clear
1158
1159 #as_bytes
1160 #from_bytes
1161
1162 #columnar_impl
1163
1164 #try_unwrap
1165
1166 }.into()
1167}
1168
1169#[allow(unused)]
1171fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility) -> proc_macro::TokenStream {
1172
1173 let c_name = format!("{}Container", name);
1174 let c_ident = syn::Ident::new(&c_name, name.span());
1175
1176 let names: Vec<&syn::Ident> =
1177 data_enum
1178 .variants
1179 .iter()
1180 .map(|variant| &variant.ident)
1181 .collect();
1182
1183 let indices: &Vec<u8> = &(0 .. names.len()).map(|x| x as u8).collect();
1184
1185 assert!(names.len() <= 256, "Too many variants for enum");
1187
1188 #[cfg(feature = "serde")]
1189 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
1190 #[cfg(not(feature = "serde"))]
1191 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
1192
1193 quote! {
1194 #derive
1196 #vis struct #c_ident <CVar = Vec<u8>> {
1197 pub variant: CVar,
1199 }
1200
1201 impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Push<#name> for #c_ident<CV> {
1202 #[inline]
1203 fn push(&mut self, item: #name) {
1204 match item {
1205 #( #name::#names => self.variant.push(&#indices), )*
1206 }
1207 }
1208 }
1209
1210 impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
1211 #[inline]
1212 fn push(&mut self, item: &'columnar #name) {
1213 match *item {
1214 #( #name::#names => self.variant.push(#indices), )*
1215 }
1216 }
1217 }
1218
1219 impl<CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for #c_ident <CVar> {
1220 type Ref = #name;
1221 #[inline(always)]
1222 fn get(&self, index: usize) -> Self::Ref {
1223 match self.variant.index_as(index) {
1224 #( #indices => #name::#names, )*
1225 x => panic!("Unacceptable discriminant found: {:?}", x),
1226 }
1227 }
1228 }
1229
1230 impl<'columnar, CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for &'columnar #c_ident <CVar> {
1231 type Ref = #name;
1232 #[inline(always)]
1233 fn get(&self, index: usize) -> Self::Ref {
1234 match self.variant.index_as(index) {
1235 #( #indices => #name::#names, )*
1236 x => panic!("Unacceptable discriminant found: {:?}", x),
1237 }
1238 }
1239 }
1240
1241 impl<CVar: ::columnar::Clear> ::columnar::Clear for #c_ident <CVar> {
1242 #[inline(always)]
1243 fn clear(&mut self) {
1244 self.variant.clear();
1245 }
1246 }
1247
1248 impl<CVar: ::columnar::Len> ::columnar::Len for #c_ident <CVar> {
1249 #[inline(always)]
1250 fn len(&self) -> usize {
1251 self.variant.len()
1252 }
1253 }
1254
1255 impl<'a, CVar: ::columnar::AsBytes<'a>> ::columnar::AsBytes<'a> for #c_ident <CVar> {
1256 #[inline(always)]
1258 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
1259 self.variant.as_bytes()
1260 }
1261 }
1262
1263 impl<'columnar, CVar: ::columnar::FromBytes<'columnar>> ::columnar::FromBytes<'columnar> for #c_ident <CVar> {
1264 const SLICE_COUNT: usize = CVar::SLICE_COUNT;
1265 #[inline(always)]
1266 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
1267 Self { variant: ::columnar::FromBytes::from_bytes(bytes) }
1268 }
1269 #[inline(always)]
1270 fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
1271 Self { variant: ::columnar::FromBytes::from_store(store, offset) }
1272 }
1273 fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
1274 CVar::element_sizes(sizes)
1275 }
1276 }
1277
1278 impl ::columnar::Columnar for #name {
1279 #[inline(always)]
1280 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
1281 #[inline(always)]
1282 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
1283 type Container = #c_ident;
1284 }
1285
1286 impl<CV: ::columnar::common::BorrowIndexAs<u8>> ::columnar::Borrow for #c_ident <CV> {
1287 type Ref<'a> = #name;
1288 type Borrowed<'a> = #c_ident < CV::Borrowed<'a> > where CV: 'a;
1289 #[inline(always)]
1290 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1291 #c_ident {
1292 variant: self.variant.borrow()
1293 }
1294 }
1295 #[inline(always)]
1296 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1297 #c_ident {
1298 variant: <CV as ::columnar::Borrow>::reborrow(thing.variant),
1299 }
1300 }
1301 #[inline(always)]
1302 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
1303 }
1304
1305 impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Container for #c_ident <CV> {
1306 #[inline(always)]
1307 fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
1308 self.variant.extend_from_self(other.variant, range);
1309 }
1310
1311 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1312 self.variant.reserve_for(selves.map(|x| x.variant));
1313 }
1314 }
1315 }.into()
1316}