From e33db3409c78f6a4e758315387a8e308f014c267 Mon Sep 17 00:00:00 2001 From: John Colvin Date: Sat, 6 Jun 2020 22:51:59 +0100 Subject: [PATCH] Fix Issue 20943 - std.algorithm.setops.cartesianProduct fails for ranges with @system popFront --- std/algorithm/setops.d | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/std/algorithm/setops.d b/std/algorithm/setops.d index ae51c398b73..48341c40de9 100644 --- a/std/algorithm/setops.d +++ b/std/algorithm/setops.d @@ -391,7 +391,7 @@ if (ranges.length >= 2 && return mixin(algoFormat("tuple(%(current[%d].front%|,%))", iota(0, current.length))); } - void popFront() scope @safe + void popFront() scope { foreach_reverse (i, ref r; current) { @@ -554,6 +554,40 @@ pure @safe nothrow @nogc unittest foreach (pair; cartesianProduct(seq, seq)) {} } +unittest +{ + import std.algorithm.comparison : equal; + import std.typecons : tuple; + + static struct SystemRange + { + int[] data; + + int front() @system @property + { + return data[0]; + } + + bool empty() @system @property + { + return data.length == 0; + } + + void popFront() @system + { + data = data[1 .. $]; + } + + SystemRange save() @system + { + return this; + } + } + + assert(SystemRange([1, 2]).cartesianProduct(SystemRange([3, 4])) + .equal([tuple(1, 3), tuple(1, 4), tuple(2, 3), tuple(2, 4)])); +} + // largestPartialIntersection /** Given a range of sorted $(REF_ALTTEXT forward ranges, isForwardRange, std,range,primitives)