Cleverness of the compiler

Namespace rswhite4 at googlemail.com
Sun Nov 24 16:08:50 PST 2013


I love this feature, but I'm unsure how it works. Can someone 
explain me, how the compiler deduce that he should read 4 bytes 
for each index (the 'at' function)? The type is void*, not int*.

----
import std.stdio;
import core.stdc.stdlib : calloc, realloc, free;
import core.stdc.string : memcpy;

struct Tarray {
	void* ptr;
	size_t length;
	size_t capacity;

	~this() {
		.free(this.ptr);
		this.ptr = null;
	}
}

void push(T)(ref Tarray arr, T elem) {
	if (arr.length == arr.capacity)
		arr.reserve(T.sizeof);

	memcpy(&arr.ptr[arr.length++], &elem, T.sizeof);
}

void reserve(ref Tarray arr, size_t typeOf, size_t cap = 0) {
	if (arr.capacity != 0) {
		arr.capacity = cap == 0 ? (arr.capacity * 2) + 1 : arr.capacity 
+ cap;
		arr.ptr = .realloc(arr.ptr, arr.capacity * typeOf);
	} else {
		arr.capacity = cap == 0 ? 3 : cap;
		arr.ptr = .calloc(arr.capacity, typeOf);
	}
}

void at(T)(ref Tarray arr, size_t index, T* elem) {
	if (index >= arr.length || elem is null)
		return;

	memcpy(elem, &arr.ptr[index], T.sizeof);
}

void main() {
	Tarray arr;
	arr.push(42);
	int a;
	arr.at(0, &a);
	writeln(a, "::", arr.length, "::", arr.capacity);
	arr.push(23);
	arr.at(1, &a);
	writeln(a, "::", arr.length, "::", arr.capacity);
	arr.push(1337);
	arr.at(2, &a);
	writeln(a, "::", arr.length, "::", arr.capacity);
	arr.push(ushort.max + 1);
	arr.at(3, &a);
	writeln(a, "::", arr.length, "::", arr.capacity);
}
----


More information about the Digitalmars-d-learn mailing list