Enumerable
Enumerable is the protocol a class adopts so its instances can drive a
for (T* x in collection) loop. It provides a count and an indexed accessor
that the for-in codegen calls.
class MyContainer <Enumerable> { ... }Overview
Section titled “Overview”xtc’s for … in handles fixed-size arrays, slices, ranges and heap-allocated
pointers: anything where the codegen can derive a count and an element address
up front. A class instance can’t be walked that way because its storage
layout is private. A class that conforms to Enumerable provides two methods
the loop can call, and the codegen rewrites
for (Object* e in col) { body; }into a counted loop that reads enumLength once at loop entry
and calls enumAt on each iteration. The walk is stateless, so nested
iteration over the same collection works and break / continue behave
normally. Calls go through the protocol’s vtable slot, so the concrete class’s
methods run even when the static type of col is Object*.
Required methods
Section titled “Required methods”Topics · enumLength · enumAt
enumLength
Section titled “enumLength”u32 enumLength(void); // xt6502: u16Return the total number of elements. The for-in codegen reads this once, at loop entry, to bound the loop.
enumAt
Section titled “enumAt”Object* enumAt(u32 i);Return the element at 0-based index i. The element type is Object*. A
container storing typed pointers (Number,
String, user classes) returns them here, and the loop
body downcasts if it needs the concrete type:
for (Object* o in arr) { Number* n = (Number* ?)o; if (n != 0) Stdio.printf("%d\n", n.asI16());}Conforming types
Section titled “Conforming types”Standard-library containers that conform (each implements enumLength and
enumAt):
Primitive-element collections (String’s u8
characters, Data’s u8 bytes) use the pointer-style
for-in and don’t box each element through Object*.
Adopt Enumerable on a custom container so callers can walk it with the same
for … in they use on the built-in collections, without exposing its internal
layout. Iteration is index-based and stateless, so two loops over the same
instance, including nested ones, don’t interfere.