Cleverness of the compiler

growler growlercab at gmail.com
Sun Nov 24 16:51:43 PST 2013


On Monday, 25 November 2013 at 00:08:52 UTC, Namespace wrote:
> 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);
> }
> ----

All the calls to 'at' are using T=int (implied), as far as I can 
tell.
...
int a;
...
arr.at(0, &a); // tyepof(a) is int so in 'at' T.sizeof = 4.

Is this the call to 'at' you're referring to?

Cheers



More information about the Digitalmars-d-learn mailing list