blob: 8ea515c164a56b6e24fa8702903fc9b13c6ecfec [file] [log] [blame]
/* REQUIRED_ARGS: -O -release -inline
This compares two different ways to do a for loop. The range
version should SROA the VecRange struct into two register variables.
*/
extern (C):
nothrow:
@nogc:
@safe:
alias vec_base_t = size_t; // base type of vector
alias vec_t = vec_base_t*;
@trusted
pure
size_t vec_index(size_t b, const vec_t vec);
@trusted
pure ref inout(vec_base_t) vec_numbits(inout vec_t v) { return v[-1]; }
@trusted
pure ref inout(vec_base_t) vec_dim(inout vec_t v) { return v[-2]; }
struct VecRange
{
size_t i;
const vec_t v;
@nogc @safe nothrow pure:
this(const vec_t v) { this.v = v; i = vec_index(0, v); }
bool empty() const { return i == vec_numbits(v); }
size_t front() const { return i; }
void popFront() { i = vec_index(i + 1, v); }
}
@safe
pure
uint vec_numBitsSet(const vec_t vec)
{
uint n = 0;
size_t length = vec_numbits(vec);
for (size_t i = 0; (i = vec_index(i, vec)) < length; ++i)
++n;
return n;
}
@safe
pure
uint vec_numBitsSet2(const vec_t vec)
{
uint n = 0;
foreach (j; VecRange(vec))
++n;
return n;
}