namespace; include rt, run; // generics are compiled per set of type arguments: T can be any size, new(T) // stamps the real type, and a struct can take several parameters struct pt { int x, y; }; struct record { K key; V val; }; struct box { int n; T* items; }; K rkey(record* r) { return r.key; } V* rval(record* r) { return &r.val; } int tsize() { return sizeof(T); } T*.u make(int n) { T* p = rt.new(T, n) as T*; return u*p; } record*.u mkrec(K k) { record* r = rt.new(record); // copied references are shared so the record does not consume its input. r.key = run.share_value(k); return u*r; } T pick(T* a, int i) { return a[i]; } int sumn(T* a, int n) { int s = 0; for (int i = 0; i < n; i++) s += a[i]; return s; } fn nameof() { return run.tname(typeof(T)); } o3 int osum(T* a, int n) { int s = 0; for (int i = 0; i < n; i++) s += a[i].x + a[i].y; return s; } int depth(int n) { if (n == 0) return tsize(); return depth(n - 1); } int main() { record* a = mkrec(9); a.val.x = 5; a.val.y = 6; rt.put_n(rkey(a)); rt.put_c(' '); rt.put_n(rval(a).y); rt.put_c(' '); rt.put_n(sizeof(record)); rt.put_c(' '); rt.put_n(tsize()); rt.put_c(' '); rt.put_n(tsize()); rt.put_c(' '); rt.put_n(tsize>()); rt.put_c(' '); rt.put_n(depth(5)); rt.put_c(10); pt* ps = make(3); ps[2].x = 40; ps[2].y = 2; rt.put_n(pick(ps, 2).x + ps[2].y); rt.put_c(' '); rt.put_s(nameof()); rt.put_c(' '); rt.put_s(nameof()); rt.put_c(' '); rt.put_n(osum(ps, 3)); rt.put_c(' '); int* is = make(4); is[0] = 1; is[1] = 2; is[2] = 3; is[3] = 4; rt.put_n(sumn(is, 4)); rt.put_c(' '); record* b = mkrec(ps); rt.put_n(b.key == ps); rt.put_c(10); rt.free(d*a); rt.free(d*b); rt.free(d*ps); rt.free(d*is); return 0; }