Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 55 additions & 28 deletions std/range/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ The remainder of this module provides a rich set of _range creation and
composition templates that let you construct new ranges out of existing ranges:

$(BOOKTABLE ,
$(TR $(TD $(D $(LREF bitwise)))
$(TD Bitwise adapter over a integral type _range.
))
$(TR $(TD $(D $(LREF chain)))
$(TD Concatenates several ranges into a single _range.
))
Expand Down Expand Up @@ -9594,17 +9597,7 @@ auto refRange(R)(R* range)
foo(r);
}

/**
Bitwise adapter over integral type ranges. Consumes the range elements bit by bit.

Params:
R = an input range to iterate over

Returns:
At minimum, an input range. If `R` was a forward, bidirectional or random
access range, `Bitwise!R` will be as well.
*/
struct Bitwise(R)
private struct Bitwise(R)
if (isInputRange!R && isIntegral!(ElementType!R))
{
private:
Expand Down Expand Up @@ -9635,7 +9628,7 @@ public:
{
static if (hasLength!R)
{
return length() == 0;
return length == 0;
}
else static if (isBidirectionalRange!R)
{
Expand Down Expand Up @@ -9664,7 +9657,7 @@ public:

bool front()
{
assert(!empty());
assert(!empty);
return (parent.front & mask(maskPos)) != 0;
}

Expand Down Expand Up @@ -9707,12 +9700,13 @@ public:
{
bool back()
{
assert(!empty());
assert(!empty);
return (parent.back & mask(backMaskPos)) != 0;
}

void popBack()
{
assert(!empty);
++backMaskPos;
if (backMaskPos > bitsNum)
{
Expand All @@ -9736,7 +9730,7 @@ public:
*/
static if (hasLength!R)
{
assert(n < length(), __PRETTY_FUNCTION__ ~ ": Index out of bounds");
assert(n < length, "Index out of bounds");
}
}
body
Expand Down Expand Up @@ -9765,14 +9759,14 @@ public:
}

/**
Assignes `flag` to the `n`th bit within the range
Assigns `flag` to the `n`th bit within the range
*/
void opIndexAssign(bool flag, size_t n)
in
{
static if (hasLength!R)
{
assert(n < length(), __PRETTY_FUNCTION__ ~ ": Index out of bounds");
assert(n < length, "Index out of bounds");
}
}
body
Expand All @@ -9792,13 +9786,13 @@ public:

Bitwise!R opSlice()
{
return this;
return this.save;
}

Bitwise!R opSlice(size_t start, size_t end)
in
{
assert(start < end, __PRETTY_FUNCTION__ ~ ": Invalid bounds: end <= start");
assert(start < end, "Invalid bounds: end <= start");
}
body
{
Expand Down Expand Up @@ -9834,9 +9828,43 @@ private:
}
}

// Test all range types over all integral types
/**
Bitwise adapter over a integral type range. Consumes the range elements bit by bit.

Params:
R = an integral input range to iterate over

Returns:
A `Bitwise` input range with propagated forward, bidirectional
and random access capabilities
*/
auto bitwise(R)(auto ref R range)
if (isInputRange!R && isIntegral!(ElementType!R))
{
return Bitwise!R(range);
}

///
@safe unittest
@safe pure unittest
{
import std.algorithm.comparison : equal;
import std.format : format;

// 00000011 00001001
ubyte[] arr = [3, 9];
auto r = arr.bitwise;

// iterate through it as with any other range
assert(format("%(%d%)", r) == "0000001100001001");
assert(format("%(%d%)", r.retro).equal("0000001100001001".retro));

// set a bit
r[5] = 1;
assert(arr[0] == 7);
}

// Test all range types over all integral types
@safe pure nothrow unittest
{
import std.internal.test.dummyrange;

Expand Down Expand Up @@ -9874,12 +9902,12 @@ private:
long numCalls = 42;
bool initialFrontValue;

if (!bw.empty())
if (!bw.empty)
{
initialFrontValue = bw.front;
}

while (!bw.empty() && (--numCalls))
while (!bw.empty && (--numCalls))
{
bw.front;
assert(bw.front == initialFrontValue);
Expand All @@ -9890,7 +9918,7 @@ private:
more times than it should
*/
numCalls = 0;
while (!bw.empty())
while (!bw.empty)
{
++numCalls;

Expand All @@ -9917,22 +9945,21 @@ private:

auto rangeLen = numCalls / (IntegralType.sizeof * 8);
assert(numCalls == (IntegralType.sizeof * 8 * rangeLen));
assert(bw.empty());
assert(bw.empty);
static if (isForwardRange!T)
{
assert(bw2.empty());
assert(bw2.empty);
}

static if (isBidirectionalRange!T)
{
assert(bw3.empty());
assert(bw3.empty);
}
}
}
}

// Test opIndex and opSlice
///
@system unittest
{
alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,
Expand Down