aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/generics.zc
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tests/programs/generics.zc
a
Diffstat (limited to 'tests/programs/generics.zc')
-rw-r--r--tests/programs/generics.zc54
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/programs/generics.zc b/tests/programs/generics.zc
new file mode 100644
index 0000000..e841b19
--- /dev/null
+++ b/tests/programs/generics.zc
@@ -0,0 +1,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;
+}