Expand Up
@@ -321,6 +321,7 @@ is ignored.
}
public :
// /
this (Range needle)
{
if (! needle.length) return ;
Expand All
@@ -347,6 +348,7 @@ public:
}
}
// /
Range beFound (Range haystack)
{
import std.algorithm.comparison : max;
Expand All
@@ -368,11 +370,13 @@ public:
return haystack[$ .. $];
}
// /
@property size_t length()
{
return needle.length;
}
// /
alias opDollar = length;
}
Expand Down
Expand Up
@@ -1765,8 +1769,7 @@ if (isForwardRange!R1 && isForwardRange!R2
assert (equal(r, SList! int (2 , 5 , 7 , 3 )[]));
}
// Specialization for searching a random-access range for a
// bidirectional range
// / ditto
R1 find (alias pred = " a == b" , R1 , R2 )(R1 haystack, R2 needle)
if (isRandomAccessRange! R1 && isBidirectionalRange! R2
&& is (typeof (binaryFun! pred(haystack.front, needle.front)) : bool ))
Expand All
@@ -1775,9 +1778,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
const needleLength = walkLength(needle.save);
if (needleLength > haystack.length)
{
// @@@BUG@@@
// return haystack[$ .. $];
return haystack[haystack.length .. haystack.length];
return haystack[$ .. $];
}
// @@@BUG@@@
// auto needleBack = moveBack(needle);
Expand Down
Expand Up
@@ -1837,8 +1838,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
// assert(find!"a == b"("abc", "bc").length == 2);
}
// Leftover specialization: searching a random-access range for a
// non-bidirectional forward range
// / ditto
R1 find (alias pred = " a == b" , R1 , R2 )(R1 haystack, R2 needle)
if (isRandomAccessRange! R1 && isForwardRange! R2 && ! isBidirectionalRange! R2 &&
is (typeof (binaryFun! pred(haystack.front, needle.front)) : bool ))
Expand Down
Expand Up
@@ -3850,6 +3850,43 @@ enum OpenRight
yes // / Interval is open to the right (last element is not included)
}
/**
Lazily iterates $(D range) _until the element $(D e) for which
$(D pred(e, sentinel)) is true.
Params:
pred = Predicate to determine when to stop.
range = The $(XREF_PACK_NAMED _range,primitives,isInputRange,input _range)
to iterate over.
sentinel = The element to stop at.
openRight = Determines whether the element for which the given predicate is
true should be included in the resulting range ($(D OpenRight.no)), or
not ($(D OpenRight.yes)).
Returns:
An $(XREF_PACK_NAMED _range,primitives,isInputRange,input _range) that
iterates over the original range's elements, but ends when the specified
predicate becomes true. If the original range is a
$(XREF_PACK_NAMED _range,primitives,isForwardRange,forward _range) or
higher, this range will be a forward range.
*/
Until! (pred, Range , Sentinel)
until(alias pred = " a == b" , Range , Sentinel)
(Range range, Sentinel sentinel, OpenRight openRight = OpenRight.yes)
if (! is (Sentinel == OpenRight))
{
return typeof (return )(range, sentinel, openRight);
}
// / Ditto
Until! (pred, Range , void )
until(alias pred, Range )
(Range range, OpenRight openRight = OpenRight.yes)
{
return typeof (return )(range, openRight);
}
// / ditto
struct Until (alias pred, Range , Sentinel) if (isInputRange! Range )
{
private Range _input;
Expand All
@@ -3865,6 +3902,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
bool _done;
static if (! is (Sentinel == void ))
// /
this (Range input, Sentinel sentinel,
OpenRight openRight = OpenRight.yes)
{
Expand All
@@ -3874,18 +3912,21 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
_done = _input.empty || openRight && predSatisfied();
}
else
// /
this (Range input, OpenRight openRight = OpenRight.yes)
{
_input = input;
_openRight = openRight;
_done = _input.empty || openRight && predSatisfied();
}
// /
@property bool empty()
{
return _done;
}
// /
@property auto ref front()
{
assert (! empty);
Expand All
@@ -3900,6 +3941,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
return cast (bool ) startsWith! pred(_input, _sentinel);
}
// /
void popFront ()
{
assert (! empty);
Expand All
@@ -3919,6 +3961,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
static if (isForwardRange! Range )
{
static if (! is (Sentinel == void ))
// /
@property Until save()
{
Until result = this ;
Expand All
@@ -3929,6 +3972,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
return result;
}
else
// /
@property Until save()
{
Until result = this ;
Expand All
@@ -3940,42 +3984,6 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
}
}
/**
Lazily iterates $(D range) _until the element $(D e) for which
$(D pred(e, sentinel)) is true.
Params:
pred = Predicate to determine when to stop.
range = The $(XREF_PACK_NAMED _range,primitives,isInputRange,input _range)
to iterate over.
sentinel = The element to stop at.
openRight = Determines whether the element for which the given predicate is
true should be included in the resulting range ($(D OpenRight.no)), or
not ($(D OpenRight.yes)).
Returns:
An $(XREF_PACK_NAMED _range,primitives,isInputRange,input _range) that
iterates over the original range's elements, but ends when the specified
predicate becomes true. If the original range is a
$(XREF_PACK_NAMED _range,primitives,isForwardRange,forward _range) or
higher, this range will be a forward range.
*/
Until! (pred, Range , Sentinel)
until(alias pred = " a == b" , Range , Sentinel)
(Range range, Sentinel sentinel, OpenRight openRight = OpenRight.yes)
if (! is (Sentinel == OpenRight))
{
return typeof (return )(range, sentinel, openRight);
}
// / Ditto
Until! (pred, Range , void )
until(alias pred, Range )
(Range range, OpenRight openRight = OpenRight.yes)
{
return typeof (return )(range, openRight);
}
// /
@safe unittest
{
Expand Down