mirror of
https://github.com/dlang/phobos.git
synced 2025-05-09 21:11:57 +03:00
std.algorithms: document public methods
This commit is contained in:
parent
80594b0b61
commit
b8f17e2531
5 changed files with 244 additions and 197 deletions
|
@ -1168,7 +1168,7 @@ size_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)
|
||||||
assert(levenshteinDistance("cat"d, "rat"d) == 1);
|
assert(levenshteinDistance("cat"d, "rat"d) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compat overload for alias this strings
|
/// ditto
|
||||||
size_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)
|
size_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)
|
||||||
(auto ref Range1 s, auto ref Range2 t)
|
(auto ref Range1 s, auto ref Range2 t)
|
||||||
if (isConvertibleToString!Range1 || isConvertibleToString!Range2)
|
if (isConvertibleToString!Range1 || isConvertibleToString!Range2)
|
||||||
|
@ -1240,7 +1240,7 @@ levenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)
|
||||||
assert(levenshteinDistance("kitten", "sitting") == 3);
|
assert(levenshteinDistance("kitten", "sitting") == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compat overload for alias this strings
|
/// ditto
|
||||||
Tuple!(size_t, EditOp[])
|
Tuple!(size_t, EditOp[])
|
||||||
levenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)
|
levenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)
|
||||||
(auto ref Range1 s, auto ref Range2 t)
|
(auto ref Range1 s, auto ref Range2 t)
|
||||||
|
|
|
@ -1319,83 +1319,6 @@ private struct FilterBidiResult(alias pred, Range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// group
|
|
||||||
struct Group(alias pred, R) if (isInputRange!R)
|
|
||||||
{
|
|
||||||
import std.typecons : Rebindable, tuple, Tuple;
|
|
||||||
|
|
||||||
private alias comp = binaryFun!pred;
|
|
||||||
|
|
||||||
private alias E = ElementType!R;
|
|
||||||
static if ((is(E == class) || is(E == interface)) &&
|
|
||||||
(is(E == const) || is(E == immutable)))
|
|
||||||
{
|
|
||||||
private alias MutableE = Rebindable!E;
|
|
||||||
}
|
|
||||||
else static if (is(E : Unqual!E))
|
|
||||||
{
|
|
||||||
private alias MutableE = Unqual!E;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
private alias MutableE = E;
|
|
||||||
}
|
|
||||||
|
|
||||||
private R _input;
|
|
||||||
private Tuple!(MutableE, uint) _current;
|
|
||||||
|
|
||||||
this(R input)
|
|
||||||
{
|
|
||||||
_input = input;
|
|
||||||
if (!_input.empty) popFront();
|
|
||||||
}
|
|
||||||
|
|
||||||
void popFront()
|
|
||||||
{
|
|
||||||
if (_input.empty)
|
|
||||||
{
|
|
||||||
_current[1] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_current = tuple(_input.front, 1u);
|
|
||||||
_input.popFront();
|
|
||||||
while (!_input.empty && comp(_current[0], _input.front))
|
|
||||||
{
|
|
||||||
++_current[1];
|
|
||||||
_input.popFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static if (isInfinite!R)
|
|
||||||
{
|
|
||||||
enum bool empty = false; // Propagate infiniteness.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@property bool empty()
|
|
||||||
{
|
|
||||||
return _current[1] == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@property auto ref front()
|
|
||||||
{
|
|
||||||
assert(!empty);
|
|
||||||
return _current;
|
|
||||||
}
|
|
||||||
|
|
||||||
static if (isForwardRange!R) {
|
|
||||||
@property typeof(this) save() {
|
|
||||||
typeof(this) ret = this;
|
|
||||||
ret._input = this._input.save;
|
|
||||||
ret._current = this._current;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Groups consecutively equivalent elements into a single tuple of the element and
|
Groups consecutively equivalent elements into a single tuple of the element and
|
||||||
the number of its repetitions.
|
the number of its repetitions.
|
||||||
|
@ -1423,6 +1346,89 @@ Group!(pred, Range) group(alias pred = "a == b", Range)(Range r)
|
||||||
return typeof(return)(r);
|
return typeof(return)(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
struct Group(alias pred, R) if (isInputRange!R)
|
||||||
|
{
|
||||||
|
import std.typecons : Rebindable, tuple, Tuple;
|
||||||
|
|
||||||
|
private alias comp = binaryFun!pred;
|
||||||
|
|
||||||
|
private alias E = ElementType!R;
|
||||||
|
static if ((is(E == class) || is(E == interface)) &&
|
||||||
|
(is(E == const) || is(E == immutable)))
|
||||||
|
{
|
||||||
|
private alias MutableE = Rebindable!E;
|
||||||
|
}
|
||||||
|
else static if (is(E : Unqual!E))
|
||||||
|
{
|
||||||
|
private alias MutableE = Unqual!E;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
private alias MutableE = E;
|
||||||
|
}
|
||||||
|
|
||||||
|
private R _input;
|
||||||
|
private Tuple!(MutableE, uint) _current;
|
||||||
|
|
||||||
|
///
|
||||||
|
this(R input)
|
||||||
|
{
|
||||||
|
_input = input;
|
||||||
|
if (!_input.empty) popFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void popFront()
|
||||||
|
{
|
||||||
|
if (_input.empty)
|
||||||
|
{
|
||||||
|
_current[1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_current = tuple(_input.front, 1u);
|
||||||
|
_input.popFront();
|
||||||
|
while (!_input.empty && comp(_current[0], _input.front))
|
||||||
|
{
|
||||||
|
++_current[1];
|
||||||
|
_input.popFront();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (isInfinite!R)
|
||||||
|
{
|
||||||
|
///
|
||||||
|
enum bool empty = false; // Propagate infiniteness.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
///
|
||||||
|
@property bool empty()
|
||||||
|
{
|
||||||
|
return _current[1] == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@property auto ref front()
|
||||||
|
{
|
||||||
|
assert(!empty);
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (isForwardRange!R) {
|
||||||
|
///
|
||||||
|
@property typeof(this) save() {
|
||||||
|
typeof(this) ret = this;
|
||||||
|
ret._input = this._input.save;
|
||||||
|
ret._current = this._current;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
|
@ -4874,13 +4880,31 @@ private struct UniqResult(alias pred, Range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// permutations
|
/**
|
||||||
|
Lazily computes all _permutations of $(D r) using $(WEB
|
||||||
|
en.wikipedia.org/wiki/Heap%27s_algorithm, Heap's algorithm).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A forward range the elements of which are an $(XREF range,
|
||||||
|
indexed) view into $(D r).
|
||||||
|
|
||||||
|
See_Also:
|
||||||
|
$(XREF_PACK algorithm,sorting,nextPermutation).
|
||||||
|
*/
|
||||||
|
Permutations!Range permutations(Range)(Range r)
|
||||||
|
if (isRandomAccessRange!Range && hasLength!Range)
|
||||||
|
{
|
||||||
|
return typeof(return)(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
struct Permutations(Range)
|
struct Permutations(Range)
|
||||||
if (isRandomAccessRange!Range && hasLength!Range)
|
if (isRandomAccessRange!Range && hasLength!Range)
|
||||||
{
|
{
|
||||||
size_t[] indices, state;
|
size_t[] indices, state;
|
||||||
Range r;
|
Range r;
|
||||||
|
|
||||||
|
///
|
||||||
this(Range r)
|
this(Range r)
|
||||||
{
|
{
|
||||||
import std.range : iota;
|
import std.range : iota;
|
||||||
|
@ -4892,14 +4916,17 @@ struct Permutations(Range)
|
||||||
empty = r.length == 0;
|
empty = r.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
bool empty;
|
bool empty;
|
||||||
|
|
||||||
|
///
|
||||||
@property auto front()
|
@property auto front()
|
||||||
{
|
{
|
||||||
import std.range : indexed;
|
import std.range : indexed;
|
||||||
return r.indexed(indices);
|
return r.indexed(indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
void next(int n)
|
void next(int n)
|
||||||
|
@ -4928,23 +4955,6 @@ struct Permutations(Range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Lazily computes all _permutations of $(D r) using $(WEB
|
|
||||||
en.wikipedia.org/wiki/Heap%27s_algorithm, Heap's algorithm).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A forward range the elements of which are an $(XREF range,
|
|
||||||
indexed) view into $(D r).
|
|
||||||
|
|
||||||
See_Also:
|
|
||||||
$(XREF_PACK algorithm,sorting,nextPermutation).
|
|
||||||
*/
|
|
||||||
Permutations!Range permutations(Range)(Range r)
|
|
||||||
if (isRandomAccessRange!Range && hasLength!Range)
|
|
||||||
{
|
|
||||||
return typeof(return)(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
|
|
|
@ -1667,7 +1667,7 @@ if (s != SwapStrategy.stable
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ditto
|
/// Ditto
|
||||||
Range remove
|
Range remove
|
||||||
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
|
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
|
||||||
(Range range, Offset offset)
|
(Range range, Offset offset)
|
||||||
|
@ -2380,8 +2380,9 @@ unittest
|
||||||
swap(b1, b2);
|
swap(b1, b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not yet documented
|
/// ditto
|
||||||
void swap(T)(ref T lhs, ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))
|
void swap(T)(ref T lhs, ref T rhs)
|
||||||
|
if (is(typeof(lhs.proxySwap(rhs))))
|
||||||
{
|
{
|
||||||
lhs.proxySwap(rhs);
|
lhs.proxySwap(rhs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,6 +321,7 @@ is ignored.
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
this(Range needle)
|
this(Range needle)
|
||||||
{
|
{
|
||||||
if (!needle.length) return;
|
if (!needle.length) return;
|
||||||
|
@ -347,6 +348,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
Range beFound(Range haystack)
|
Range beFound(Range haystack)
|
||||||
{
|
{
|
||||||
import std.algorithm.comparison : max;
|
import std.algorithm.comparison : max;
|
||||||
|
@ -368,11 +370,13 @@ public:
|
||||||
return haystack[$ .. $];
|
return haystack[$ .. $];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property size_t length()
|
@property size_t length()
|
||||||
{
|
{
|
||||||
return needle.length;
|
return needle.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
alias opDollar = length;
|
alias opDollar = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1776,8 +1780,7 @@ if (isForwardRange!R1 && isForwardRange!R2
|
||||||
assert(equal(r, SList!int(2, 5, 7, 3)[]));
|
assert(equal(r, SList!int(2, 5, 7, 3)[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialization for searching a random-access range for a
|
/// ditto
|
||||||
// bidirectional range
|
|
||||||
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
if (isRandomAccessRange!R1 && isBidirectionalRange!R2
|
if (isRandomAccessRange!R1 && isBidirectionalRange!R2
|
||||||
&& is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
&& is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
||||||
|
@ -1786,9 +1789,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
|
||||||
const needleLength = walkLength(needle.save);
|
const needleLength = walkLength(needle.save);
|
||||||
if (needleLength > haystack.length)
|
if (needleLength > haystack.length)
|
||||||
{
|
{
|
||||||
// @@@BUG@@@
|
return haystack[$ .. $];
|
||||||
//return haystack[$ .. $];
|
|
||||||
return haystack[haystack.length .. haystack.length];
|
|
||||||
}
|
}
|
||||||
// @@@BUG@@@
|
// @@@BUG@@@
|
||||||
// auto needleBack = moveBack(needle);
|
// auto needleBack = moveBack(needle);
|
||||||
|
@ -1848,8 +1849,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
|
||||||
//assert(find!"a == b"("abc", "bc").length == 2);
|
//assert(find!"a == b"("abc", "bc").length == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leftover specialization: searching a random-access range for a
|
/// ditto
|
||||||
// non-bidirectional forward range
|
|
||||||
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
if (isRandomAccessRange!R1 && isForwardRange!R2 && !isBidirectionalRange!R2 &&
|
if (isRandomAccessRange!R1 && isForwardRange!R2 && !isBidirectionalRange!R2 &&
|
||||||
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
||||||
|
@ -3861,96 +3861,6 @@ enum OpenRight
|
||||||
yes /// Interval is open to the right (last element is not included)
|
yes /// Interval is open to the right (last element is not included)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
|
|
||||||
{
|
|
||||||
private Range _input;
|
|
||||||
static if (!is(Sentinel == void))
|
|
||||||
private Sentinel _sentinel;
|
|
||||||
// mixin(bitfields!(
|
|
||||||
// OpenRight, "_openRight", 1,
|
|
||||||
// bool, "_done", 1,
|
|
||||||
// uint, "", 6));
|
|
||||||
// OpenRight, "_openRight", 1,
|
|
||||||
// bool, "_done", 1,
|
|
||||||
OpenRight _openRight;
|
|
||||||
bool _done;
|
|
||||||
|
|
||||||
static if (!is(Sentinel == void))
|
|
||||||
this(Range input, Sentinel sentinel,
|
|
||||||
OpenRight openRight = OpenRight.yes)
|
|
||||||
{
|
|
||||||
_input = input;
|
|
||||||
_sentinel = sentinel;
|
|
||||||
_openRight = openRight;
|
|
||||||
_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);
|
|
||||||
return _input.front;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool predSatisfied()
|
|
||||||
{
|
|
||||||
static if (is(Sentinel == void))
|
|
||||||
return cast(bool) unaryFun!pred(_input.front);
|
|
||||||
else
|
|
||||||
return cast(bool) startsWith!pred(_input, _sentinel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void popFront()
|
|
||||||
{
|
|
||||||
assert(!empty);
|
|
||||||
if (!_openRight)
|
|
||||||
{
|
|
||||||
_done = predSatisfied();
|
|
||||||
_input.popFront();
|
|
||||||
_done = _done || _input.empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_input.popFront();
|
|
||||||
_done = _input.empty || predSatisfied();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static if (isForwardRange!Range)
|
|
||||||
{
|
|
||||||
static if (!is(Sentinel == void))
|
|
||||||
@property Until save()
|
|
||||||
{
|
|
||||||
Until result = this;
|
|
||||||
result._input = _input.save;
|
|
||||||
result._sentinel = _sentinel;
|
|
||||||
result._openRight = _openRight;
|
|
||||||
result._done = _done;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
@property Until save()
|
|
||||||
{
|
|
||||||
Until result = this;
|
|
||||||
result._input = _input.save;
|
|
||||||
result._openRight = _openRight;
|
|
||||||
result._done = _done;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Lazily iterates $(D range) _until the element $(D e) for which
|
Lazily iterates $(D range) _until the element $(D e) for which
|
||||||
$(D pred(e, sentinel)) is true.
|
$(D pred(e, sentinel)) is true.
|
||||||
|
@ -3987,6 +3897,104 @@ until(alias pred, Range)
|
||||||
return typeof(return)(range, openRight);
|
return typeof(return)(range, openRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
|
||||||
|
{
|
||||||
|
private Range _input;
|
||||||
|
static if (!is(Sentinel == void))
|
||||||
|
private Sentinel _sentinel;
|
||||||
|
// mixin(bitfields!(
|
||||||
|
// OpenRight, "_openRight", 1,
|
||||||
|
// bool, "_done", 1,
|
||||||
|
// uint, "", 6));
|
||||||
|
// OpenRight, "_openRight", 1,
|
||||||
|
// bool, "_done", 1,
|
||||||
|
OpenRight _openRight;
|
||||||
|
bool _done;
|
||||||
|
|
||||||
|
static if (!is(Sentinel == void))
|
||||||
|
///
|
||||||
|
this(Range input, Sentinel sentinel,
|
||||||
|
OpenRight openRight = OpenRight.yes)
|
||||||
|
{
|
||||||
|
_input = input;
|
||||||
|
_sentinel = sentinel;
|
||||||
|
_openRight = openRight;
|
||||||
|
_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);
|
||||||
|
return _input.front;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool predSatisfied()
|
||||||
|
{
|
||||||
|
static if (is(Sentinel == void))
|
||||||
|
return cast(bool) unaryFun!pred(_input.front);
|
||||||
|
else
|
||||||
|
return cast(bool) startsWith!pred(_input, _sentinel);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void popFront()
|
||||||
|
{
|
||||||
|
assert(!empty);
|
||||||
|
if (!_openRight)
|
||||||
|
{
|
||||||
|
_done = predSatisfied();
|
||||||
|
_input.popFront();
|
||||||
|
_done = _done || _input.empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_input.popFront();
|
||||||
|
_done = _input.empty || predSatisfied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (isForwardRange!Range)
|
||||||
|
{
|
||||||
|
static if (!is(Sentinel == void))
|
||||||
|
///
|
||||||
|
@property Until save()
|
||||||
|
{
|
||||||
|
Until result = this;
|
||||||
|
result._input = _input.save;
|
||||||
|
result._sentinel = _sentinel;
|
||||||
|
result._openRight = _openRight;
|
||||||
|
result._done = _done;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
///
|
||||||
|
@property Until save()
|
||||||
|
{
|
||||||
|
Until result = this;
|
||||||
|
result._input = _input.save;
|
||||||
|
result._openRight = _openRight;
|
||||||
|
result._done = _done;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
|
|
|
@ -788,6 +788,8 @@ struct NWayUnion(alias less, RangeOfRanges)
|
||||||
private alias ElementType = .ElementType!(.ElementType!RangeOfRanges);
|
private alias ElementType = .ElementType!(.ElementType!RangeOfRanges);
|
||||||
private alias comp = binaryFun!less;
|
private alias comp = binaryFun!less;
|
||||||
private RangeOfRanges _ror;
|
private RangeOfRanges _ror;
|
||||||
|
|
||||||
|
///
|
||||||
static bool compFront(.ElementType!RangeOfRanges a,
|
static bool compFront(.ElementType!RangeOfRanges a,
|
||||||
.ElementType!RangeOfRanges b)
|
.ElementType!RangeOfRanges b)
|
||||||
{
|
{
|
||||||
|
@ -796,6 +798,7 @@ struct NWayUnion(alias less, RangeOfRanges)
|
||||||
}
|
}
|
||||||
BinaryHeap!(RangeOfRanges, compFront) _heap;
|
BinaryHeap!(RangeOfRanges, compFront) _heap;
|
||||||
|
|
||||||
|
///
|
||||||
this(RangeOfRanges ror)
|
this(RangeOfRanges ror)
|
||||||
{
|
{
|
||||||
import std.algorithm.mutation : remove, SwapStrategy;
|
import std.algorithm.mutation : remove, SwapStrategy;
|
||||||
|
@ -807,13 +810,16 @@ struct NWayUnion(alias less, RangeOfRanges)
|
||||||
_heap.acquire(_ror);
|
_heap.acquire(_ror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property bool empty() { return _ror.empty; }
|
@property bool empty() { return _ror.empty; }
|
||||||
|
|
||||||
|
///
|
||||||
@property auto ref front()
|
@property auto ref front()
|
||||||
{
|
{
|
||||||
return _heap.front.front;
|
return _heap.front.front;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
_heap.removeFront();
|
_heap.removeFront();
|
||||||
|
@ -900,6 +906,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
this(R1 r1, R2 r2)
|
this(R1 r1, R2 r2)
|
||||||
{
|
{
|
||||||
this.r1 = r1;
|
this.r1 = r1;
|
||||||
|
@ -908,12 +915,14 @@ public:
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
r1.popFront();
|
r1.popFront();
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property auto ref front()
|
@property auto ref front()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -922,6 +931,7 @@ public:
|
||||||
|
|
||||||
static if (isForwardRange!R1 && isForwardRange!R2)
|
static if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
{
|
{
|
||||||
|
///
|
||||||
@property typeof(this) save()
|
@property typeof(this) save()
|
||||||
{
|
{
|
||||||
auto ret = this;
|
auto ret = this;
|
||||||
|
@ -931,6 +941,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property bool empty() { return r1.empty; }
|
@property bool empty() { return r1.empty; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1010,6 +1021,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
this(Rs input)
|
this(Rs input)
|
||||||
{
|
{
|
||||||
this._input = input;
|
this._input = input;
|
||||||
|
@ -1017,6 +1029,7 @@ public:
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property bool empty()
|
@property bool empty()
|
||||||
{
|
{
|
||||||
foreach (ref r; _input)
|
foreach (ref r; _input)
|
||||||
|
@ -1026,6 +1039,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -1042,6 +1056,7 @@ public:
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property ElementType front()
|
@property ElementType front()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -1050,6 +1065,7 @@ public:
|
||||||
|
|
||||||
static if (allSatisfy!(isForwardRange, Rs))
|
static if (allSatisfy!(isForwardRange, Rs))
|
||||||
{
|
{
|
||||||
|
///
|
||||||
@property SetIntersection save()
|
@property SetIntersection save()
|
||||||
{
|
{
|
||||||
auto ret = this;
|
auto ret = this;
|
||||||
|
@ -1158,6 +1174,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
this(R1 r1, R2 r2)
|
this(R1 r1, R2 r2)
|
||||||
{
|
{
|
||||||
this.r1 = r1;
|
this.r1 = r1;
|
||||||
|
@ -1166,6 +1183,7 @@ public:
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -1187,6 +1205,7 @@ public:
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property auto ref front()
|
@property auto ref front()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -1197,6 +1216,7 @@ public:
|
||||||
|
|
||||||
static if (isForwardRange!R1 && isForwardRange!R2)
|
static if (isForwardRange!R1 && isForwardRange!R2)
|
||||||
{
|
{
|
||||||
|
///
|
||||||
@property typeof(this) save()
|
@property typeof(this) save()
|
||||||
{
|
{
|
||||||
auto ret = this;
|
auto ret = this;
|
||||||
|
@ -1206,8 +1226,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
ref auto opSlice() { return this; }
|
ref auto opSlice() { return this; }
|
||||||
|
|
||||||
|
///
|
||||||
@property bool empty() { return r1.empty && r2.empty; }
|
@property bool empty() { return r1.empty && r2.empty; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,17 +1322,20 @@ public:
|
||||||
static assert(!is(CommonType!(staticMap!(.ElementType, Rs)) == void),
|
static assert(!is(CommonType!(staticMap!(.ElementType, Rs)) == void),
|
||||||
typeof(this).stringof ~ ": incompatible element types.");
|
typeof(this).stringof ~ ": incompatible element types.");
|
||||||
|
|
||||||
|
///
|
||||||
this(Rs rs)
|
this(Rs rs)
|
||||||
{
|
{
|
||||||
this._r = rs;
|
this._r = rs;
|
||||||
adjustPosition();
|
adjustPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property bool empty()
|
@property bool empty()
|
||||||
{
|
{
|
||||||
return _crt == _crt.max;
|
return _crt == _crt.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
// Assumes _crt is correct
|
// Assumes _crt is correct
|
||||||
|
@ -1327,6 +1352,7 @@ public:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property auto ref ElementType front()
|
@property auto ref ElementType front()
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
|
@ -1342,6 +1368,7 @@ public:
|
||||||
|
|
||||||
static if (allSatisfy!(isForwardRange, Rs))
|
static if (allSatisfy!(isForwardRange, Rs))
|
||||||
{
|
{
|
||||||
|
///
|
||||||
@property auto save()
|
@property auto save()
|
||||||
{
|
{
|
||||||
auto ret = this;
|
auto ret = this;
|
||||||
|
@ -1355,6 +1382,7 @@ public:
|
||||||
|
|
||||||
static if (allSatisfy!(hasLength, Rs))
|
static if (allSatisfy!(hasLength, Rs))
|
||||||
{
|
{
|
||||||
|
///
|
||||||
@property size_t length()
|
@property size_t length()
|
||||||
{
|
{
|
||||||
size_t result;
|
size_t result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue