mirror of
https://github.com/dlang/phobos.git
synced 2025-05-12 23:29:01 +03:00
Add support for more than two arguments to std.algorithm.setIntersection
This seems to have always been intended to work, but was left unfinished. The old documentation, as well as the current entry in the cheat sheet, claimed it supported any number of arguments.
This commit is contained in:
parent
ce25c43b2c
commit
1791e7c39d
1 changed files with 60 additions and 32 deletions
|
@ -10873,37 +10873,42 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Lazily computes the intersection of two input ranges $(D
|
Lazily computes the intersection of two or more input ranges $(D
|
||||||
rs). The ranges are assumed to be sorted by $(D less). The element
|
ranges). The ranges are assumed to be sorted by $(D less). The element
|
||||||
types of both ranges must have a common type.
|
types of the ranges must have a common type.
|
||||||
*/
|
*/
|
||||||
struct SetIntersection(alias less = "a < b", Rs...)
|
struct SetIntersection(alias less = "a < b", Rs...)
|
||||||
if (allSatisfy!(isInputRange, Rs))
|
if (allSatisfy!(isInputRange, Rs) &&
|
||||||
|
!is(CommonType!(staticMap!(ElementType, Rs)) == void))
|
||||||
{
|
{
|
||||||
static assert(Rs.length == 2);
|
|
||||||
private:
|
private:
|
||||||
Rs _input;
|
Rs _input;
|
||||||
alias binaryFun!(less) comp;
|
alias comp = binaryFun!less;
|
||||||
alias CommonType!(staticMap!(.ElementType, Rs)) ElementType;
|
alias ElementType = CommonType!(staticMap!(.ElementType, Rs));
|
||||||
|
|
||||||
|
// Positions to the first elements that are all equal
|
||||||
void adjustPosition()
|
void adjustPosition()
|
||||||
{
|
{
|
||||||
// Positions to the first two elements that are equal
|
outer:
|
||||||
while (!empty)
|
while (!empty)
|
||||||
{
|
{
|
||||||
if (comp(_input[0].front, _input[1].front))
|
foreach (i, ref r; _input[0 .. $ - 1])
|
||||||
{
|
{
|
||||||
_input[0].popFront();
|
alias next = _input[i + 1];
|
||||||
}
|
if (comp(r.front, next.front))
|
||||||
else if (comp(_input[1].front, _input[0].front))
|
|
||||||
{
|
{
|
||||||
_input[1].popFront();
|
r.popFront();
|
||||||
|
continue outer;
|
||||||
}
|
}
|
||||||
else
|
if (comp(next.front, r.front))
|
||||||
{
|
{
|
||||||
break;
|
next.popFront();
|
||||||
|
continue outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -10916,9 +10921,9 @@ public:
|
||||||
|
|
||||||
@property bool empty()
|
@property bool empty()
|
||||||
{
|
{
|
||||||
foreach (i, U; Rs)
|
foreach (ref r; _input)
|
||||||
{
|
{
|
||||||
if (_input[i].empty) return true;
|
if (r.empty) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -10926,10 +10931,16 @@ public:
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
assert(!comp(_input[0].front, _input[1].front)
|
foreach (i, ref r; _input[0 .. $ - 1])
|
||||||
&& !comp(_input[1].front, _input[0].front));
|
{
|
||||||
_input[0].popFront();
|
alias next = _input[i + 1];
|
||||||
_input[1].popFront();
|
assert(!comp(r.front, next.front) && !comp(next.front, r.front));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ref r; _input)
|
||||||
|
{
|
||||||
|
r.popFront();
|
||||||
|
}
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10941,7 +10952,7 @@ public:
|
||||||
|
|
||||||
static if (allSatisfy!(isForwardRange, Rs))
|
static if (allSatisfy!(isForwardRange, Rs))
|
||||||
{
|
{
|
||||||
@property auto save()
|
@property SetIntersection save()
|
||||||
{
|
{
|
||||||
auto ret = this;
|
auto ret = this;
|
||||||
foreach (ti, elem; _input)
|
foreach (ti, elem; _input)
|
||||||
|
@ -10956,12 +10967,12 @@ public:
|
||||||
/// Ditto
|
/// Ditto
|
||||||
SetIntersection!(less, Rs) setIntersection(alias less = "a < b", Rs...)
|
SetIntersection!(less, Rs) setIntersection(alias less = "a < b", Rs...)
|
||||||
(Rs ranges)
|
(Rs ranges)
|
||||||
if (allSatisfy!(isInputRange, Rs))
|
if (allSatisfy!(isInputRange, Rs) &&
|
||||||
|
!is(CommonType!(staticMap!(ElementType, Rs)) == void))
|
||||||
{
|
{
|
||||||
return typeof(return)(ranges);
|
return typeof(return)(ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
/+ setIntersection doesn't yet support more than two inputs
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
|
@ -10969,18 +10980,35 @@ unittest
|
||||||
int[] b = [ 0, 1, 2, 4, 7, 8 ];
|
int[] b = [ 0, 1, 2, 4, 7, 8 ];
|
||||||
int[] c = [ 0, 1, 4, 5, 7, 8 ];
|
int[] c = [ 0, 1, 4, 5, 7, 8 ];
|
||||||
assert(equal(setIntersection(a, a), a));
|
assert(equal(setIntersection(a, a), a));
|
||||||
assert(equal(setIntersection(a, b), [1, 2, 4, 7][]));
|
assert(equal(setIntersection(a, b), [1, 2, 4, 7]));
|
||||||
assert(equal(setIntersection(a, b, c), [1, 4, 7][]));
|
assert(equal(setIntersection(a, b, c), [1, 4, 7]));
|
||||||
}
|
}
|
||||||
+/
|
|
||||||
|
|
||||||
///
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
int[] a = [ 1, 2, 4, 5, 7, 9 ];
|
int[] a = [ 1, 2, 4, 5, 7, 9 ];
|
||||||
int[] b = [ 0, 1, 2, 4, 7, 8 ];
|
int[] b = [ 0, 1, 2, 4, 7, 8 ];
|
||||||
|
int[] c = [ 0, 1, 4, 5, 7, 8 ];
|
||||||
|
int[] d = [ 1, 3, 4 ];
|
||||||
|
int[] e = [ 4, 5 ];
|
||||||
|
|
||||||
assert(equal(setIntersection(a, a), a));
|
assert(equal(setIntersection(a, a), a));
|
||||||
assert(equal(setIntersection(a, b), [1, 2, 4, 7][]));
|
assert(equal(setIntersection(a, a, a), a));
|
||||||
|
assert(equal(setIntersection(a, b), [1, 2, 4, 7]));
|
||||||
|
assert(equal(setIntersection(a, b, c), [1, 4, 7]));
|
||||||
|
assert(equal(setIntersection(a, b, c, d), [1, 4]));
|
||||||
|
assert(equal(setIntersection(a, b, c, d, e), [4]));
|
||||||
|
|
||||||
|
auto inpA = a.filter!(_ => true), inpB = b.filter!(_ => true);
|
||||||
|
auto inpC = c.filter!(_ => true), inpD = d.filter!(_ => true);
|
||||||
|
assert(equal(setIntersection(inpA, inpB, inpC, inpD), [1, 4]));
|
||||||
|
|
||||||
|
assert(equal(setIntersection(a, b, b, a), [1, 2, 4, 7]));
|
||||||
|
assert(equal(setIntersection(a, c, b), [1, 4, 7]));
|
||||||
|
assert(equal(setIntersection(b, a, c), [1, 4, 7]));
|
||||||
|
assert(equal(setIntersection(b, c, a), [1, 4, 7]));
|
||||||
|
assert(equal(setIntersection(c, a, b), [1, 4, 7]));
|
||||||
|
assert(equal(setIntersection(c, b, a), [1, 4, 7]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue