C++ Container equivalents
Downs
default_357-line at yahoo.de
Tue Aug 14 23:36:40 PDT 2007
Bruce Adams wrote:
> Most of the time D arrays should be enough. In C++ I end up using
> vector, map and set the most. The set is the main one I want
> to identify an equivalent to.
This is kind of embarrassing, because there's no such thing as sets in
D, natively. The closest you can come is probably bool[Type], that is,
an associative array.
Regarding lists, here's a proto-implementation I threw together.
Basic functionality is missing, but you should get the idea. The actual
struct is Phobos/Tango-agnostic.
Have fun!
--downs
struct list(T) {
private {
static struct entry {
T value=void;
entry *next=null, prev=null;
}
entry *first=null, last=null;
void update(bool left)(entry *e, entry *newEntry) {
static if(left) {
if (e==first) first=newEntry;
else { e.prev.next=newEntry; newEntry.prev=e.prev; }
} else {
if (e==last) last=newEntry;
else { e.next.prev=newEntry; newEntry.next=e.next; }
}
// at this point we have effectively removed e.
// but we keep it around to prevent the GC from wailing in anguish
// delete e;
}
}
static list opCall(T[] init) {
list res;
foreach (entry; init) res.push_back(entry);
return res;
}
static list opCall(entry *a, entry *b) { list res=void; res.first=a;
res.last=b; return res; }
void push(bool front)(T what) {
auto newEntry=new entry;
newEntry.value=what;
static if (front) {
if (first) { newEntry.next=first; first.prev=newEntry; }
first=newEntry;
if (!last) last=first;
}
else {
if (last) { newEntry.prev=last; last.next=newEntry; } last=newEntry;
if (!first) first=last;
}
}
bool opEquals(T[] comp) {
size_t count=0;
foreach (entry; *this) {
if (count==comp.length) return false;
if (comp[count++]!=entry) return false;
}
if (count!=comp.length) return false;
return true;
}
list opSlice(size_t from, size_t to) {
entry *start=first; while (from--) { start=start.next; to--; }
entry *end=start; while (--to) end=end.next;
return list(start, end);
}
void opSliceAssign(list what, size_t from, size_t to) {
entry *start=first; while (from--) { start=start.next; to--; }
entry *end=start; while (--to) end=end.next;
update!(true)(start, what.first);
update!(false)(end, what.last);
}
int opApply(int delegate(ref T) dg) {
entry *current=first;
writefln("_____");
scope(exit) writefln("'''''");
while (true) {
writefln("Entry ", current.value);
auto res=dg(current.value);
if (res) return res;
if (current==last) return 0;
current=current.next;
}
}
int opApply(int delegate(ref size_t, ref T) dg) {
size_t count=0;
foreach (ref entry; *this) { auto res=dg(count, entry); ++count; if
(res) return res; }
return 0;
}
alias push!(true) push_front; alias push!(false) push_back;
size_t length() { size_t res=0; foreach (bogus; *this) ++res; return
res; }
T[] toArray() { auto res=new T[length]; foreach (id, entry; *this)
res[id]=entry; return res; }
}
import std.stdio;
void main() {
list!(int) test;
test.push_back(5);
test.push_front(4);
test.push_back(8);
writefln(test.toArray);
assert(test==[4, 5, 8]);
writefln(test[1..2].toArray);
assert(test[1..2]==[5]);
test[1..2]=list!(int)([6, 7]);
writefln(test.toArray);
assert(test==[4, 6, 7, 8]);
}
More information about the Digitalmars-d-learn
mailing list