Skip to content

Commit 56dfb01

Browse files
bors[bot]phimuemue
andauthored
Merge #478
478: Simplify tuple macro r=jswrenn a=phimuemue This is a follow-up to (i.e. builds upon) #475, doing some of the mentioned "macro cleverness" in the comments. Co-authored-by: philipp <descpl@yahoo.de>
2 parents af54286 + fb5a093 commit 56dfb01

File tree

1 file changed

+30
-37
lines changed

1 file changed

+30
-37
lines changed

src/tuple_impl.rs

+30-37
Original file line numberDiff line numberDiff line change
@@ -244,15 +244,32 @@ pub trait TupleCollect: Sized {
244244
fn left_shift_push(&mut self, item: Self::Item);
245245
}
246246

247+
macro_rules! count_ident{
248+
() => {0};
249+
($i0:ident, $($i:ident,)*) => {1 + count_ident!($($i,)*)};
250+
}
251+
macro_rules! ignore_ident{
252+
($id:ident, $($t:tt)*) => {$($t)*};
253+
}
254+
macro_rules! rev_for_each_ident{
255+
($m:ident, ) => {};
256+
($m:ident, $i0:ident, $($i:ident,)*) => {
257+
rev_for_each_ident!($m, $($i,)*);
258+
$m!($i0);
259+
};
260+
}
261+
247262
macro_rules! impl_tuple_collect {
248-
($N:expr; $A:ident ; $($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => (
249-
impl<$A> TupleCollect for ($($X),*,) {
250-
type Item = $A;
251-
type Buffer = [Option<$A>; $N - 1];
263+
($dummy:ident,) => {}; // stop
264+
($dummy:ident, $($Y:ident,)*) => (
265+
impl_tuple_collect!($($Y,)*);
266+
impl<A> TupleCollect for ($(ignore_ident!($Y, A),)*) {
267+
type Item = A;
268+
type Buffer = [Option<A>; count_ident!($($Y,)*) - 1];
252269

253270
#[allow(unused_assignments, unused_mut)]
254271
fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
255-
where I: IntoIterator<Item = $A>
272+
where I: IntoIterator<Item = A>
256273
{
257274
let mut iter = iter.into_iter();
258275
$(
@@ -281,7 +298,7 @@ macro_rules! impl_tuple_collect {
281298
}
282299

283300
fn collect_from_iter_no_buf<I>(iter: I) -> Option<Self>
284-
where I: IntoIterator<Item = $A>
301+
where I: IntoIterator<Item = A>
285302
{
286303
let mut iter = iter.into_iter();
287304

@@ -291,44 +308,20 @@ macro_rules! impl_tuple_collect {
291308
}
292309

293310
fn num_items() -> usize {
294-
$N
311+
count_ident!($($Y,)*)
295312
}
296313

297-
fn left_shift_push(&mut self, item: $A) {
314+
fn left_shift_push(&mut self, mut item: A) {
298315
use std::mem::replace;
299316

300317
let &mut ($(ref mut $Y),*,) = self;
301-
$(
302-
let item = replace($Y_rev, item);
303-
)*
318+
macro_rules! replace_item{($i:ident) => {
319+
item = replace($i, item);
320+
}};
321+
rev_for_each_ident!(replace_item, $($Y,)*);
304322
drop(item);
305323
}
306324
}
307325
)
308326
}
309-
310-
// This snippet generates the twelve `impl_tuple_collect!` invocations:
311-
// use core::iter;
312-
// use itertools::Itertools;
313-
//
314-
// for i in 1..=12 {
315-
// println!("impl_tuple_collect!({arity}; A; {ty}; {idents}; {rev_idents});",
316-
// arity=i,
317-
// ty=iter::repeat("A").take(i).join(", "),
318-
// idents=('a'..='z').take(i).join(", "),
319-
// rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ")
320-
// );
321-
// }
322-
// It could probably be replaced by a bit more macro cleverness.
323-
impl_tuple_collect!(1; A; A; a; a);
324-
impl_tuple_collect!(2; A; A, A; a, b; b, a);
325-
impl_tuple_collect!(3; A; A, A, A; a, b, c; c, b, a);
326-
impl_tuple_collect!(4; A; A, A, A, A; a, b, c, d; d, c, b, a);
327-
impl_tuple_collect!(5; A; A, A, A, A, A; a, b, c, d, e; e, d, c, b, a);
328-
impl_tuple_collect!(6; A; A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a);
329-
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);
330-
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);
331-
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);
332-
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);
333-
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);
334-
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);
327+
impl_tuple_collect!(dummy, a, b, c, d, e, f, g, h, i, j, k, l,);

0 commit comments

Comments
 (0)