view dmd/ArrayT.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children
line wrap: on
line source

module dmd.ArrayT;

import std.contracts;
import core.stdc.stdlib;
import core.stdc.string;

class ArrayT(T)
{
	uint dim;
    uint allocdim;
    T* data;

    ~this()
	{
		free(data);
	}

    void mark()
	{
	}
	
    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*)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("ArrayT::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
		if (allocdim - dim < nentries) {
			allocdim = dim + nentries;
			data = cast(T*)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(T*)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, ArrayT 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(ArrayT 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, &ArrayT_sort_compare);
		}
	}

    final ArrayT copy()
	{
		ArrayT a = new TArray();
		a.setDim(dim);

		memcpy(a.data, data, dim * (*data).sizeof);

		return a;
	}
}