1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
// 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, V> { K key; V val; };
struct box<T> { int n; T* items; };
K rkey<K, V>(record<K, V>* r) { return r.key; }
V* rval<K, V>(record<K, V>* r) { return &r.val; }
int tsize<T>() { return sizeof(T); }
T*.u make<T>(int n) { T* p = new(T, n) as T*; return u*p; }
record<K, V>*.u mkrec<K, V>(K k) {
record<K, V>* r = new(record<K, V>);
r.key = k;
return u*r;
}
T pick<T>(T* a, int i) { return a[i]; }
int sumn<T>(T* a, int n) {
int s = 0;
for (int i = 0; i < n; i++) s += a[i];
return s;
}
fn nameof<T>() { return tname(typeof(T)); }
o3 int osum<T>(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<T>(int n) {
if (n == 0) return tsize<T>();
return depth<T>(n - 1);
}
int main() {
record<int, pt>* a = mkrec<int, pt>(9);
a.val.x = 5; a.val.y = 6;
put_n(rkey<int, pt>(a)); put_c(' ');
put_n(rval<int, pt>(a).y); put_c(' ');
put_n(sizeof(record<int, pt>)); put_c(' ');
put_n(tsize<int>()); put_c(' ');
put_n(tsize<pt>()); put_c(' ');
put_n(tsize<record<int, pt>>()); put_c(' ');
put_n(depth<pt>(5)); put_c(10);
pt* ps = make<pt>(3);
ps[2].x = 40; ps[2].y = 2;
put_n(pick<pt>(ps, 2).x + ps[2].y); put_c(' ');
put_s(nameof<pt>()); put_c(' '); put_s(nameof<int>()); put_c(' ');
put_n(osum<pt>(ps, 3)); put_c(' ');
int* is = make<int>(4);
is[0] = 1; is[1] = 2; is[2] = 3; is[3] = 4;
put_n(sumn<int>(is, 4)); put_c(' ');
record<pt*, int>* b = mkrec<pt*, int>(ps);
put_n(b.key == ps); put_c(10);
free(d*a); free(d*b); free(d*ps); free(d*is);
return 0;
}
|