Skip to content

Commit dc2109e

Browse files
authored
Merge pull request #4981 from wilzbach/bitwise-cleanup
First cleanup of bitwise adapter + add to docs
2 parents 6e9b56a + 8f72536 commit dc2109e

File tree

1 file changed

+55
-28
lines changed

1 file changed

+55
-28
lines changed

std/range/package.d

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ The remainder of this module provides a rich set of _range creation and
3333
composition templates that let you construct new ranges out of existing ranges:
3434
3535
$(BOOKTABLE ,
36+
$(TR $(TD $(D $(LREF bitwise)))
37+
$(TD Bitwise adapter over a integral type _range.
38+
))
3639
$(TR $(TD $(D $(LREF chain)))
3740
$(TD Concatenates several ranges into a single _range.
3841
))
@@ -9607,17 +9610,7 @@ auto refRange(R)(R* range)
96079610
foo(r);
96089611
}
96099612

9610-
/**
9611-
Bitwise adapter over integral type ranges. Consumes the range elements bit by bit.
9612-
9613-
Params:
9614-
R = an input range to iterate over
9615-
9616-
Returns:
9617-
At minimum, an input range. If `R` was a forward, bidirectional or random
9618-
access range, `Bitwise!R` will be as well.
9619-
*/
9620-
struct Bitwise(R)
9613+
private struct Bitwise(R)
96219614
if (isInputRange!R && isIntegral!(ElementType!R))
96229615
{
96239616
private:
@@ -9648,7 +9641,7 @@ public:
96489641
{
96499642
static if (hasLength!R)
96509643
{
9651-
return length() == 0;
9644+
return length == 0;
96529645
}
96539646
else static if (isBidirectionalRange!R)
96549647
{
@@ -9677,7 +9670,7 @@ public:
96779670

96789671
bool front()
96799672
{
9680-
assert(!empty());
9673+
assert(!empty);
96819674
return (parent.front & mask(maskPos)) != 0;
96829675
}
96839676

@@ -9720,12 +9713,13 @@ public:
97209713
{
97219714
bool back()
97229715
{
9723-
assert(!empty());
9716+
assert(!empty);
97249717
return (parent.back & mask(backMaskPos)) != 0;
97259718
}
97269719

97279720
void popBack()
97289721
{
9722+
assert(!empty);
97299723
++backMaskPos;
97309724
if (backMaskPos > bitsNum)
97319725
{
@@ -9749,7 +9743,7 @@ public:
97499743
*/
97509744
static if (hasLength!R)
97519745
{
9752-
assert(n < length(), __PRETTY_FUNCTION__ ~ ": Index out of bounds");
9746+
assert(n < length, "Index out of bounds");
97539747
}
97549748
}
97559749
body
@@ -9778,14 +9772,14 @@ public:
97789772
}
97799773

97809774
/**
9781-
Assignes `flag` to the `n`th bit within the range
9775+
Assigns `flag` to the `n`th bit within the range
97829776
*/
97839777
void opIndexAssign(bool flag, size_t n)
97849778
in
97859779
{
97869780
static if (hasLength!R)
97879781
{
9788-
assert(n < length(), __PRETTY_FUNCTION__ ~ ": Index out of bounds");
9782+
assert(n < length, "Index out of bounds");
97899783
}
97909784
}
97919785
body
@@ -9805,13 +9799,13 @@ public:
98059799

98069800
Bitwise!R opSlice()
98079801
{
9808-
return this;
9802+
return this.save;
98099803
}
98109804

98119805
Bitwise!R opSlice(size_t start, size_t end)
98129806
in
98139807
{
9814-
assert(start < end, __PRETTY_FUNCTION__ ~ ": Invalid bounds: end <= start");
9808+
assert(start < end, "Invalid bounds: end <= start");
98159809
}
98169810
body
98179811
{
@@ -9847,9 +9841,43 @@ private:
98479841
}
98489842
}
98499843

9850-
// Test all range types over all integral types
9844+
/**
9845+
Bitwise adapter over a integral type range. Consumes the range elements bit by bit.
9846+
9847+
Params:
9848+
R = an integral input range to iterate over
9849+
9850+
Returns:
9851+
A `Bitwise` input range with propagated forward, bidirectional
9852+
and random access capabilities
9853+
*/
9854+
auto bitwise(R)(auto ref R range)
9855+
if (isInputRange!R && isIntegral!(ElementType!R))
9856+
{
9857+
return Bitwise!R(range);
9858+
}
9859+
98519860
///
9852-
@safe unittest
9861+
@safe pure unittest
9862+
{
9863+
import std.algorithm.comparison : equal;
9864+
import std.format : format;
9865+
9866+
// 00000011 00001001
9867+
ubyte[] arr = [3, 9];
9868+
auto r = arr.bitwise;
9869+
9870+
// iterate through it as with any other range
9871+
assert(format("%(%d%)", r) == "0000001100001001");
9872+
assert(format("%(%d%)", r.retro).equal("0000001100001001".retro));
9873+
9874+
// set a bit
9875+
r[5] = 1;
9876+
assert(arr[0] == 7);
9877+
}
9878+
9879+
// Test all range types over all integral types
9880+
@safe pure nothrow unittest
98539881
{
98549882
import std.internal.test.dummyrange;
98559883

@@ -9887,12 +9915,12 @@ private:
98879915
long numCalls = 42;
98889916
bool initialFrontValue;
98899917

9890-
if (!bw.empty())
9918+
if (!bw.empty)
98919919
{
98929920
initialFrontValue = bw.front;
98939921
}
98949922

9895-
while (!bw.empty() && (--numCalls))
9923+
while (!bw.empty && (--numCalls))
98969924
{
98979925
bw.front;
98989926
assert(bw.front == initialFrontValue);
@@ -9903,7 +9931,7 @@ private:
99039931
more times than it should
99049932
*/
99059933
numCalls = 0;
9906-
while (!bw.empty())
9934+
while (!bw.empty)
99079935
{
99089936
++numCalls;
99099937

@@ -9930,22 +9958,21 @@ private:
99309958

99319959
auto rangeLen = numCalls / (IntegralType.sizeof * 8);
99329960
assert(numCalls == (IntegralType.sizeof * 8 * rangeLen));
9933-
assert(bw.empty());
9961+
assert(bw.empty);
99349962
static if (isForwardRange!T)
99359963
{
9936-
assert(bw2.empty());
9964+
assert(bw2.empty);
99379965
}
99389966

99399967
static if (isBidirectionalRange!T)
99409968
{
9941-
assert(bw3.empty());
9969+
assert(bw3.empty);
99429970
}
99439971
}
99449972
}
99459973
}
99469974

99479975
// Test opIndex and opSlice
9948-
///
99499976
@system unittest
99509977
{
99519978
alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,

0 commit comments

Comments
 (0)