@@ -630,11 +630,46 @@ Creates a mapped iterator. Uses `__map` if possible.
630
630
auto mapIterator (alias fun, Iterator)(Iterator iterator)
631
631
{
632
632
static if (__traits(hasMember, Iterator, " __map" ))
633
- return Iterator.__map! fun(iterator);
633
+ {
634
+ static if (is (Iterator : MapIterator! (Iter0, fun0), Iter0, alias fun0)
635
+ && ! __traits(compiles, Iterator.__map! fun(iterator)))
636
+ {
637
+ // https://github.com/libmir/mir-algorithm/issues/111
638
+ pragma (msg, __FUNCTION__ ~ " not coalescing chained map calls into a single lambda, possibly because of multiple embedded context pointers" );
639
+ return MapIterator! (Iterator, fun)(iterator);
640
+ }
641
+ else
642
+ return Iterator.__map! fun(iterator);
643
+ }
634
644
else
635
645
return MapIterator! (Iterator, fun)(iterator);
636
646
}
637
647
648
+ @safe pure nothrow @nogc version(mir_test) unittest
649
+ {
650
+ // https://github.com/libmir/mir-algorithm/issues/111
651
+ import mir.ndslice.topology : iota, map;
652
+ import mir.functional : pipe;
653
+
654
+ static auto foo (T)(T x)
655
+ {
656
+ return x.map! (a => a + 1 );
657
+ }
658
+
659
+ static auto bar (T)(T x)
660
+ {
661
+ return foo (x).map! (a => a + 2 );
662
+ }
663
+
664
+ auto data = iota(5 );
665
+ auto result = iota([5 ], 3 );
666
+
667
+ auto x = data.map! (a => a + 1 ).map! (a => a + 2 );
668
+ assert (x == result);
669
+
670
+ auto y = bar(data);
671
+ assert (y == result);
672
+ }
638
673
639
674
/+ +
640
675
`BytegroupIterator` is used by $(SUBREF topology, Bytegroup) and $(SUBREF topology, bytegroup).
0 commit comments