Re: your "XXX" block, I've refactored the code thus:
# 0 --> identical element
if ( $which_list == 0 ) {
die "Can't happen" if @indices1 != @indices2;
foreach my $i ( 0 .. $#indices1 ) {
my ( $item1, @offsets ) = @{ $list1_aref->[ $indices1[
+$i] ] };
my ( $item2, $offset ) = @{ $list2_aref->[ $indices2[
+$i] ] };
die unless $item1 eq $item2;
push @offsets, $offset;
push @merged, [ $item1, @offsets ];
}
}
# 1 --> list 1 has an element here
if ( $which_list & 1 ) {
foreach ( @{ $list1_aref }[ @indices1 ] ) {
my ( $item1, @offsets ) = @{ $_ };
push @offsets, undef;
push @merged, [ $item1, @offsets ];
}
}
# 2 --> list 2 has an element here
if ( $which_list & 2 ) {
foreach ( @{ $list2_aref }[ @indices2 ] ) {
my ( $item2, $offset ) = @{ $_ };
my @offsets = map { undef() } 1 .. $offset_width;
push @offsets, $offset;
push @merged, [ $item2, @offsets ];
}
}
I've scrapped the 'elsifs' and used & instead of ==.