mirror of
https://github.com/dlang/phobos.git
synced 2025-05-01 15:40:36 +03:00
Add missing signature constraints for splitter.
As well as require bidirectional separator with length before assuming retro(separator) and separator.length will work. Without these additional constraints, splitter will cause unhelpful compile errors about being unable instantiate find, when the separator is a non-forward input range, or when it doesn't have length, or when it's non-bidirectional. In the latter case, splitter should still work, just that it won't export a bidirectional interface.
This commit is contained in:
parent
9fab541993
commit
cd9696a8e8
1 changed files with 28 additions and 3 deletions
|
@ -2412,7 +2412,9 @@ with string types.
|
|||
*/
|
||||
auto splitter(Range, Separator)(Range r, Separator s)
|
||||
if (is(typeof(Range.init.front == Separator.init.front) : bool)
|
||||
&& (hasSlicing!Range || isNarrowString!Range))
|
||||
&& (hasSlicing!Range || isNarrowString!Range)
|
||||
&& isForwardRange!Separator
|
||||
&& (hasLength!Separator || isNarrowString!Separator))
|
||||
{
|
||||
static struct Result
|
||||
{
|
||||
|
@ -2444,7 +2446,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
|
|||
if (_backLength != _backLength.max) return;
|
||||
assert(!_input.empty);
|
||||
// compute back length
|
||||
static if (isBidirectionalRange!Range)
|
||||
static if (isBidirectionalRange!Range && isBidirectionalRange!Separator)
|
||||
{
|
||||
_backLength = _input.length -
|
||||
find(retro(_input), retro(_separator)).source.length;
|
||||
|
@ -2518,7 +2520,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
|
|||
}
|
||||
|
||||
// Bidirectional functionality as suggested by Brad Roberts.
|
||||
static if (isBidirectionalRange!Range)
|
||||
static if (isBidirectionalRange!Range && isBidirectionalRange!Separator)
|
||||
{
|
||||
@property Range back()
|
||||
{
|
||||
|
@ -2619,6 +2621,29 @@ unittest
|
|||
}
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
// Test by-reference separator
|
||||
class RefSep {
|
||||
string _impl;
|
||||
this(string s) { _impl = s; }
|
||||
@property empty() { return _impl.empty; }
|
||||
@property auto front() { return _impl.front; }
|
||||
void popFront() { _impl = _impl[1..$]; }
|
||||
@property RefSep save() { return new RefSep(_impl); }
|
||||
@property auto length() { return _impl.length; }
|
||||
}
|
||||
auto sep = new RefSep("->");
|
||||
auto data = "i->am->pointing";
|
||||
auto words = splitter(data, sep);
|
||||
auto expected = [ "i", "am", "pointing" ];
|
||||
foreach (w; words) {
|
||||
assert(w == expected.front);
|
||||
expected.popFront();
|
||||
}
|
||||
assert(expected.empty);
|
||||
}
|
||||
|
||||
auto splitter(alias isTerminator, Range)(Range input)
|
||||
if (is(typeof(unaryFun!(isTerminator)(ElementType!(Range).init))))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue