Mercurial > projects > ddmd
view dmd/Array.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 347de076ad34 |
children | 52188e7e3fb5 |
line wrap: on
line source
module dmd.Array; import dmd.common; import core.memory; import std.exception; import core.stdc.string; import core.stdc.stdlib; import dmd.TObject; class Array : TObject { uint dim = 0; uint allocdim = 0; void** data = null; ~this() { ///mem.free(data); } void mark() { ///unsigned u; ///mem.mark(data); ///for (u = 0; u < dim; u++) ///mem.mark(data[u]); // BUG: what if arrays of Object's? } override string toString() { char *p; ///char **buf = cast(char**)alloca(dim * (char*).sizeof); scope string[] buf = new string[dim]; uint len = 2; for (uint u = 0; u < dim; u++) { buf[u] = (cast(Object)data[u]).toString(); len += buf[u].length + 1; } char* str = cast(char*)GC.malloc(len); str[0] = '['; p = str + 1; for (uint u = 0; u < dim; u++) { if (u != 0) { *p++ = ','; } uint length = buf[u].length; p[0..length] = buf[u][]; p += length; } *p++ = ']'; *p = 0; return assumeUnique(str[0..len]); } final void reserve(uint nentries) { //printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes); if (allocdim - dim < nentries) { allocdim = dim + nentries; data = cast(void**)GC.realloc(data, allocdim * (*data).sizeof); } } final void setDim(uint newdim) { if (dim < newdim) { reserve(newdim - dim); } dim = newdim; } final void fixDim() { if (dim != allocdim) { data = cast(void**)GC.realloc(data, dim * (*data).sizeof); allocdim = dim; } } final void push(void* ptr) { reserve(1); data[dim++] = ptr; } final void* pop() { return data[--dim]; } final void shift(void* ptr) { reserve(1); memmove(data + 1, data, dim * (*data).sizeof); data[0] = ptr; dim++; } final void insert(uint index, void* ptr) { reserve(1); memmove(data + index + 1, data + index, (dim - index) * (*data).sizeof); data[index] = ptr; dim++; } final void insert(uint index, Array a) { if (a !is null) { uint d = a.dim; reserve(d); if (dim != index) { memmove(data + index + d, data + index, (dim - index) * (*data).sizeof); } memcpy(data + index, a.data, d * (*data).sizeof); dim += d; } } /*********************************** * Append array a to this array. */ final void append(Array a) { insert(dim, a); } final void remove(uint i) { memmove(data + i, data + i + 1, (dim - i) * (*data).sizeof); dim--; } final void zero() { memset(data, 0, dim * (*data).sizeof); } final void* tos() { return dim ? data[dim - 1] : null; } private static extern (C) int Array_sort_compare(const(void*) x, const(void*) y) { Object ox = *cast(Object *)x; Object oy = *cast(Object *)y; return ox.opCmp(oy); } final void sort() { if (dim) { qsort(cast(void*)data, dim, Object.sizeof, &Array_sort_compare); } } final Array copyTo(Array a) { a.setDim(dim); memcpy(a.data, data, dim * (*data).sizeof); return a; } final Array copy() { return copyTo(new Array()); } } class Vector(T) : TObject { public: @property final size_t dim() { return _dim; } @property final void dim(size_t newDim) { _dim = newDim; } @property final size_t length() const { return _dim; } /* Doesn't work due to compiler BUG @property final size_t opDollar() const { return _dim; } */ /* // Use [] for accessing members instead // or ptr() to get the pointer to the first element @property T *data() { return _data; } */ @property T *ptr() { return _data; } @property final size_t allocdim() { return _allocdim; } ref T opIndex(size_t index) { return _data[index]; } void opIndexAssign(T value, size_t index) { _data[index] = value; } final T pop() { T v = _data[--_dim]; // _data[dim] = T.init; return v; } final void push(T elem) { reserve(1); _data[_dim++] = elem; } final void zero() { memset(_data, 0, dim * T.sizeof); // TODO fix to assign T.init } final void reserve(size_t nentries) { //printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes); if (allocdim - dim < nentries) { _allocdim = dim + nentries; _data = cast(T*)GC.realloc(_data, allocdim * T.sizeof); } } final void shift(T ptr) { reserve(1); memmove(_data + 1, _data, _dim * T.sizeof); _data[0] = ptr; _dim++; } final Vector!T copy() { return copyTo(new Vector!T()); } final Vector!T copyTo(Vector!T a) { a.setDim(dim); memcpy(a._data, _data, dim * T.sizeof); // TODO call postblits return a; } final void setDim(size_t newdim) { if (dim < newdim) { reserve(newdim - dim); } _dim = newdim; // TODO if newdim < dim set memory to T.init } int opApply(scope int delegate(ref T) dg) { int result = 0; for (size_t i = 0; i < _dim; i++) { result = dg(_data[i]); if (result) break; } return result; } int opApply(scope int delegate(ref size_t key, ref T value) dg) { int result = 0; for (size_t i = 0; i < _dim; i++) { result = dg(i, _data[i]); if(result) break; } return result; } final void append(Vector!T a) { insert(dim, a); } final void remove(size_t i) { memmove(_data + i, _data + i + 1, (_dim - i) * T.sizeof); // _data[dim-1] = T.init; _dim--; } final void insert(uint index, T ptr) { reserve(1); memmove(_data + index + 1, _data + index, (_dim - index) * T.sizeof); _data[index] = ptr; _dim++; } final void insert(size_t index, Vector!T a) { if (a !is null) { uint d = a.dim; reserve(d); if (dim != index) { memmove(_data + index + d, _data + index, (dim - index) * T.sizeof); } memcpy(_data + index, a._data, d * T.sizeof); _dim += d; } } private: T* _data = null; size_t _dim = 0; size_t _allocdim = 0; }