Closed ijackson closed 7 months ago
I'm not sure.
iproduct!(0..2, 0..2) -> (0, 0), ... yes tuples
iproduct!(0..2) --> 0, ... not tuples (change this would be a breaking change)
iproduct!() then why would it be a tuple?
but macros that generate iproduct! invocations might produce this case sometimes.
I think it would be perfectly fine to not do this until some specific macro that wants to use it shows up to say why and how it'd be useful. Otherwise an error seems perfectly fine here.
iproduct!(0..2, 0..2) -> (0, 0), ... yes tuples iproduct!(0..2) --> 0, ... not tuples (change this would be a breaking change) iproduct!() then why would it be a tuple?
Oh! The lack of tuples for a single argument is strange. My hypothetical macro generating iproduct! calls would already break.
I guess there's a workaround:
use itertools::Itertools;
macro_rules! iproduct_fully_general {
{ } => { std::iter::once(()) };
{ $e0:expr $(,)? } => { std::iter::IntoIterator::into_iter($e0).map(|v| (v,)) };
{ $e0:expr, $($e:expr),+ } => { itertools::iproduct!($e0, $($e),+) };
} // the type depends funkily on the number of arguments, but that's true of iproduct! anyway
fn main() {
println!("{:?}\n{:?}\n{:?}",
iproduct_fully_general!().collect_vec(),
iproduct_fully_general!([1,2]).collect_vec(),
iproduct_fully_general!([1,2], [3,4]).collect_vec(),
)
}
I really think we should fix this in a future incompatible version.
I rewrote Itertools::multi_cartesian_product
internals so the next release is a breaking one (it will finally produce a single vector for an empty product ^^). I guess it has some sense to do that as well.
To reproduce:
Expected output:
Actual output:
This wouldn't be particularly useful for humans, but macros that generate iproduct! invocations might produce this case sometimes.