From ff083dfec1ee1b9b4b9a54426a425ee4065b0601 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet <44676486+Philippe-Cholet@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:29:06 +0100 Subject: [PATCH 1/4] `iproduct`: allow commas at the end --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1f39379e2..f3e295301 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -249,13 +249,13 @@ macro_rules! iproduct { (@flatten $I:expr, $J:expr, $($K:expr,)*) => ( $crate::iproduct!(@flatten $crate::cons_tuples($crate::iproduct!($I, $J)), $($K,)*) ); - ($I:expr) => ( + ($I:expr $(,)?) => ( $crate::__std_iter::IntoIterator::into_iter($I) ); - ($I:expr, $J:expr) => ( + ($I:expr, $J:expr $(,)?) => ( $crate::Itertools::cartesian_product($crate::iproduct!($I), $crate::iproduct!($J)) ); - ($I:expr, $J:expr, $($K:expr),+) => ( + ($I:expr, $J:expr, $($K:expr),+ $(,)?) => ( $crate::iproduct!(@flatten $crate::iproduct!($I, $J), $($K,)+) ); } From 518efd395e7879f97453486c185956c4b7605209 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet <44676486+Philippe-Cholet@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:36:05 +0100 Subject: [PATCH 2/4] `iproduct(it)`: yield 1-tuples instead --- src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f3e295301..a3998fdac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -250,10 +250,13 @@ macro_rules! iproduct { $crate::iproduct!(@flatten $crate::cons_tuples($crate::iproduct!($I, $J)), $($K,)*) ); ($I:expr $(,)?) => ( - $crate::__std_iter::IntoIterator::into_iter($I) + $crate::__std_iter::IntoIterator::into_iter($I).map(|elt| (elt,)) ); ($I:expr, $J:expr $(,)?) => ( - $crate::Itertools::cartesian_product($crate::iproduct!($I), $crate::iproduct!($J)) + $crate::Itertools::cartesian_product( + $crate::__std_iter::IntoIterator::into_iter($I), + $crate::__std_iter::IntoIterator::into_iter($J), + ) ); ($I:expr, $J:expr, $($K:expr),+ $(,)?) => ( $crate::iproduct!(@flatten $crate::iproduct!($I, $J), $($K,)+) From 8297524cc8d7c285ae3dc779e16e9b39d7703f8d Mon Sep 17 00:00:00 2001 From: Philippe-Cholet <44676486+Philippe-Cholet@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:32:06 +0100 Subject: [PATCH 3/4] `iproduct`: yield one unit for the empty product --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index a3998fdac..5d49b7fc6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -249,6 +249,9 @@ macro_rules! iproduct { (@flatten $I:expr, $J:expr, $($K:expr,)*) => ( $crate::iproduct!(@flatten $crate::cons_tuples($crate::iproduct!($I, $J)), $($K,)*) ); + () => ( + $crate::__std_iter::once(()) + ); ($I:expr $(,)?) => ( $crate::__std_iter::IntoIterator::into_iter($I).map(|elt| (elt,)) ); From 5ab11d66c2d59eb7882e4a2a9dc9d67bbd2d74bc Mon Sep 17 00:00:00 2001 From: Philippe-Cholet <44676486+Philippe-Cholet@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:15:59 +0100 Subject: [PATCH 4/4] Update `iproduct` tests Test name `iproduct1` starts with `i` because `product1` is for another kind of test. --- tests/macros_hygiene.rs | 1 + tests/test_core.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/macros_hygiene.rs b/tests/macros_hygiene.rs index d1111245d..20b59fba8 100644 --- a/tests/macros_hygiene.rs +++ b/tests/macros_hygiene.rs @@ -1,5 +1,6 @@ #[test] fn iproduct_hygiene() { + let _ = itertools::iproduct!(); let _ = itertools::iproduct!(0..6); let _ = itertools::iproduct!(0..6, 0..9); let _ = itertools::iproduct!(0..6, 0..9, 0..12); diff --git a/tests/test_core.rs b/tests/test_core.rs index 45a8df438..db77a1e3e 100644 --- a/tests/test_core.rs +++ b/tests/test_core.rs @@ -18,6 +18,23 @@ use crate::it::Itertools; use core::iter; use itertools as it; +#[test] +fn product0() { + let mut prod = iproduct!(); + assert_eq!(prod.next(), Some(())); + assert!(prod.next().is_none()); +} + +#[test] +fn iproduct1() { + let s = "αβ"; + + let mut prod = iproduct!(s.chars()); + assert_eq!(prod.next(), Some(('α',))); + assert_eq!(prod.next(), Some(('β',))); + assert!(prod.next().is_none()); +} + #[test] fn product2() { let s = "αβ";