mirror of
https://github.com/dlang/phobos.git
synced 2025-05-06 19:16:13 +03:00
[std.algorithm.searching] Refactor findSplit result types
This commit is contained in:
parent
9cb5f6d7db
commit
0819fec814
1 changed files with 43 additions and 110 deletions
|
@ -2881,6 +2881,29 @@ if (isForwardRange!R1 && ifTestable!(typeof(haystack.front), unaryFun!pred))
|
|||
assert(findSkip!isWhite(s) == 2);
|
||||
}
|
||||
|
||||
private struct FindSplitResult(ubyte emptyRangeIndex, Types...)
|
||||
{
|
||||
this(Types vals)
|
||||
{
|
||||
asTuple = typeof(asTuple)(vals);
|
||||
}
|
||||
void opAssign(typeof(asTuple) rhs)
|
||||
{
|
||||
asTuple = rhs;
|
||||
}
|
||||
Tuple!Types asTuple;
|
||||
alias asTuple this;
|
||||
|
||||
static if (hasConstEmptyMember!(typeof(asTuple[emptyRangeIndex])))
|
||||
{
|
||||
bool opCast(T : bool)() const => !asTuple[emptyRangeIndex].empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool opCast(T : bool)() => !asTuple[emptyRangeIndex].empty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
These functions find the first occurrence of `needle` in `haystack` and then
|
||||
split `haystack` as follows.
|
||||
|
@ -2930,45 +2953,15 @@ See_Also: $(LREF find)
|
|||
auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||
if (isForwardRange!R1 && isForwardRange!R2)
|
||||
{
|
||||
static struct Result(S1, S2) if (isForwardRange!S1 &&
|
||||
isForwardRange!S2)
|
||||
{
|
||||
this(S1 pre, S1 separator, S2 post)
|
||||
{
|
||||
asTuple = typeof(asTuple)(pre, separator, post);
|
||||
}
|
||||
void opAssign(typeof(asTuple) rhs)
|
||||
{
|
||||
asTuple = rhs;
|
||||
}
|
||||
Tuple!(S1, S1, S2) asTuple;
|
||||
static if (hasConstEmptyMember!(typeof(asTuple[1])))
|
||||
{
|
||||
bool opCast(T : bool)() const
|
||||
{
|
||||
return !asTuple[1].empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool opCast(T : bool)()
|
||||
{
|
||||
return !asTuple[1].empty;
|
||||
}
|
||||
}
|
||||
alias asTuple this;
|
||||
}
|
||||
|
||||
static if (isSomeString!R1 && isSomeString!R2
|
||||
|| (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))
|
||||
{
|
||||
auto balance = find!pred(haystack, needle);
|
||||
immutable pos1 = haystack.length - balance.length;
|
||||
immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
|
||||
return Result!(typeof(haystack[0 .. pos1]),
|
||||
typeof(haystack[pos2 .. haystack.length]))(haystack[0 .. pos1],
|
||||
haystack[pos1 .. pos2],
|
||||
haystack[pos2 .. haystack.length]);
|
||||
alias Slice = typeof(haystack[0 .. pos1]);
|
||||
return FindSplitResult!(1, Slice, Slice, Slice)(
|
||||
haystack[0 .. pos1], haystack[pos1 .. pos2], haystack[pos2 .. haystack.length]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2997,10 +2990,11 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
{
|
||||
pos1 = pos2;
|
||||
}
|
||||
return Result!(typeof(takeExactly(original, pos1)),
|
||||
typeof(h))(takeExactly(original, pos1),
|
||||
takeExactly(haystack, pos2 - pos1),
|
||||
h);
|
||||
return FindSplitResult!(1,
|
||||
typeof(takeExactly(original, pos1)),
|
||||
typeof(takeExactly(original, pos1)), typeof(h))(
|
||||
takeExactly(original, pos1),
|
||||
takeExactly(haystack, pos2 - pos1), h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3008,43 +3002,14 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
auto findSplitBefore(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||
if (isForwardRange!R1 && isForwardRange!R2)
|
||||
{
|
||||
static struct Result(S1, S2) if (isForwardRange!S1 &&
|
||||
isForwardRange!S2)
|
||||
{
|
||||
this(S1 pre, S2 post)
|
||||
{
|
||||
asTuple = typeof(asTuple)(pre, post);
|
||||
}
|
||||
void opAssign(typeof(asTuple) rhs)
|
||||
{
|
||||
asTuple = rhs;
|
||||
}
|
||||
Tuple!(S1, S2) asTuple;
|
||||
static if (hasConstEmptyMember!(typeof(asTuple[1])))
|
||||
{
|
||||
bool opCast(T : bool)() const
|
||||
{
|
||||
return !asTuple[1].empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool opCast(T : bool)()
|
||||
{
|
||||
return !asTuple[1].empty;
|
||||
}
|
||||
}
|
||||
alias asTuple this;
|
||||
}
|
||||
|
||||
static if (isSomeString!R1 && isSomeString!R2
|
||||
|| (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2))
|
||||
{
|
||||
auto balance = find!pred(haystack, needle);
|
||||
immutable pos = haystack.length - balance.length;
|
||||
return Result!(typeof(haystack[0 .. pos]),
|
||||
typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],
|
||||
haystack[pos .. haystack.length]);
|
||||
return FindSplitResult!(1,
|
||||
typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
|
||||
haystack[0 .. pos], haystack[pos .. haystack.length]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3074,9 +3039,9 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
pos1 = pos2;
|
||||
haystack = h;
|
||||
}
|
||||
return Result!(typeof(takeExactly(original, pos1)),
|
||||
typeof(haystack))(takeExactly(original, pos1),
|
||||
haystack);
|
||||
return FindSplitResult!(1,
|
||||
typeof(takeExactly(original, pos1)), typeof(haystack))(
|
||||
takeExactly(original, pos1), haystack);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3084,47 +3049,19 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
auto findSplitAfter(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||
if (isForwardRange!R1 && isForwardRange!R2)
|
||||
{
|
||||
static struct Result(S1, S2) if (isForwardRange!S1 &&
|
||||
isForwardRange!S2)
|
||||
{
|
||||
this(S1 pre, S2 post)
|
||||
{
|
||||
asTuple = typeof(asTuple)(pre, post);
|
||||
}
|
||||
void opAssign(typeof(asTuple) rhs)
|
||||
{
|
||||
asTuple = rhs;
|
||||
}
|
||||
Tuple!(S1, S2) asTuple;
|
||||
static if (hasConstEmptyMember!(typeof(asTuple[1])))
|
||||
{
|
||||
bool opCast(T : bool)() const
|
||||
{
|
||||
return !asTuple[0].empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool opCast(T : bool)()
|
||||
{
|
||||
return !asTuple[0].empty;
|
||||
}
|
||||
}
|
||||
alias asTuple this;
|
||||
}
|
||||
|
||||
static if (isSomeString!R1 && isSomeString!R2
|
||||
|| isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2)
|
||||
{
|
||||
auto balance = find!pred(haystack, needle);
|
||||
immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;
|
||||
return Result!(typeof(haystack[0 .. pos]),
|
||||
typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],
|
||||
haystack[pos .. haystack.length]);
|
||||
return FindSplitResult!(0,
|
||||
typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
|
||||
haystack[0 .. pos], haystack[pos .. haystack.length]);
|
||||
}
|
||||
else
|
||||
{
|
||||
import std.range : takeExactly;
|
||||
alias Res = FindSplitResult!(0, typeof(takeExactly(haystack, 0)), typeof(haystack));
|
||||
auto original = haystack.save;
|
||||
auto h = haystack.save;
|
||||
auto n = needle.save;
|
||||
|
@ -3134,9 +3071,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
if (h.empty)
|
||||
{
|
||||
// Failed search
|
||||
return Result!(typeof(takeExactly(original, 0)),
|
||||
typeof(original))(takeExactly(original, 0),
|
||||
original);
|
||||
return Res(takeExactly(original, 0), original);
|
||||
}
|
||||
if (binaryFun!pred(h.front, n.front))
|
||||
{
|
||||
|
@ -3152,9 +3087,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
pos2 = ++pos1;
|
||||
}
|
||||
}
|
||||
return Result!(typeof(takeExactly(original, pos2)),
|
||||
typeof(h))(takeExactly(original, pos2),
|
||||
h);
|
||||
return Res(takeExactly(original, pos2), h);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue