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