mirror of
https://github.com/dlang/phobos.git
synced 2025-05-08 03:56:54 +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);
|
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
|
These functions find the first occurrence of `needle` in `haystack` and then
|
||||||
split `haystack` as follows.
|
split `haystack` as follows.
|
||||||
|
@ -2930,45 +2953,15 @@ See_Also: $(LREF find)
|
||||||
auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
if (isForwardRange!R1 && isForwardRange!R2)
|
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
|
static if (isSomeString!R1 && isSomeString!R2
|
||||||
|| (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))
|
|| (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))
|
||||||
{
|
{
|
||||||
auto balance = find!pred(haystack, needle);
|
auto balance = find!pred(haystack, needle);
|
||||||
immutable pos1 = haystack.length - balance.length;
|
immutable pos1 = haystack.length - balance.length;
|
||||||
immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
|
immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
|
||||||
return Result!(typeof(haystack[0 .. pos1]),
|
alias Slice = typeof(haystack[0 .. pos1]);
|
||||||
typeof(haystack[pos2 .. haystack.length]))(haystack[0 .. pos1],
|
return FindSplitResult!(1, Slice, Slice, Slice)(
|
||||||
haystack[pos1 .. pos2],
|
haystack[0 .. pos1], haystack[pos1 .. pos2], haystack[pos2 .. haystack.length]);
|
||||||
haystack[pos2 .. haystack.length]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2997,10 +2990,11 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
{
|
{
|
||||||
pos1 = pos2;
|
pos1 = pos2;
|
||||||
}
|
}
|
||||||
return Result!(typeof(takeExactly(original, pos1)),
|
return FindSplitResult!(1,
|
||||||
typeof(h))(takeExactly(original, pos1),
|
typeof(takeExactly(original, pos1)),
|
||||||
takeExactly(haystack, pos2 - pos1),
|
typeof(takeExactly(original, pos1)), typeof(h))(
|
||||||
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)
|
auto findSplitBefore(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
if (isForwardRange!R1 && isForwardRange!R2)
|
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
|
static if (isSomeString!R1 && isSomeString!R2
|
||||||
|| (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2))
|
|| (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2))
|
||||||
{
|
{
|
||||||
auto balance = find!pred(haystack, needle);
|
auto balance = find!pred(haystack, needle);
|
||||||
immutable pos = haystack.length - balance.length;
|
immutable pos = haystack.length - balance.length;
|
||||||
return Result!(typeof(haystack[0 .. pos]),
|
return FindSplitResult!(1,
|
||||||
typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],
|
typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
|
||||||
haystack[pos .. haystack.length]);
|
haystack[0 .. pos], haystack[pos .. haystack.length]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3074,9 +3039,9 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
pos1 = pos2;
|
pos1 = pos2;
|
||||||
haystack = h;
|
haystack = h;
|
||||||
}
|
}
|
||||||
return Result!(typeof(takeExactly(original, pos1)),
|
return FindSplitResult!(1,
|
||||||
typeof(haystack))(takeExactly(original, pos1),
|
typeof(takeExactly(original, pos1)), typeof(haystack))(
|
||||||
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)
|
auto findSplitAfter(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
if (isForwardRange!R1 && isForwardRange!R2)
|
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
|
static if (isSomeString!R1 && isSomeString!R2
|
||||||
|| isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2)
|
|| isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2)
|
||||||
{
|
{
|
||||||
auto balance = find!pred(haystack, needle);
|
auto balance = find!pred(haystack, needle);
|
||||||
immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;
|
immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;
|
||||||
return Result!(typeof(haystack[0 .. pos]),
|
return FindSplitResult!(0,
|
||||||
typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],
|
typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
|
||||||
haystack[pos .. haystack.length]);
|
haystack[0 .. pos], haystack[pos .. haystack.length]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
import std.range : takeExactly;
|
import std.range : takeExactly;
|
||||||
|
alias Res = FindSplitResult!(0, typeof(takeExactly(haystack, 0)), typeof(haystack));
|
||||||
auto original = haystack.save;
|
auto original = haystack.save;
|
||||||
auto h = haystack.save;
|
auto h = haystack.save;
|
||||||
auto n = needle.save;
|
auto n = needle.save;
|
||||||
|
@ -3134,9 +3071,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
if (h.empty)
|
if (h.empty)
|
||||||
{
|
{
|
||||||
// Failed search
|
// Failed search
|
||||||
return Result!(typeof(takeExactly(original, 0)),
|
return Res(takeExactly(original, 0), original);
|
||||||
typeof(original))(takeExactly(original, 0),
|
|
||||||
original);
|
|
||||||
}
|
}
|
||||||
if (binaryFun!pred(h.front, n.front))
|
if (binaryFun!pred(h.front, n.front))
|
||||||
{
|
{
|
||||||
|
@ -3152,9 +3087,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
pos2 = ++pos1;
|
pos2 = ++pos1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result!(typeof(takeExactly(original, pos2)),
|
return Res(takeExactly(original, pos2), h);
|
||||||
typeof(h))(takeExactly(original, pos2),
|
|
||||||
h);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue