Add alias opDollar and use $ in range slicing

This commit is contained in:
k-hara 2012-11-27 10:34:56 +09:00
parent 24b7d423d2
commit 07104b5fe6
5 changed files with 72 additions and 78 deletions

View file

@ -534,7 +534,7 @@ unittest
assert(squares[3] == 16);
// Test slicing.
auto squareSlice = squares[1..squares.length - 1];
auto squareSlice = squares[1..$-1];
assert(equal(squareSlice, [4, 9][]));
assert(squareSlice.back == 9);
assert(squareSlice[1] == 9);
@ -2111,7 +2111,7 @@ if (is(typeof(ElementType!Range.init == Separator.init))
}
else
{
_input = _input[_frontLength .. _input.length];
_input = _input[_frontLength .. $];
skipOver(_input, _separator) || assert(false);
_frontLength = _unComputed;
}
@ -2144,7 +2144,7 @@ if (is(typeof(ElementType!Range.init == Separator.init))
_backLength = _input.length - lastIndex - 1;
}
}
return _input[_input.length - _backLength .. _input.length];
return _input[$ - _backLength .. $];
}
void popBack()
@ -2164,7 +2164,7 @@ if (is(typeof(ElementType!Range.init == Separator.init))
}
else
{
_input = _input[0 .. _input.length - _backLength];
_input = _input[0 .. $ - _backLength];
if (!_input.empty && _input.back == _separator)
{
_input.popBack();
@ -2342,7 +2342,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
{
// Special case: popping the first-to-last item; there is
// an empty item right after this.
_input = _input[_input.length .. _input.length];
_input = _input[$ .. $];
_frontLength = 0;
static if (isBidirectionalRange!Range)
_backLength = 0;
@ -2350,7 +2350,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
}
// Normal case, pop one item and the separator, get ready for
// reading the next item
_input = _input[_frontLength + separatorLength .. _input.length];
_input = _input[_frontLength + separatorLength .. $];
// mark _frontLength as uninitialized
_frontLength = _frontLength.max;
}
@ -2371,7 +2371,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
@property Range back()
{
ensureBackLength();
return _input[_input.length - _backLength .. _input.length];
return _input[$ - _backLength .. $];
}
void popBack()
@ -2395,7 +2395,7 @@ if (is(typeof(Range.init.front == Separator.init.front) : bool)
return;
}
// Normal case
_input = _input[0 .. _input.length - _backLength - separatorLength];
_input = _input[0 .. $ - _backLength - separatorLength];
_backLength = _backLength.max;
}
}
@ -2511,7 +2511,7 @@ private struct SplitterResult(alias isTerminator, Range)
return;
}
// Skip over existing word
_input = _input[_end .. _input.length];
_input = _input[_end .. $];
// Skip terminator
for (;;)
{
@ -3299,9 +3299,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);
@ -3319,7 +3317,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
{
if (scout >= haystack.length)
{
return haystack[haystack.length .. haystack.length];
return haystack[$ .. $];
}
if (!binaryFun!pred(haystack[scout], needleBack))
{
@ -3327,7 +3325,7 @@ if (isRandomAccessRange!R1 && isBidirectionalRange!R2
continue;
}
// Found a match with the last element in the needle
auto cand = haystack[scout + 1 - needleLength .. haystack.length];
auto cand = haystack[scout + 1 - needleLength .. $];
if (startsWith!pred(cand, needle))
{
// found
@ -3476,9 +3474,8 @@ unittest
// Failed search
static if (hasLength!R1)
{
static if (is(typeof(haystack[haystack.length ..
haystack.length]) : R1))
return haystack[haystack.length .. haystack.length];
static if (is(typeof(haystack[$ .. $]) : R1))
return haystack[$ .. $];
else
return R1.init;
}
@ -3718,7 +3715,7 @@ is ignored.
return 0;
immutable delta = portion - ignore;
return equal(needle[needle.length - delta .. needle.length],
return equal(needle[$ - delta .. $],
needle[virtual_begin .. virtual_begin + delta]);
}
@ -3948,7 +3945,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
return tuple(haystack[0 .. pos1],
haystack[pos1 .. pos2],
haystack[pos2 .. haystack.length]);
haystack[pos2 .. $]);
}
else
{
@ -3987,7 +3984,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
{
auto balance = find!pred(haystack, needle);
immutable pos = haystack.length - balance.length;
return tuple(haystack[0 .. pos], haystack[pos .. haystack.length]);
return tuple(haystack[0 .. pos], haystack[pos .. $]);
}
else
{
@ -4023,7 +4020,7 @@ if (isForwardRange!R1 && isForwardRange!R2)
{
auto balance = find!pred(haystack, needle);
immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;
return tuple(haystack[0 .. pos], haystack[pos .. haystack.length]);
return tuple(haystack[0 .. pos], haystack[pos .. $]);
}
else
{
@ -7024,8 +7021,8 @@ Range partition(alias predicate,
alias .partition!(pred, ss, Range) recurse;
auto lower = recurse(r[0 .. middle]);
auto upper = recurse(r[middle .. $]);
bringToFront(lower, r[middle .. r.length - upper.length]);
return r[r.length - lower.length - upper.length .. r.length];
bringToFront(lower, r[middle .. $ - upper.length]);
return r[$ - lower.length - upper.length .. $];
}
else static if (ss == SwapStrategy.semistable)
{
@ -7226,10 +7223,10 @@ if (ss == SwapStrategy.unstable && isRandomAccessRange!Range
auto swapLen = min(i, strictlyLess);
swapRanges(r[0 .. swapLen], r[j - swapLen .. j]);
swapLen = min(r.length - l, strictlyGreater);
swapRanges(r[k .. k + swapLen], r[r.length - swapLen .. r.length]);
swapRanges(r[k .. k + swapLen], r[$ - swapLen .. $]);
return tuple(r[0 .. strictlyLess],
r[strictlyLess .. r.length - strictlyGreater],
r[r.length - strictlyGreater .. r.length]);
r[strictlyLess .. $ - strictlyGreater],
r[$ - strictlyGreater .. $]);
}
unittest
@ -7486,7 +7483,7 @@ sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
enum maxLen = 8;
assert(isSorted!lessFun(r), text("Failed to sort range of type ",
Range.stringof, ". Actual result is: ",
r[0 .. r.length > maxLen ? maxLen : r.length ],
r[0 .. $ > maxLen ? maxLen : $],
r.length > maxLen ? "..." : ""));
}
else
@ -7762,7 +7759,7 @@ private void sortImpl(alias less, SwapStrategy ss, Range)(Range r)
}
swapAt(r, r.length - 1, lessI);
auto right = r[lessI + 1..r.length];
auto right = r[lessI + 1 .. $];
auto left = r[0..min(lessI, greaterI + 1)];
if (right.length > left.length)
@ -7798,7 +7795,7 @@ private void sortImpl(alias less, SwapStrategy ss, Range)(Range r)
}
else
{
.sortImpl!(less, ss, Range)(r[0 .. r.length - right.length]);
.sortImpl!(less, ss, Range)(r[0 .. $ - right.length]);
r = right;
}
}
@ -7925,7 +7922,7 @@ unittest
/**
Reorders the random-access range $(D r) such that the range $(D r[0
.. mid]) is the same as if the entire $(D r) were sorted, and leaves
the range $(D r[mid .. r.length]) in no particular order. Performs
the range $(D r[mid .. $(DOLLAR)]) in no particular order. Performs
$(BIGOH r.length * log(mid)) evaluations of $(D pred). The
implementation simply calls $(D topN!(less, ss)(r, n)) and then $(D
sort!(less, ss)(r[0 .. n])).

View file

@ -495,7 +495,7 @@ unittest
{
assert(a.length, "Attempting to popBack() past the front of an array of " ~
typeof(a[0]).stringof);
a = a[0 .. $ - std.utf.strideBack(a, a.length)];
a = a[0 .. $ - std.utf.strideBack(a, $)];
}
unittest
@ -1235,12 +1235,12 @@ unittest
assert(cmp(words[3], "jerry") == 0);
assert(cmp(words[4], "") == 0);
auto s1 = s[0 .. s.length - 1]; // lop off trailing ','
auto s1 = s[0 .. $ - 1]; // lop off trailing ','
words = split(s1, ",");
assert(words.length == 4);
assert(cmp(words[3], "jerry") == 0);
auto s2 = s1[1 .. s1.length]; // lop off leading ','
auto s2 = s1[1 .. $]; // lop off leading ','
words = split(s2, ",");
assert(words.length == 3);
assert(cmp(words[0], "peter") == 0);
@ -1255,12 +1255,12 @@ unittest
assert(cmp(words[3], "jerry") == 0);
assert(cmp(words[4], "") == 0);
auto s4 = s3[0 .. s3.length - 2]; // lop off trailing ',,'
auto s4 = s3[0 .. $ - 2]; // lop off trailing ',,'
words = split(s4, ",,");
assert(words.length == 4);
assert(cmp(words[3], "jerry") == 0);
auto s5 = s4[2 .. s4.length]; // lop off leading ',,'
auto s5 = s4[2 .. $]; // lop off leading ',,'
words = split(s5, ",,");
assert(words.length == 3);
assert(cmp(words[0], "peter") == 0);
@ -1561,7 +1561,7 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2
return subject;
auto app = appender!(E[])();
app.put(subject[0 .. subject.length - balance.length]);
app.put(subject[0 .. $ - balance.length]);
app.put(to.save);
replaceInto(app, balance[from.length .. $], from, to);
@ -1590,7 +1590,7 @@ if (isOutputRange!(Sink, E) && isDynamicArray!(E[])
sink.put(subject);
break;
}
sink.put(subject[0 .. subject.length - balance.length]);
sink.put(subject[0 .. $ - balance.length]);
sink.put(to.save);
subject = balance[from.length .. $];
}
@ -1901,7 +1901,7 @@ if (isDynamicArray!(E[]) &&
auto balance = std.algorithm.find(subject, from.save);
if (balance.empty) return subject;
auto app = appender!(E[])();
app.put(subject[0 .. subject.length - balance.length]);
app.put(subject[0 .. $ - balance.length]);
app.put(to.save);
app.put(balance[from.length .. $]);
@ -1958,8 +1958,7 @@ body
immutable so = slice.ptr - s.ptr;
result[0 .. so] = s[0 .. so];
result[so .. so + replacement.length] = replacement[];
result[so + replacement.length .. result.length] =
s[so + slice.length .. s.length];
result[so + replacement.length .. $] = s[so + slice.length .. $];
return cast(inout(T)[]) result;
}
@ -2555,7 +2554,7 @@ struct SimpleSlice(T)
core.memory.GC.malloc(newLen * T.sizeof);
result._e = result._b + newLen;
result[0 .. this.length] = this;
result[this.length .. result.length] = another;
result[this.length .. $] = another;
return result;
}
@ -2609,8 +2608,8 @@ unittest
// assert(s[2] == 6);
// assert(s[] == s);
// assert(s[0 .. s.length] == s);
// assert(equal(s[0 .. s.length - 1], [4, 5][]));
// assert(s[0 .. $] == s);
// assert(equal(s[0 .. $ - 1], [4, 5][]));
// auto s1 = s ~ s[0 .. 1];
// assert(equal(s1, [4, 5, 6, 4][]));

View file

@ -2667,10 +2667,7 @@ Defines the container's primary range, which is a random-access range.
return _b - _a;
}
size_t opDollar() const
{
return length;
}
alias opDollar = length;
@property T front()
{
@ -2864,11 +2861,7 @@ Complexity: $(BIGOH 1).
}
/// ditto
size_t opDollar() const
{
// @@@BUG@@@ This doesn't work yet
return length;
}
alias opDollar = length;
/**
Returns the maximum number of elements the container can store without
@ -3284,8 +3277,7 @@ Complexity: $(BIGOH n + m), where $(D m) is the length of $(D stuff)
immutable offset = r._a;
enforce(offset <= length);
auto result = insertBack(stuff);
bringToFront(this[offset .. length - result],
this[length - result .. length]);
bringToFront(this[offset .. $ - result], this[$ - result .. $]);
return result;
}
}
@ -3298,8 +3290,7 @@ Complexity: $(BIGOH n + m), where $(D m) is the length of $(D stuff)
immutable offset = r._b;
enforce(offset <= length);
auto result = insertBack(stuff);
bringToFront(this[offset .. length - result],
this[length - result .. length]);
bringToFront(this[offset .. $ - result], this[$ - result .. $]);
return result;
}
@ -3364,9 +3355,9 @@ $(D r)
immutable offset2 = r._b;
immutable tailLength = length - offset2;
// Use copy here, not a[] = b[] because the ranges may overlap
copy(this[offset2 .. length], this[offset1 .. offset1 + tailLength]);
copy(this[offset2 .. $], this[offset1 .. offset1 + tailLength]);
length = offset1 + tailLength;
return this[length - tailLength .. length];
return this[$ - tailLength .. $];
}
/// ditto
alias remove stableLinearRemove;
@ -3445,7 +3436,7 @@ unittest
unittest
{
auto a = Array!int(1, 2, 3, 4, 5);
auto r = a[2 .. a.length];
auto r = a[2 .. $];
assert(a.insertBefore(r, 42) == 1);
assert(a == Array!int(1, 2, 42, 3, 4, 5));
r = a[2 .. 2];
@ -4154,6 +4145,8 @@ struct Array(T) if (is(T == bool))
assert(_a <= _b);
return _b - _a;
}
/// Ditto
alias opDollar = length;
}
/**
@ -4209,6 +4202,9 @@ struct Array(T) if (is(T == bool))
return _store.refCountedStore.isInitialized ? _store._length : 0;
}
/// ditto
alias opDollar = length;
unittest
{
Array!bool a;
@ -4800,9 +4796,9 @@ struct Array(T) if (is(T == bool))
*/
Range linearRemove(Range r)
{
copy(this[r._b .. length], this[r._a .. length]);
copy(this[r._b .. $], this[r._a .. $]);
length = length - r.length;
return this[r._a .. length];
return this[r._a .. $];
}
/// ditto
alias linearRemove stableLinearRemove;

View file

@ -1439,7 +1439,7 @@ if (isBidirectionalRange!(Unqual!Range))
static if (hasSlicing!R)
typeof(this) opSlice(IndexType a, IndexType b)
{
return typeof(this)(source[source.length - b .. source.length - a]);
return typeof(this)(source[$ - b .. $ - a]);
}
}
@ -1597,7 +1597,7 @@ if (isInputRange!(Unqual!Range))
if (!slack) return;
static if (isRandomAccessRange!R && hasSlicing!R)
{
source = source[0 .. source.length - slack];
source = source[0 .. $ - slack];
}
else static if (isBidirectionalRange!R)
{
@ -1653,7 +1653,7 @@ if (isInputRange!(Unqual!Range))
{
static if (isRandomAccessRange!R && hasLength!R && hasSlicing!R)
{
source = source[min(_n, source.length) .. source.length];
source = source[min(_n, $) .. $];
}
else
{
@ -1784,8 +1784,7 @@ unittest
assert(s1[1..5].length == 4);
assert(s1[0..0].empty);
assert(s1[3..3].empty);
// assert(s1[$ .. $].empty);
assert(s1[s1.opDollar() .. s1.opDollar()].empty);
assert(s1[$ .. $].empty);
auto s2 = stride(arr, 2);
assert(equal(s2[0..2], [1,3]));
@ -1794,8 +1793,7 @@ unittest
assert(s2[1..5].length == 4);
assert(s2[0..0].empty);
assert(s2[3..3].empty);
// assert(s2[$ .. $].empty);
assert(s2[s2.opDollar() .. s2.opDollar()].empty);
assert(s2[$ .. $].empty);
// Test fix for Bug 5035
auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns
@ -2460,7 +2458,7 @@ auto radial(Range, I)(Range r, I startingIndex)
if (isRandomAccessRange!(Unqual!Range) && hasLength!(Unqual!Range) && isIntegral!I)
{
if (!r.empty) ++startingIndex;
return roundRobin(retro(r[0 .. startingIndex]), r[startingIndex .. r.length]);
return roundRobin(retro(r[0 .. startingIndex]), r[startingIndex .. $]);
}
/// Ditto
@ -2694,9 +2692,7 @@ if (isInputRange!(Unqual!R) && hasSlicing!(Unqual!R))
{
static if (hasLength!R)
{
// @@@BUG@@@
//return input[0 .. min(n, $)];
return input[0 .. min(n, input.length)];
return input[0 .. min(n, $)];
}
else
{
@ -6244,7 +6240,7 @@ struct Chunks(Source) if(isInputRange!Source && hasSlicing!Source && hasLength!S
@property auto front()
{
assert(!empty);
return _source[0..min(_chunkSize, _source.length)];
return _source[0..min(_chunkSize, $)];
}
/// Ditto
@ -7250,7 +7246,7 @@ if (isRandomAccessRange!Range && hasLength!Range)
auto upperBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)
if (isTwoWayCompatible!(predFun, ElementType!Range, V))
{
return this[getTransitionIndex!(sp, gt)(value) .. length];
return this[getTransitionIndex!(sp, gt)(value) .. $];
}
// equalRange
@ -7363,11 +7359,11 @@ assert(equal(r[2], [ 4, 4, 5, 6 ]));
- this[it + 1 .. first]
.upperBound!(SearchPolicy.gallop)(value).length;
return tuple(this[0 .. left], this[left .. right],
this[right .. length]);
this[right .. $]);
}
}
// No equal element was found
return tuple(this[0 .. first], this.init, this[first .. length]);
return tuple(this[0 .. first], this.init, this[first .. $]);
}
// contains
@ -7964,6 +7960,9 @@ assert(buffer2 == [11, 12, 13, 14, 15]);
/++ Ditto +/
@property auto length() const {assert(0);}
/++ Ditto +/
alias opDollar = length;
}
else static if(hasLength!R)
{
@ -7972,10 +7971,13 @@ assert(buffer2 == [11, 12, 13, 14, 15]);
return (*_range).length;
}
static if(is(typeof((*cast(const R*)_range).length))) @property auto length() const
static if(is(typeof((*cast(const R*)_range).length)))
@property auto length() const
{
return (*_range).length;
}
alias opDollar = length;
}

View file

@ -567,7 +567,7 @@ static assert(Bytecode.sizeof == 4);
if(indent>0)
{
string spaces=" ";
put(sink,spaces[0..(indent%spaces.length)]);
put(sink, spaces[0..(indent%$)]);
for (size_t i=indent/spaces.length;i>0;--i)
put(sink,spaces);
}