Revert "Merge pull request #4961 from edi33416/uniq_consistency"

This reverts commit 428217b317, reversing
changes made to 7c2dc1ccba.
This commit is contained in:
Vladimir Panteleev 2017-05-10 22:20:16 +00:00
parent ef025a64ab
commit 1e61c5cb6e

View file

@ -4951,48 +4951,9 @@ if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))
assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1])); assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1]));
} }
///
@system unittest
{
import std.algorithm.comparison : equal;
struct S
{
int i;
string s;
}
auto arr = [ S(1, "a"), S(1, "b"), S(2, "c"), S(2, "d") ];
// Let's consider just the 'i' member for equality
auto r = arr.uniq!((a, b) => a.i == b.i);
assert(r.equal([S(1, "a"), S(2, "c")]));
assert(r.front == S(1, "a"));
assert(r.back == S(2, "c"));
r.popBack;
assert(r.back == S(1, "a"));
assert(r.front == r.back);
r.popBack;
assert(r.empty);
import std.exception : assertThrown;
assertThrown!Error(r.front);
assertThrown!Error(r.back);
assertThrown!Error(r.popFront);
assertThrown!Error(r.popBack);
}
private struct UniqResult(alias pred, Range) private struct UniqResult(alias pred, Range)
{ {
private Range _input; Range _input;
static if (isBidirectionalRange!Range)
{
private ElementType!Range _back;
private bool _isInBack;
}
this(Range input) this(Range input)
{ {
@ -5007,19 +4968,10 @@ private struct UniqResult(alias pred, Range)
void popFront() void popFront()
{ {
assert(!empty, "Attempting to popFront an empty uniq."); assert(!empty, "Attempting to popFront an empty uniq.");
static if (isBidirectionalRange!Range)
{
if (_input.empty)
{
_isInBack = false;
return;
}
}
auto last = _input.front; auto last = _input.front;
do do
{ {
_input.popFront; _input.popFront();
} }
while (!_input.empty && pred(last, _input.front)); while (!_input.empty && pred(last, _input.front));
} }
@ -5027,13 +4979,6 @@ private struct UniqResult(alias pred, Range)
@property ElementType!Range front() @property ElementType!Range front()
{ {
assert(!empty, "Attempting to fetch the front of an empty uniq."); assert(!empty, "Attempting to fetch the front of an empty uniq.");
static if (isBidirectionalRange!Range)
{
if (_input.empty && _isInBack)
{
return _back;
}
}
return _input.front; return _input.front;
} }
@ -5042,33 +4987,18 @@ private struct UniqResult(alias pred, Range)
void popBack() void popBack()
{ {
assert(!empty, "Attempting to popBack an empty uniq."); assert(!empty, "Attempting to popBack an empty uniq.");
if (_input.empty) auto last = _input.back;
{
_isInBack = false;
}
else
{
_isInBack = true;
_back = _input.back;
ElementType!Range last;
do do
{ {
last = _input.back; _input.popBack();
_input.popBack;
}
while (!_input.empty && pred(_back, _input.back));
_back = last;
} }
while (!_input.empty && pred(last, _input.back));
} }
@property ElementType!Range back() @property ElementType!Range back()
{ {
assert(!empty, "Attempting to fetch the back of an empty uniq."); assert(!empty, "Attempting to fetch the back of an empty uniq.");
if (!_isInBack) return _input.back;
{
popBack;
}
return _back;
} }
} }
@ -5078,17 +5008,7 @@ private struct UniqResult(alias pred, Range)
} }
else else
{ {
@property bool empty() @property bool empty() { return _input.empty; }
{
static if (isBidirectionalRange!Range)
{
return _input.empty && !_isInBack;
}
else
{
return _input.empty;
}
}
} }
static if (isForwardRange!Range) static if (isForwardRange!Range)