sub mixedgray_iterator { my @domains = @_; my @sizes = map { scalar @$_ } @domains; die "all items must have at least two positions" if grep {$_<2} @sizes; my @cur_indices = (0) x @domains; my @pos_to_loop_next = 0 .. @domains; my @dir = (1) x @domains; my $done; return sub { return undef if $done; my $rv = [map {$domains[$_][$cur_indices[$_]]} 0..$#domains]; if ($pos_to_loop_next[0]==@domains) { $done=1; return $rv } (my $domain,$pos_to_loop_next[0]) = ($pos_to_loop_next[0], 0); $cur_indices[$domain] += $dir[$domain]; if ($cur_indices[$domain]==0 || $cur_indices[$domain]==$sizes[$domain]-1) { $dir[$domain] = -$dir[$domain]; $pos_to_loop_next[$domain] = $pos_to_loop_next[$domain+1]; $pos_to_loop_next[$domain+1] = $domain+1; } return $rv; } }