RosettaCodeData/Task/Queue-Usage/D/queue-usage-2.d

76 lines
1.9 KiB
D
Raw Permalink Normal View History

2013-04-10 23:57:08 -07:00
module queue_usage2;
2015-02-20 00:35:01 -05:00
import std.traits: hasIndirections;
2013-04-10 23:57:08 -07:00
struct GrowableCircularQueue(T) {
public size_t length;
2015-02-20 00:35:01 -05:00
private size_t first, last;
2013-04-10 23:57:08 -07:00
private T[] A = [T.init];
2015-02-20 00:35:01 -05:00
this(T[] items...) pure nothrow @safe {
foreach (x; items)
push(x);
}
@property bool empty() const pure nothrow @safe @nogc {
2013-04-10 23:57:08 -07:00
return length == 0;
}
2015-02-20 00:35:01 -05:00
@property T front() pure nothrow @safe @nogc {
assert(length != 0);
return A[first];
}
T opIndex(in size_t i) pure nothrow @safe @nogc {
assert(i < length);
return A[(first + i) & (A.length - 1)];
}
void push(T item) pure nothrow @safe {
2013-04-10 23:57:08 -07:00
if (length >= A.length) { // Double the queue.
2015-02-20 00:35:01 -05:00
immutable oldALen = A.length;
A.length *= 2;
if (last < first) {
A[oldALen .. oldALen + last + 1] = A[0 .. last + 1];
static if (hasIndirections!T)
A[0 .. last + 1] = T.init; // Help for the GC.
last += oldALen;
}
2013-04-10 23:57:08 -07:00
}
2015-02-20 00:35:01 -05:00
last = (last + 1) & (A.length - 1);
A[last] = item;
2013-04-10 23:57:08 -07:00
length++;
}
2015-02-20 00:35:01 -05:00
@property T pop() pure nothrow @safe @nogc {
assert(length != 0);
auto saved = A[first];
2013-04-10 23:57:08 -07:00
static if (hasIndirections!T)
2015-02-20 00:35:01 -05:00
A[first] = T.init; // Help for the GC.
first = (first + 1) & (A.length - 1);
2013-04-10 23:57:08 -07:00
length--;
return saved;
}
}
version (queue_usage2_main) {
2015-02-20 00:35:01 -05:00
void main() {
GrowableCircularQueue!int q;
2013-04-10 23:57:08 -07:00
q.push(10);
q.push(20);
q.push(30);
2015-02-20 00:35:01 -05:00
assert(q.pop == 10);
assert(q.pop == 20);
assert(q.pop == 30);
assert(q.empty);
2013-04-10 23:57:08 -07:00
uint count = 0;
foreach (immutable i; 1 .. 1_000) {
foreach (immutable j; 0 .. i)
q.push(count++);
foreach (immutable j; 0 .. i)
2015-02-20 00:35:01 -05:00
q.pop;
2013-04-10 23:57:08 -07:00
}
}
}