From 0d5f4a369bce2cecb70fa98b2c888add06854d33 Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 18 Sep 2020 11:05:43 +0200 Subject: [PATCH 1/5] More macro cleverness (1) avoid explicitly passing number of arguments --- src/tuple_impl.rs | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 8f14845df..2bf0d0ed7 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -244,11 +244,16 @@ pub trait TupleCollect: Sized { fn left_shift_push(&mut self, item: Self::Item); } +macro_rules! count_ident{ + () => {0}; + ($i0:ident, $($i:ident,)*) => {1 + count_ident!($($i,)*)}; +} + macro_rules! impl_tuple_collect { - ($N:expr; $A:ident ; $($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => ( + ($A:ident ; $($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => ( impl<$A> TupleCollect for ($($X),*,) { type Item = $A; - type Buffer = [Option<$A>; $N - 1]; + type Buffer = [Option<$A>; count_ident!($($Y,)*) - 1]; #[allow(unused_assignments, unused_mut)] fn collect_from_iter(iter: I, buf: &mut Self::Buffer) -> Option @@ -291,7 +296,7 @@ macro_rules! impl_tuple_collect { } fn num_items() -> usize { - $N + count_ident!($($Y,)*) } fn left_shift_push(&mut self, item: $A) { @@ -312,23 +317,22 @@ macro_rules! impl_tuple_collect { // use itertools::Itertools; // // for i in 1..=12 { -// println!("impl_tuple_collect!({arity}; A; {ty}; {idents}; {rev_idents});", -// arity=i, +// println!("impl_tuple_collect!(A; {ty}; {idents}; {rev_idents});", // ty=iter::repeat("A").take(i).join(", "), // idents=('a'..='z').take(i).join(", "), // rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ") // ); // } // It could probably be replaced by a bit more macro cleverness. -impl_tuple_collect!(1; A; A; a; a); -impl_tuple_collect!(2; A; A, A; a, b; b, a); -impl_tuple_collect!(3; A; A, A, A; a, b, c; c, b, a); -impl_tuple_collect!(4; A; A, A, A, A; a, b, c, d; d, c, b, a); -impl_tuple_collect!(5; A; A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); -impl_tuple_collect!(6; A; A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); -impl_tuple_collect!(7; A; A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); -impl_tuple_collect!(8; A; A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); -impl_tuple_collect!(9; A; A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(10; A; A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(11; A; A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(12; A; A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; A; a; a); +impl_tuple_collect!(A; A, A; a, b; b, a); +impl_tuple_collect!(A; A, A, A; a, b, c; c, b, a); +impl_tuple_collect!(A; A, A, A, A; a, b, c, d; d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); From 46527c12eca88f5024e693f98bcdfa32955237de Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 18 Sep 2020 11:05:43 +0200 Subject: [PATCH 2/5] More macro cleverness (2) avoid always-same parameter --- src/tuple_impl.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 2bf0d0ed7..a174565e2 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -250,14 +250,14 @@ macro_rules! count_ident{ } macro_rules! impl_tuple_collect { - ($A:ident ; $($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => ( - impl<$A> TupleCollect for ($($X),*,) { - type Item = $A; - type Buffer = [Option<$A>; count_ident!($($Y,)*) - 1]; + ($($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => ( + impl TupleCollect for ($($X),*,) { + type Item = A; + type Buffer = [Option; count_ident!($($Y,)*) - 1]; #[allow(unused_assignments, unused_mut)] fn collect_from_iter(iter: I, buf: &mut Self::Buffer) -> Option - where I: IntoIterator + where I: IntoIterator { let mut iter = iter.into_iter(); $( @@ -286,7 +286,7 @@ macro_rules! impl_tuple_collect { } fn collect_from_iter_no_buf(iter: I) -> Option - where I: IntoIterator + where I: IntoIterator { let mut iter = iter.into_iter(); @@ -299,7 +299,7 @@ macro_rules! impl_tuple_collect { count_ident!($($Y,)*) } - fn left_shift_push(&mut self, item: $A) { + fn left_shift_push(&mut self, item: A) { use std::mem::replace; let &mut ($(ref mut $Y),*,) = self; @@ -317,22 +317,22 @@ macro_rules! impl_tuple_collect { // use itertools::Itertools; // // for i in 1..=12 { -// println!("impl_tuple_collect!(A; {ty}; {idents}; {rev_idents});", +// println!("impl_tuple_collect!({ty}; {idents}; {rev_idents});", // ty=iter::repeat("A").take(i).join(", "), // idents=('a'..='z').take(i).join(", "), // rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ") // ); // } // It could probably be replaced by a bit more macro cleverness. -impl_tuple_collect!(A; A; a; a); -impl_tuple_collect!(A; A, A; a, b; b, a); -impl_tuple_collect!(A; A, A, A; a, b, c; c, b, a); -impl_tuple_collect!(A; A, A, A, A; a, b, c, d; d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A; A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A; a; a); +impl_tuple_collect!(A, A; a, b; b, a); +impl_tuple_collect!(A, A, A; a, b, c; c, b, a); +impl_tuple_collect!(A, A, A, A; a, b, c, d; d, c, b, a); +impl_tuple_collect!(A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); From 9a40b74438d46122f052e7c293aabd1a6b53fb34 Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 18 Sep 2020 11:05:43 +0200 Subject: [PATCH 3/5] More macro cleverness (3) avoid inferrable arguments --- src/tuple_impl.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index a174565e2..9a6e37bd8 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -248,10 +248,13 @@ macro_rules! count_ident{ () => {0}; ($i0:ident, $($i:ident,)*) => {1 + count_ident!($($i,)*)}; } +macro_rules! ignore_ident{ + ($id:ident, $($t:tt)*) => {$($t)*}; +} macro_rules! impl_tuple_collect { - ($($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => ( - impl TupleCollect for ($($X),*,) { + ($($Y:ident),* ; $($Y_rev:ident),*) => ( + impl TupleCollect for ($(ignore_ident!($Y, A),)*) { type Item = A; type Buffer = [Option; count_ident!($($Y,)*) - 1]; @@ -317,22 +320,21 @@ macro_rules! impl_tuple_collect { // use itertools::Itertools; // // for i in 1..=12 { -// println!("impl_tuple_collect!({ty}; {idents}; {rev_idents});", -// ty=iter::repeat("A").take(i).join(", "), +// println!("impl_tuple_collect!({idents}; {rev_idents});", // idents=('a'..='z').take(i).join(", "), // rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ") // ); // } // It could probably be replaced by a bit more macro cleverness. -impl_tuple_collect!(A; a; a); -impl_tuple_collect!(A, A; a, b; b, a); -impl_tuple_collect!(A, A, A; a, b, c; c, b, a); -impl_tuple_collect!(A, A, A, A; a, b, c, d; d, c, b, a); -impl_tuple_collect!(A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(a; a); +impl_tuple_collect!(a, b; b, a); +impl_tuple_collect!(a, b, c; c, b, a); +impl_tuple_collect!(a, b, c, d; d, c, b, a); +impl_tuple_collect!(a, b, c, d, e; e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f; f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g; g, f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); From de78fef12844bdb591066134d4edaafb19675bf1 Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 18 Sep 2020 11:05:43 +0200 Subject: [PATCH 4/5] More macro cleverness (4) avoid Y_rev --- src/tuple_impl.rs | 53 ++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 9a6e37bd8..3fe3f80ee 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -251,9 +251,16 @@ macro_rules! count_ident{ macro_rules! ignore_ident{ ($id:ident, $($t:tt)*) => {$($t)*}; } +macro_rules! rev_for_each_ident{ + ($m:ident, ) => {}; + ($m:ident, $i0:ident, $($i:ident,)*) => { + rev_for_each_ident!($m, $($i,)*); + $m!($i0); + }; +} macro_rules! impl_tuple_collect { - ($($Y:ident),* ; $($Y_rev:ident),*) => ( + ($($Y:ident),*) => ( impl TupleCollect for ($(ignore_ident!($Y, A),)*) { type Item = A; type Buffer = [Option; count_ident!($($Y,)*) - 1]; @@ -302,39 +309,29 @@ macro_rules! impl_tuple_collect { count_ident!($($Y,)*) } - fn left_shift_push(&mut self, item: A) { + fn left_shift_push(&mut self, mut item: A) { use std::mem::replace; let &mut ($(ref mut $Y),*,) = self; - $( - let item = replace($Y_rev, item); - )* + macro_rules! replace_item{($i:ident) => { + item = replace($i, item); + }}; + rev_for_each_ident!(replace_item, $($Y,)*); drop(item); } } ) } -// This snippet generates the twelve `impl_tuple_collect!` invocations: -// use core::iter; -// use itertools::Itertools; -// -// for i in 1..=12 { -// println!("impl_tuple_collect!({idents}; {rev_idents});", -// idents=('a'..='z').take(i).join(", "), -// rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ") -// ); -// } -// It could probably be replaced by a bit more macro cleverness. -impl_tuple_collect!(a; a); -impl_tuple_collect!(a, b; b, a); -impl_tuple_collect!(a, b, c; c, b, a); -impl_tuple_collect!(a, b, c, d; d, c, b, a); -impl_tuple_collect!(a, b, c, d, e; e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f; f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g; g, f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(a); +impl_tuple_collect!(a, b); +impl_tuple_collect!(a, b, c); +impl_tuple_collect!(a, b, c, d); +impl_tuple_collect!(a, b, c, d, e); +impl_tuple_collect!(a, b, c, d, e, f); +impl_tuple_collect!(a, b, c, d, e, f, g); +impl_tuple_collect!(a, b, c, d, e, f, g, h); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k); +impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k, l); From fb5a0931516ce7481dcf314b62ed5ad08bc6e26f Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 18 Sep 2020 11:05:43 +0200 Subject: [PATCH 5/5] More macro cleverness (5) loop over suffixes via macro --- src/tuple_impl.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 3fe3f80ee..1d24b0bb3 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -260,7 +260,9 @@ macro_rules! rev_for_each_ident{ } macro_rules! impl_tuple_collect { - ($($Y:ident),*) => ( + ($dummy:ident,) => {}; // stop + ($dummy:ident, $($Y:ident,)*) => ( + impl_tuple_collect!($($Y,)*); impl TupleCollect for ($(ignore_ident!($Y, A),)*) { type Item = A; type Buffer = [Option; count_ident!($($Y,)*) - 1]; @@ -322,16 +324,4 @@ macro_rules! impl_tuple_collect { } ) } - -impl_tuple_collect!(a); -impl_tuple_collect!(a, b); -impl_tuple_collect!(a, b, c); -impl_tuple_collect!(a, b, c, d); -impl_tuple_collect!(a, b, c, d, e); -impl_tuple_collect!(a, b, c, d, e, f); -impl_tuple_collect!(a, b, c, d, e, f, g); -impl_tuple_collect!(a, b, c, d, e, f, g, h); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k); -impl_tuple_collect!(a, b, c, d, e, f, g, h, i, j, k, l); +impl_tuple_collect!(dummy, a, b, c, d, e, f, g, h, i, j, k, l,);